Responses and pagination
Every call answers with the same envelope: the data, and what the call cost and how fresh it is. Lists page by cursor.
The envelope
A successful call is HTTP 200 with two keys, data and meta:
{
"data": { … },
"meta": {
"request_id": "req_7f3ac1e94b2d40f8a1c6e5d2",
"credits_charged": 3,
"credits_remaining": 74218,
"cached": false,
"fetched_at": "2026-09-22T09:12:03Z",
"next_cursor": null
}
}| meta field | What it says |
|---|---|
request_id | This call, for the requests log and for support. Quote it if you write to us. |
credits_charged | What the call cost: the endpoint’s published credits, or 0 for a call we failed. |
credits_remaining | Your balance after this call. |
cached | Whether the answer came from our cache. It doesn’t change the price. |
fetched_at | When the data was actually fetched from the platform. For a cached answer, that’s earlier than now. |
next_cursor | For a list: pass it back as cursor for the next page. null on the last page, and on single objects. |
The data
datais one object, or a list of them. Which one is on each endpoint’s page.- Each platform’s objects use that platform’s own names: Google Maps after Google’s Places API, Instagram after the Graph API, TikTok after TikTok’s APIs, LinkedIn after the words on its pages. Every field is in Response objects.
- Every documented key is always present. When the platform doesn’t show a value, it’s
null, never0or an empty string, so a missing value can’t pass for a real one.
Errors
A failed call is an HTTP error with one key, error. Branch on code: it’s stable and documented. The message is written for a person, says what to do next, and may change.
{
"error": {
"type": "not_found",
"code": "profile_not_found",
"message": "No TikTok account with that username. Usernames are case-insensitive and exclude the leading @.",
"docs": "https://scrapefield.com/docs/errors#profile_not_found",
"request_id": "req_7f3ac1e94b2d40f8a1c6e5d2"
}
}Every code, its HTTP status and what to do about it is in Errors.
Pagination
Lists page by cursor, never by offset: on a feed that changes while you read it, an offset skips and repeats. Ask for a page size with limit, then pass meta.next_cursor back as cursor until it comes back null.
let cursor = null;
const all = [];
do {
const url = new URL("https://api.scrapefield.com/v1/tiktok/videos");
url.searchParams.set("username", "nasa");
url.searchParams.set("limit", "30");
if (cursor) url.searchParams.set("cursor", cursor);
const res = await fetch(url, { headers: { Authorization: `Bearer ${key}` } });
const { data, meta } = await res.json();
all.push(...data);
cursor = meta.next_cursor; // null on the last page
} while (cursor);11 of the 18 endpoints return lists. Each one’s maximum limit is on its page.
| Code | HTTP | When, and what to do |
|---|---|---|
invalid_cursor | 400 | The cursor was not one we issued. Pass `meta.next_cursor` from the previous page verbatim, or omit it. |