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.
COMMON QUESTIONS
Frequently asked 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.
TRY THE API
Make the first request today.
One key covers REST and MCP. Add credit when you need it.
Get an API key