User Login
Get fresh auth tokens for a Twitter account via API. Required for write endpoints like tweeting and DMs. GetXAPI login endpoint docs.
/twitter/user_loginThis 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
| Field | Type | Required | Description |
|---|---|---|---|
username | string | Yes | Twitter username (without @) |
password | string | Yes | Account password |
email | string | Yes | The 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_secret | string | Conditional | Base32 TOTP secret, required whenever the account has authenticator-app 2FA. |
ms_refresh_token | string | No (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_id | string | No (recommended) | OAuth client id (GUID) paired with ms_refresh_token. |
proxy | string | No (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_idthe emailed code is read for you; without them, the login ends atemail_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_requiredis 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
| HTTP | challenge / meaning | What to do |
|---|---|---|
| 400 | Missing fields / invalid username | Send username + password |
| 401 | Wrong password | Check credentials |
| 404 | Account not found | Suspended, deleted, or renamed |
| 410 | Suspended | — |
| 422 | verification_required — "Confirm your account" (phone on file) | Log in once manually from a trusted IP |
| 423 | email_code_required — X emailed a code and we have no mailbox access | Send ms_refresh_token + ms_client_id |
| 423 | locked — account locked | Unlock at x.com/account/access |
| 429 | rate_limited — too many logins from this IP | Use a fresh residential/ISP IP |
| 502 | proxy_unreachable | Your proxy did not respond |
| 502 | identifier_block | X rejected the identifier / served an unsupported step — retry on another IP |
| 503 | Login service unavailable | Retry 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
/twitter/user_login/asyncSame 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
}challenge | Meaning |
|---|---|
email_code | X emailed a code — read it from the inbox and submit it |
totp | Authenticator code — omit totp_secret on step 1 and supply it here instead |
verification | X wants a method chosen first |
Step 2 — Submit the code
/twitter/user_login/confirm| Field | Type | Required | Description |
|---|---|---|---|
session_id | string | Yes | From step 1 |
code | string | Yes | The 6-digit code the owner read from the inbox |
username | string | No | Pass 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
| HTTP | code / challenge | Meaning |
|---|---|---|
| 400 | — | Missing username/password (step 1) or session_id/code (step 2) |
| 410 | session_expired | Session unknown or past its 5-minute window — start again at step 1 |
| 423 | email_code / totp / verification | Verification needed — submit the code |
| 429 | — | Rate limit: 1 request every 2 seconds |
| 502 | proxy_unreachable | The proxy did not respond — retry or use a different one |
| 503 | worker_auth_failed | Login 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"}'Update ProfileNew
Update Twitter profile fields (name, bio, location, URL, color, birthdate) programmatically via API. $0.001 per call. GetXAPI update profile endpoint.
User Login V2 (Recovery)New
Recover a Twitter/X account with a dead token and changed password via the mailbox. Returns fresh tokens + a new password. $0.005 per call.