Skip to content

Pagination

Soxom supports cursor-based and offset-based pagination with automatic iteration.

TypeDescriptionUse Case
cursorToken or ID marking positionRecommended for most APIs
offsetTraditional offset/limitLegacy APIs, simple use cases
pagination:
# Default pagination type for all list endpoints
default_type: cursor
# Define pagination schemes
schemes:
cursor:
cursor:
request_param: after # Query param for cursor
response_property: next_cursor # Response field with next cursor
limit:
request_param: limit
default: 20
max: 100
has_more:
response_property: has_more # Boolean indicating more results
offset:
offset:
request_param: offset
limit:
request_param: limit
default: 20
total:
response_property: total # Total count of results

Best for large datasets and real-time data.

pagination:
schemes:
cursor:
cursor:
request_param: after
response_property: next_cursor
# Or use last item's ID:
# response_property: data[-1].id
limit:
request_param: limit
default: 20
max: 100
has_more:
response_property: has_more

Expected API Response:

{
"data": [...],
"next_cursor": "cursor_abc123",
"has_more": true
}

Traditional pagination with page numbers.

pagination:
schemes:
offset:
offset:
request_param: offset
limit:
request_param: limit
default: 20
total:
response_property: total

Expected API Response:

{
"data": [...],
"total": 150,
"offset": 0,
"limit": 20
}

Use the x-soxom-pagination extension in your OpenAPI spec:

paths:
/users:
get:
x-soxom-pagination:
type: cursor
cursor: $request.after
results: $response.data
has_more: $response.has_more
parameters:
- name: after
in: query
schema:
type: string
- name: limit
in: query
schema:
type: integer
default: 20
responses:
"200":
content:
application/json:
schema:
$ref: "#/components/schemas/UserListResponse"
/products:
get:
x-soxom-pagination:
type: offset
results: $response.data
total: $response.total
PropertyDescription
typecursor or offset
cursorJSONPath to cursor in request/response
resultsJSONPath to results array
has_moreJSONPath to has_more boolean
totalJSONPath to total count (offset only)

Automatically fetches all pages:

// Iterate through all users automatically
for await (const user of client.users.list()) {
console.log(user.name);
}
// With filters
for await (const user of client.users.list({ status: "active" })) {
console.log(user.name);
}
// Collect all into array
const allUsers = await client.users.list().toArray();

Control pagination manually:

// Get first page
const page = await client.users.list({ limit: 10 });
console.log(page.data);
// Check for more pages
if (page.hasMore) {
const nextPage = await page.next();
console.log(nextPage.data);
}
// Or use the cursor directly
const page2 = await client.users.list({
limit: 10,
after: page.nextCursor
});

Soxom expects list responses to have this structure:

{
"data": [
{ "id": "1", "name": "Alice" },
{ "id": "2", "name": "Bob" }
],
"next_cursor": "cursor_xyz",
"has_more": true
}
{
"data": [
{ "id": "1", "name": "Alice" },
{ "id": "2", "name": "Bob" }
],
"total": 100,
"offset": 0,
"limit": 20
}
  1. Prefer cursor pagination for better performance with large datasets
  2. Set reasonable defaults - 20-50 items per page is typical
  3. Set max limits to prevent abuse
  4. Use has_more instead of checking cursor existence
  • Retries - Automatic retry configuration
  • Timeouts - Request timeout settings