GetXAPI
Users

User Login

Get fresh auth tokens for a Twitter account via API. Required for write endpoints like tweeting and DMs. GetXAPI login endpoint docs.

POST/twitter/user_login

This endpoint costs $0.01 per API call.

Use your own proxy for reliable logins. X rate-limits logins per IP (roughly 1-2 logins per IP, then a cooldown), so without a proxy you may hit rate_limited frequently. Supply a residential or ISP (static-residential) proxy with a sticky session — the entire login flow, including 2FA, must come from a single IP. Datacenter and rotating proxies will fail or get rate-limited. Format: http://user:pass@host:port. A fresh IP per login (or one IP per account) is best.

X now verifies logins by emailing a code. From a new IP, X sends a verification code to the account's inbox before (or instead of) asking for the password. Pass the mailbox OAuth credentials below (ms_refresh_token + ms_client_id) so we can read that code automatically — otherwise the login stops with email_code_required.

Request Body

FieldTypeRequiredDescription
usernamestringYesTwitter username (without @)
passwordstringYesAccount password
emailstringYesThe account's email. X now uses the email as the login identifier — a bare username is rejected with "We couldn't find an active X account with that username". Always send the account's real email.
totp_secretstringConditionalBase32 TOTP secret, required whenever the account has authenticator-app 2FA.
ms_refresh_tokenstringNo (recommended)Microsoft OAuth refresh token for the account's mailbox (starts with M.C…). Together with ms_client_id this lets us read X's emailed verification code automatically.
ms_client_idstringNo (recommended)OAuth client id (GUID) paired with ms_refresh_token.
proxystringNo (recommended)Your own residential or ISP static proxy with a sticky session (http://user:pass@host:port). Strongly recommended — logins are rate-limited per IP, so your own proxy avoids the shared-pool rate_limited. Datacenter and rotating proxies will fail or get rate-limited.

Notes

  • Returns fresh auth tokens (auth_token, ct0, twid) for the account.
  • The flow: X takes the email, then usually emails a 6-digit code (there is a "Use password" alternative), then asks for TOTP if 2FA is enabled. With ms_refresh_token + ms_client_id the emailed code is read for you; without them, the login ends at email_code_required.
  • Mailbox support: the automatic code read works for Hotmail / Outlook / Live mailboxes via Microsoft OAuth. Gmail and Yahoo are not supported — use the two-step Reset Password flow for those.
  • 2FA: authenticator-app (TOTP) is supported via totp_secret. Passkey-only 2FA is not supported.
  • "Confirm your account" check: X sometimes intercepts with an anti-enumeration screen asking for the phone number on file. We automatically take its "Use password" option and carry on; verification_required is returned only when that escape hatch isn't offered.
  • Profile data is fetched automatically after a successful login.

Response (200)

{
  "username": "blueriver_42",
  "auth_token": "7b3f9c1e2d8a4f6b9c0e1a2d3f4b5c6e7a8b9c0d",
  "ct0": "9a2c4e6f8b1d3a5c7e9f0b2d4a6c8e0f",
  "twid": "u=1623458791034556928",
  "profile": {
    "type": "user",
    "id": "1623458791034556928",
    "userName": "blueriver_42",
    "name": "Blue River",
    "url": "https://x.com/blueriver_42",
    "isVerified": false,
    "isBlueVerified": false,
    "profilePicture": "https://pbs.twimg.com/profile_images/...",
    "description": "",
    "location": "",
    "followers": 18,
    "following": 33,
    "createdAt": "Wed Mar 15 09:42:11 +0000 2023"
  }
}

Error Responses

HTTPchallenge / meaningWhat to do
400Missing fields / invalid usernameSend username + password
401Wrong passwordCheck credentials
404Account not foundSuspended, deleted, or renamed
410Suspended—
422verification_required — "Confirm your account" (phone on file)Log in once manually from a trusted IP
423email_code_required — X emailed a code and we have no mailbox accessSend ms_refresh_token + ms_client_id
423locked — account lockedUnlock at x.com/account/access
429rate_limited — too many logins from this IPUse a fresh residential/ISP IP
502proxy_unreachableYour proxy did not respond
502identifier_blockX rejected the identifier / served an unsupported step — retry on another IP
503Login service unavailableRetry shortly
{
  "error": "Verification required: Twitter wants a code sent to the account's email.",
  "challenge": "email_code_required"
}

Example

# Basic login (no 2FA, no mailbox access)
curl -X POST "https://api.getxapi.com/twitter/user_login" \
  -H "Authorization: Bearer API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "myaccount",
    "password": "mypassword",
    "email": "myemail@example.com"
  }'

# Full login: 2FA + automatic email-code read (recommended)
curl -X POST "https://api.getxapi.com/twitter/user_login" \
  -H "Authorization: Bearer API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "blueriver_42",
    "password": "kp7m9q2nx4tj",
    "email": "blueriver42@hotmail.com",
    "totp_secret": "JBSWY3DPEHPK3PXP",
    "ms_refresh_token": "M.C512_BAY.0.U.-Ct…",
    "ms_client_id": "9e5f94bc-e8a4-4e73-b8be-63364c29d753",
    "proxy": "http://user:pass@host:port"
  }'

Two-step login (email-code handoff)

X often emails a 6-digit code instead of accepting the password, and Gmail / Yahoo mailboxes can't be read automatically (only Hotmail/Outlook via OAuth). For those, start the login, have the account owner read the code from their inbox, then submit it — the same two-step pattern as Reset Password.

Both calls cost $0.005 and are rate limited to 1 request every 2 seconds per API key.

Step 1 — Start the login

POST/twitter/user_login/async

Same body as User Login. The browser is held open on X's verification screen for 5 minutes.

If X logs in without a challenge you get 200 and tokens immediately. If it asks for a code, you get 423 with a session_id:

{
  "error": "Verification required — submit the code to /twitter/user_login/confirm with this session_id.",
  "challenge": "email_code",
  "detail": "Enter the code X emailed to the account",
  "session_id": "0c9243315167e393f64e9dff",
  "expires_in": 300
}
challengeMeaning
email_codeX emailed a code — read it from the inbox and submit it
totpAuthenticator code — omit totp_secret on step 1 and supply it here instead
verificationX wants a method chosen first

Step 2 — Submit the code

POST/twitter/user_login/confirm
FieldTypeRequiredDescription
session_idstringYesFrom step 1
codestringYesThe 6-digit code the owner read from the inbox
usernamestringNoPass it to have the profile included in the response
{
  "username": "myaccount",
  "auth_token": "2b1bc9b015a1...",
  "ct0": "8bd431d22bc4...",
  "twid": "u=1292297646854615041",
  "session_id": "0c9243315167e393f64e9dff",
  "profile": { "...": "..." }
}

If X follows the email code with another step (e.g. 2FA), you get 423 again with the new challenge — submit the next code with the same session_id.

Errors

HTTPcode / challengeMeaning
400—Missing username/password (step 1) or session_id/code (step 2)
410session_expiredSession unknown or past its 5-minute window — start again at step 1
423email_code / totp / verificationVerification needed — submit the code
429—Rate limit: 1 request every 2 seconds
502proxy_unreachableThe proxy did not respond — retry or use a different one
503worker_auth_failedLogin worker misconfigured (internal) — not your request
# 1) start — expect 423 + session_id for a Gmail/Yahoo account
curl -X POST "https://api.getxapi.com/twitter/user_login/async" \
  -H "Authorization: Bearer API_KEY" -H "Content-Type: application/json" \
  -d '{"username":"myaccount","password":"mypassword","email":"myaccount@gmail.com"}'

# 2) submit the code the owner received
curl -X POST "https://api.getxapi.com/twitter/user_login/confirm" \
  -H "Authorization: Bearer API_KEY" -H "Content-Type: application/json" \
  -d '{"session_id":"<from step 1>","code":"214587","username":"myaccount"}'

On this page