Docs menu

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 (and cursor: 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, region or the search terms starts a new chain: drop the cursor.
  • limit is an upper bound. A platform may return fewer items than you ask for and still have more; rely on has_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.