Pagination
All list endpoints in the Seller API use cursor-based pagination. There is no total count and no page number — just data and nextCursor.
Request parameters
Every list endpoint accepts:
| Parameter | Type | Default | Notes |
|---|---|---|---|
limit | integer | 50 | Maximum 100. Must be a positive integer. |
cursor | string | — | Opaque token returned by the previous page. |
Example:
GET /v1/subscriptions?active=true&limit=25&cursor=eyJpZCI6MTAwfQResponse shape
{
"data": [
{ "id": "101", "...": "..." },
{ "id": "102", "...": "..." }
],
"nextCursor": "eyJpZCI6MTAyfQ"
}data— the page of results, in stable order.nextCursor— pass back ascursorto fetch the next page.nullmeans you've reached the end.
Iterating
const fetchAll = async (path, params = {}) => {
const all = [];
let cursor = null;
do {
const url = new URL(`https://subscord.com/api/v1/${path}`);
Object.entries(params).forEach(([k, v]) => url.searchParams.set(k, v));
url.searchParams.set("limit", "100");
if (cursor) url.searchParams.set("cursor", cursor);
const res = await fetch(url, {
headers: { Authorization: `Bearer ${process.env.SUBSCORD_API_KEY}` },
});
if (!res.ok) throw new Error(`Request failed: ${res.status}`);
const page = await res.json();
all.push(...page.data);
cursor = page.nextCursor;
} while (cursor);
return all;
};
const allActive = await fetchAll("subscriptions", { active: "true" });Cursor format
Cursors are opaque to clients. Internally they are base64url-encoded JSON tokens that point to the last record of the previous page. Do not parse, mutate, or construct cursors yourself — the encoding may change.
If you send an invalid or malformed cursor, the API returns 400 invalid_request:
{
"error": {
"code": "invalid_request",
"message": "Invalid cursor."
}
}Stability
Cursors point to a specific record, not an offset. New records inserted between requests do not shift your pagination — you will see them on a fresh listing only.
Cursors do not expire on a fixed timeline, but they are tied to the implicit ordering of the underlying list. Hold onto a cursor for hours or days at most.
Combining filters
Filter parameters (e.g. active, status, productId, createdAfter) compose with pagination, but the cursor only points to a position in the list — it does not remember which filters you applied.
Always re-send the same filters with each page. Changing filters mid-pagination will produce inconsistent results.
const params = { active: "true", productId: "42" };
let cursor = null;
do {
const page = await fetchPage("/v1/subscriptions", { ...params, cursor });
process(page.data);
cursor = page.nextCursor;
} while (cursor);