Pagination and cursors
Every list endpoint returns one page of results with a cursor and has_more:
{
"ok": true,
"data": { "object": "list", "items": [ ], "cursor": "eyJvIjoyNX0", "has_more": true },
"cursor": "eyJvIjoyNX0",
"has_more": true
}The envelope and data carry the same two values. To get the next page, send the same request with cursor set to the value you received.
- Treat the cursor as an opaque string. Pass it back unchanged; do not parse, build or store it long term.
has_more: false(andcursor: null) means you have everything.- Each page costs its usual price (usually 1 credit), whatever its size. See Credits.
- Keep every other parameter the same. Changing
sort,regionor the search terms starts a new chain: drop the cursor. limitis an upper bound. A platform may return fewer items than you ask for and still have more; rely onhas_more, not on the page size.
import os
import requests
url = "https://api.socialscrape.io/v1/github/user/repositories" # any list endpoint
headers = {"x-api-key": os.environ["SOCIALSCRAPE_API_KEY"]}
params = {"handle": "torvalds"}
items = []
while True:
body = requests.get(url, headers=headers, params=params, timeout=60).json()
if not body["ok"]:
raise RuntimeError(body["error"]["code"])
items += body["data"]["items"]
if not body["has_more"]:
break
params["cursor"] = body["cursor"]const url = new URL("https://api.socialscrape.io/v1/github/user/repositories"); // any list endpoint
url.searchParams.set("handle", "torvalds");
const headers = { "x-api-key": process.env.SOCIALSCRAPE_API_KEY! };
const items: unknown[] = [];
for (;;) {
const body = await (await fetch(url, { headers })).json();
if (!body.ok) throw new Error(body.error.code);
items.push(...body.data.items);
if (!body.has_more) break;
url.searchParams.set("cursor", body.cursor);
}Cursors from other APIs#
If you are switching from another API, the old cursor parameter names are accepted as cursor: continuationToken, continuation_token, next_max_id, max_id, max_cursor, min_time, after, page_token, pageToken, paginationToken, next_page_id, page. The values are not portable: a cursor from another provider means nothing here, so restart each list from the first page.
Cursors and cached pages#
Pages obey max_age_days like any request. A cached page that is still fresh returns for free with the cursor that was current when it was fetched. See Caching.