TwitterAPIs Docs
API ReferenceAccount Session

Twitter Session Status API | Check Your Registered X Session

Read the X session stored against your API key without changing it. Returns the account the session actually resolved to, whether it is still live or has been marked dead, when it was registered and last used, and which egress tier a write would leave on. It never returns auth_token, ct0, or any proxy URL. The key is taken from the authenticated request and the handler reads no identity from the body, the query string, or any second header, so a call can only ever read the caller's own session. This call is free. Cost: Free per call.

Session Status returns the state of the X session registered against your API key: registered (false if none), the resolved username and twitter_user_id, status of ok or dead, created_at, updated_at, last_used_at, and an egress block giving the source tier and whether your own registered proxy is in use. It never returns auth_token, ct0, or a proxy URL, is scoped to the caller, and is free.

GET
/customer/session/status

Authorization

bearerAuth
AuthorizationBearer <token>

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

In: header

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

application/json

curl -X GET "https://example.com/customer/session/status"
{  "registered": true,  "username": "yourhandle",  "twitter_user_id": "1234567890123456789",  "status": "ok",  "created_at": "2026-08-19T19:44:03.433Z",  "updated_at": "2026-08-19T19:44:03.433Z",  "last_used_at": "2026-08-26T12:34:37.015Z",  "egress": {    "source": "session",    "customer_proxy_in_use": true,    "note": "Writes leave through the proxy you registered on this session. Keep it sticky, one dedicated IP per account, and geo-matched to where the account normally signs in."  },  "message": "Your registered Twitter session is stored and marked live. A per-request proxy sent as x-proxy-url overrides the egress shown here for that call only."}
{  "error": "bad_request",  "message": "Missing or malformed parameter. Fix the request before retrying."}
{  "error": "unauthorized",  "message": "The API key is missing, malformed, or revoked. Check the Authorization header."}
{  "error": "insufficient_credits",  "message": "Your balance is exhausted. Top up your credits to continue."}
{  "error": "not_found",  "message": "The resource does not exist, for example a deleted tweet or a private account."}
{  "error": "rate_limited",  "message": "Too many requests. Back off and retry with exponential backoff."}
{  "error": "server_error",  "message": "Something failed on our side. Retry with backoff; if it persists, contact support."}

Pricing

UnitPrice
Per callFree

When to use

Call it when a write or a private read stops behaving and you need to know whether the cause is on your side. It answers three questions without a support ticket: am I posting as the account I think I am (username and twitter_user_id), has my session expired (status dead means X rejected the cookies and you should re-register), and is the proxy I supplied actually being used (egress.customer_proxy_in_use). It is a read and changes nothing, so it is safe to poll in a health check. It is free, so it still answers when your balance is exhausted, which is exactly when you most need it.

Notes

  • Read-only. It changes nothing, contacts no upstream service, and never consumes an action on your X account, so it is safe in a health check.
  • Never returns a credential. No auth_token, no ct0, no prefix or hash of either, and no proxy URL of any kind.
  • Scoped to the caller by construction. The API key comes from the authenticated request context; the handler reads no api key, user id, username, or account id from the request itself.
  • Free. Priced at zero deliberately, so a customer whose balance is exhausted can still diagnose why their calls are failing.
  • dead is not the same as absent. A session X has rejected is still stored and still revocable, and is reported as registered: true with status: dead rather than as no session at all.
  • A GET on a distinct path rather than a second method on /customer/session. Four of the surfaces this API is documented on key on the path alone and cannot represent two methods on one path, so a dual-method path could never be reported as covered.
  • egress describes the stored session. A proxy supplied per request as x-proxy-url overrides it for that call only and is not shown here.
  • 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.
  • User Login: Log in to X with a username and password (plus TOTP for 2FA) and store the resulting session against your API key, so authenticated-account reads and write tools then act as that account. A convenience alternative to bringing your own cookies via Register Session.

FAQ

Does this return my cookies?

No. auth_token and ct0 are never returned, and neither is a prefix or a hash of either. The pair is full control of your X account, so there is no version of it we hand back.

Why does it not show the proxy URL?

Because the answer is not always yours to see. When you register your own proxy the URL is yours, but when you register none the write path uses one of our residential exits, and that URL carries our gateway credentials. Rather than return the field sometimes and withhold it other times, the response gives the tier name plus customer_proxy_in_use, which answers the question without ever carrying a secret.

How do I tell whether my own proxy is being used?

Read egress.customer_proxy_in_use. It is true only when the proxy_url you registered is the one your writes leave from. A caller-supplied proxy sent per request as x-proxy-url overrides the stored one for that single call and is not reflected here, because this describes the stored session rather than a request that has not been made.

What is the difference between registered: false and status: dead?

registered: false means we hold nothing for your key, so the fix is to register. status: dead means we hold a session and X has rejected it, so the fix is to re-register with fresh cookies. They are different situations with different fixes, which is why they are not collapsed into one answer.

Can one API key read another key's session?

No. The handler takes the API key from the authenticated request context and reads no identity from the request itself, so there is no body field, query parameter, or second header that could name a different key.

Does it cost credits?

No, it is priced at zero. That is deliberate: billing refuses a call with 402 when the balance is short, so a priced status endpoint would mean the customer who has just spent their balance on failing calls is the one who cannot find out why.

Is it safe to poll?

Yes. It is a read, it changes nothing, and it does not touch X, so it never consumes an account action or triggers a challenge. It reads our stored row only.

My writes are being refused but status says ok. What does that mean?

It means the session itself is fine and the refusal is coming from X for another reason, commonly an automation or rate limit on the account rather than a credential problem. Check the error body on the failing write: our write responses carry X's own error code and message.