TwitterAPIs Docs
API ReferenceAccount Session

Twitter User Login API | Log In and Store a Session

Log in to an X account with a username and password (plus a TOTP secret when two-factor authentication is enabled). The API runs the login itself and stores the resulting session server-side against your API key; authenticated-account reads and the write tools then act as that account. It does NOT return session cookies: the response is {ok, username, message}, never auth_token/ct0/twid. Bringing your own auth_token and ct0 via POST /customer/session stays the primary, recommended path, since it never sends a password over the wire. This call costs $0.01, billed only on a successful login; a rejected attempt (bad credentials, captcha, etc.) is never charged. Cost: $0.0100 per call.

User Login logs in to X with a username, password, and an optional TOTP two-factor secret, then stores the resulting session against your API key. It returns {ok, username, message}, never the raw session cookies. It is the convenience alternative to bringing your own cookies via Register Session, which stays the recommended path. The login call itself costs $0.01, charged only on success.

POST
/user/user_login

Authorization

bearerAuth
AuthorizationBearer <token>

Pass your API key as a bearer token on every request: Authorization: Bearer <API_KEY>.

In: header

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

application/json

application/json

application/json

curl -X POST "https://example.com/user/user_login" \  -H "Content-Type: application/json" \  -d '{    "username": "string",    "password": "string"  }'
{  "ok": true,  "username": "myhandle",  "message": "Logged in. Private-data endpoints will now read as your account."}
{  "error": "two_factor_required",  "message": "This account has 2FA enabled. Include `totp_secret` in the request body."}
{  "error": "bad_credentials",  "message": "Username or password was rejected by Twitter. A missing or revoked API key also answers 401, with error unauthorized."}
{  "error": "insufficient_credits",  "message": "Your balance is exhausted. Top up your credits to continue."}
{  "error": "account_locked",  "message": "This account is locked; confirm it from the app, then retry."}
{  "error": "captcha_required",  "message": "Login requires a captcha that could not be solved automatically."}
{  "error": "rate_limited",  "message": "Too many requests. Either this API key hit its per-minute limit or Twitter throttled the login itself. Back off and retry with exponential backoff."}
{  "error": "login_failed",  "message": "Login could not be completed."}
{  "error": "login_unavailable",  "message": "Login egress is exhausted. Try again shortly."}

Pricing

UnitPrice
Per call$0.0100
Per 1,000 calls$10.00

When to use

Reach for User Login only when you cannot extract cookies from a logged-in browser and would rather hand over credentials. For anything you run on a schedule, prefer Register Session (POST /customer/session) with your own auth_token and ct0: it is the primary, most reliable path and never sends a password over the wire.

Notes

  • Register Session (POST /customer/session) is the primary, recommended path: bring your own auth_token and ct0 so no password is sent. Use User Login only when you cannot extract cookies from a browser.
  • Pass totp_secret (base32) only when the account has two-factor authentication enabled; omit it otherwise.
  • This call does NOT return session cookies. auth_token, ct0, and twid are minted and stored server-side against your API key; they are never sent back to the caller, unlike some third-party login APIs.
  • Costs $0.01 per call, billed only on a successful login (a rejected attempt is never charged); Register Session (POST /customer/session) stays free since it never runs a login flow.
  • Terminal, user-actionable failures come back as 4xx or 409 with the standard {error, message} envelope, deliberately never a bare 5xx, because retrying a password-based login on a genuine failure resubmits real credentials and can lock the account: bad_credentials (401), two_factor_required / two_factor_failed / bad_request (400), and account_suspended / account_locked / session_mismatch / verification_required / email_code_required / identifier_required (409, an identity-confirmation state only the account owner can clear).
  • Only our-side or Twitter-side transient faults are retryable: rate_limited (429), proxy_unreachable / login_interrupted / login_timeout / login_failed (502), and login_unavailable (503, egress exhausted or the login service is misconfigured).
  • Register Session: Register your auth_token and ct0 cookies once so every write and private read acts as your account, or pass them per call as x-auth-token / x-ct0 headers.
  • Revoke Session: Delete the auth_token and ct0 you registered, so we no longer hold your X session cookies. Self-serve, idempotent, and free.

FAQ

Should I use User Login or Register Session?

Register Session (POST /customer/session) is the recommended path: you bring your own auth_token and ct0 cookies, so no password is ever sent to the API. User Login is the convenience alternative for when you cannot extract cookies from a browser; it logs in with a username and password and stores the resulting session for you.

What does User Login return?

{ok, username, message}. It does NOT return session cookies: auth_token, ct0, and twid are minted and stored server-side against your API key, never sent back to the caller. Once logged in, private-data reads and write tools act as that account automatically.

Do I need a TOTP secret?

Only when the account has two-factor authentication enabled. Pass the base32 totp_secret and the API derives the current one-time code; omit it for accounts without 2FA.

How much does User Login cost?

$0.01 per call, billed only on a successful login. A rejected attempt (bad credentials, captcha required, two-factor failure, etc.) is never charged. Register Session (POST /customer/session) stays free, since it never runs a login flow.