Twitter API Pagination | Cursor-Based Paging Guide
Cursor-based pagination across search, list, and follower-graph endpoints, with a copy-paste loop that reads every page.
List-style endpoints return one page at a time. To read the rest, you follow a cursor. This applies to search, follower-graph, and list endpoints, which is everywhere a response can hold more rows than fit in a single call.
How it works
Each page response carries the page of rows plus two pagination fields:
| Field | Type | Description |
|---|---|---|
count | integer | Number of items returned in this page. |
next_cursor | string | null | An opaque token. Pass it as the cursor parameter to fetch the next page. |
<collection> | array | The page of rows itself, named for the resource, for example tweets, users, or members. |
To advance, take next_cursor from the response and send it back as the cursor query parameter on your next request. Repeat until the collection array comes back empty. That empty array is the universal stop signal on every paginated endpoint.
Do not stop on the cursor value alone. On the final page, next_cursor is null for list and affiliate endpoints, but follower-graph endpoints (followers, following, verified followers, and the v2 variants) return a non-null pipe-delimited cursor even on the last and empty page. The only reliable stop condition is an empty collection array.
# First page: no cursor.
curl "https://api.twitterapis.com/twitter/tweet/advanced_search?query=from%3Anaval" \
-H "Authorization: Bearer $TWITTERAPIS_KEY"
# Next page: pass the cursor from the previous response.
curl "https://api.twitterapis.com/twitter/tweet/advanced_search?query=from%3Anaval&cursor=DAABCgABF..." \
-H "Authorization: Bearer $TWITTERAPIS_KEY"Reading every page
A short loop reads the full result set. Keep calling until the collection array comes back empty, carrying the cursor forward each time.
async function readAll(query) {
const all = [];
let cursor = "";
while (true) {
const url = new URL("https://api.twitterapis.com/twitter/tweet/advanced_search");
url.searchParams.set("query", query);
if (cursor) url.searchParams.set("cursor", cursor);
const res = await fetch(url, {
headers: { Authorization: `Bearer ${process.env.TWITTERAPIS_KEY}` },
});
const page = await res.json();
// Universal stop: an empty collection means there are no more rows.
if (!page.tweets?.length) break;
all.push(...page.tweets);
// List and affiliate endpoints end with a null cursor; follower-graph
// endpoints keep returning one, so the empty check above is what stops them.
if (!page.next_cursor) break;
cursor = page.next_cursor;
}
return all;
}import os
import requests
def read_all(query):
all_tweets = []
cursor = ""
while True:
params = {"query": query}
if cursor:
params["cursor"] = cursor
res = requests.get(
"https://api.twitterapis.com/twitter/tweet/advanced_search",
headers={"Authorization": f"Bearer {os.environ['TWITTERAPIS_KEY']}"},
params=params,
)
page = res.json()
# Universal stop: an empty collection means there are no more rows.
tweets = page.get("tweets", [])
if not tweets:
break
all_tweets.extend(tweets)
# List and affiliate endpoints end with a null cursor; follower-graph
# endpoints keep returning one, so the empty check above stops them.
if not page.get("next_cursor"):
break
cursor = page["next_cursor"]
return all_tweetsTreat the cursor as opaque
Do not parse, edit, or store assumptions about the cursor string. It is a server token. Pass back exactly what you received. Page size is fixed per endpoint, so there is no page-size parameter to tune.
A note on cost
Each page is one billed call. A query that spans ten pages costs ten standard calls. Stop paging as soon as you have what you need rather than draining the full result set out of habit.
FAQ
When do I stop paging?
Stop when the collection array comes back empty. That empty array is the only reliable stop signal across every paginated endpoint.
Why not stop on a null cursor?
List and affiliate endpoints end with a null cursor, but follower-graph endpoints keep returning a non-null cursor even on the last page.
Can I change the page size?
No. Page size is fixed per endpoint, so there is no page-size parameter to tune. Treat the cursor as an opaque token.