How cursor pagination works
A cursor is an opaque continuation token. Do not decode it, increment it, or treat it as a page number. Send it back exactly as received.
Every TwitterXAPI collection response uses the same pagination object.
{
"items": ["..."],
"count": 20,
"pagination": {
"next_cursor": "DAABCgAB...",
"has_more": true
}
}Request the next page
Add the returned value as the cursor query parameter. URL encode it when your client does not handle query parameters.
curl --get "https://twitterxapi.com/api/v1/users/marclou/tweets" \
-H "Authorization: Bearer $TWITTERXAPI_KEY" \
--data-urlencode "level=moderate" \
--data-urlencode "cursor=DAABCgAB..."Paginate in JavaScript
This async generator yields one item at a time. Callers can stop early without changing the page loop.
async function* items(path, apiKey) {
let cursor;
do {
const url = new URL(path, "https://twitterxapi.com/api/");
url.searchParams.set("level", "moderate");
if (cursor) url.searchParams.set("cursor", cursor);
const r = await fetch(url, { headers: { Authorization: `Bearer ${apiKey}` } });
if (!r.ok) throw new Error(`HTTP ${r.status}`);
const page = await r.json();
yield* page.items;
cursor = page.pagination.has_more ? page.pagination.next_cursor : null;
} while (cursor);
}Stop safely
Stop when has_more is false or next_cursor is empty. Guard against the same cursor appearing twice.
- Retry temporary 429 and 5xx responses with backoff.
- Checkpoint the cursor after saving the page.
- Deduplicate item IDs when paging through a changing live timeline.
- Do not send a
limitparameter. Live routes return one upstream page.
Questions
What is a Twitter API cursor?
It is an opaque token that tells the API where to continue.
When should the loop stop?
Stop when has_more is false or next_cursor is empty.
Can I choose the page size?
No. Live TwitterXAPI collection routes return one upstream page.