TwitterAPIs Docs
API ReferenceWrite Actions

List Scheduled Tweets API

List every pending scheduled post on the account behind your registered session. Each row carries the id, its text, its execute_at in epoch SECONDS, X's own state label, and thread_truncated for a thread whose text is only its first tweet. Ordering is X's: pass ascending=true to ask for the oldest first. Billed at $0.0016 per call. Cost: $0.0016 per call.

GET scheduled/list returns every pending scheduled post on the account behind your registered twitterapis session, with its id, text, state, and execute_at in epoch SECONDS. X reads back milliseconds on this operation and they are converted here, so the value can go straight back into scheduled/create. One call, $0.0016.

GET
/scheduled/list

Authorization

bearerAuth
AuthorizationBearer <token>

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

In: header

Query Parameters

ascending?boolean

Pass true to ask X for the oldest row first. Anything else, including omitting it, sends ascending=false, which is what X's own composer sends. The resulting order is X's and is not re-sorted here.

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

application/json

curl -X GET "https://example.com/scheduled/list?ascending=false"
{  "scheduled": [    {      "scheduled_tweet_id": "2086650228950683649",      "text": "The Q1 changelog is live.",      "thread_truncated": false,      "execute_at": 1829752200,      "state": "Scheduled"    }  ],  "count": 1}
{  "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 call$0.0016
Per 1,000 calls$1.60

One call is the whole request, with no cursor to follow, so the per-1,000-records row below is indicative: the number of calls you make depends on how often you poll, not on how many posts are queued.

When to use

Use scheduled/list to see what is queued to post and to get the id you need to cancel one. It is also worth reading before you schedule anything, so a retry in your own code does not quietly queue the same post twice.

Notes

  • execute_at is returned in epoch SECONDS. X answers this operation in milliseconds and the value is normalised here, so a timestamp read from this list can be passed back to scheduled/create unchanged.
  • There is no cursor to pass. The only variable X's own composer sends on this operation is ascending, and the response we read carries no cursor of any kind, so one call is the whole request. Whether X itself caps the number of rows it will return has not been observed.
  • NOT BILLED, narrowly: a response that is BOTH partial AND carries no row with either a usable text or a usable instant costs nothing, even though it answers 200. An honest empty queue is NOT that case: it is a correct answer, and it is billed like any other read.
  • Needs a session for the account you are reading: either register one once (POST /customer/session), or pass per-call inline credentials as x-auth-token and x-ct0 request headers, which let a single API key act as many accounts. Returns 409 session_required if neither is supplied, 401 session_dead when the session has expired.

FAQ

Why is execute_at in seconds here when X returns milliseconds?

Because sending X's own read value back into a scheduled/create would be rejected as a millisecond timestamp. The value is converted to seconds on the way out so the API speaks one unit and a round trip works without the caller having to know about the difference.

Does this list posts that already published?

No. It lists what is still pending. Once a row publishes it becomes an ordinary tweet, so read it from your own timeline and remove it with tweet/delete if you need to.

What does partial: true mean here?

That we read X's answer but did not fully understand all of it. Any one of these is enough: a dropped row, an unreadable text, an unreadable instant, an unreadable thread shape, or an unreadable envelope. It is not the same as an empty queue, which comes back as an empty array with no partial flag at all.