Pagination
All list endpoints in the ibakepro API use cursor-based pagination.
By default, list endpoints return up to 50 results. You can adjust this with the limit parameter (maximum 100). When there are more results available, the response includes a cursor for the next page.
Pagination response format
All paginated responses follow this structure:
Paginated response
{
"data": [
{ "id": "Qm4TdvR7yKcB2sNxLpE9" },
{ "id": "HR7Pcz4Arg6kvZKseSil" }
],
"pagination": {
"limit": 50,
"has_more": true,
"next_cursor": "eyJpZCI6IkhSN1BjejRBcmc2a3ZaS3NlU2lsIn0",
"prev_cursor": null
}
}
prev_cursor is present in every paginated envelope but is always null.
Pagination is forward-only. To revisit an earlier page, restart the list and
page forward again, or keep the cursors you have already used.
Pagination parameters
- Name
limit- Type
- integer
- Description
Number of results to return per page. Default: 50, maximum: 100. A value above 100 is clamped to 100. A missing or non-numeric value falls back to 50.
- Name
cursor- Type
- string
- Description
Pagination cursor from a previous response. Pass the
next_cursorvalue verbatim to get the next page. Omit it for the first page.
Fetching the next page
When has_more is true, use the next_cursor value to fetch the next page of results.
Send every other query parameter (filters, sort, date ranges) unchanged alongside the cursor. A cursor is only valid against the same endpoint with the same filters and sort.
Request
curl -G https://au.api.ibakepro.com/api/v2/orders \
-H "Authorization: Bearer {api_key}" \
-d cursor="eyJpZCI6IkhSN1BjejRBcmc2a3ZaS3NlU2lsIn0" \
-d limit=50
Loop on has_more, never on page size
A page can contain fewer items than limit while has_more is still true.
Some list conditions are applied after the matching records are gathered (soft-deleted records, storefront visibility, name search, large status filters). On /orders, /products, /customers and /expenses the API tops a page up where it can, but on a heavily filtered list it will return a short page rather than keep going. When it does, has_more stays true and next_cursor resumes exactly where it stopped, rather than pretending the list has ended.
- Treat
has_moreas the only signal that more data exists. - Never stop because
data.length < limit, and never treat a short page as the end of the list. - Never treat an empty
dataarray as the end either, ifhas_moreistrue.
Iterating through all results
Follow next_cursor until has_more is false:
async function fetchAllOrders(apiKey) {
const orders = []
let cursor = null
do {
const params = new URLSearchParams({ limit: 100 })
if (cursor) params.set('cursor', cursor)
const response = await fetch(
`https://au.api.ibakepro.com/api/v2/orders?${params}`,
{ headers: { 'Authorization': `Bearer ${apiKey}` } }
)
const result = await response.json()
orders.push(...result.data)
// has_more is the only termination signal - a short page is not the end.
cursor = result.pagination.has_more ? result.pagination.next_cursor : null
} while (cursor)
return orders
}
Invalid and stale cursors
A cursor is an opaque string. It currently encodes the id of the last record on the page you received, but that is an implementation detail: do not decode, construct, or edit one. Pass back exactly what you were given.
On every list endpoint a cursor is rejected with 400 in two cases:
- It does not decode. Error code
invalid_cursor, fieldcursor, messageInvalid cursor. - It decodes but the record it points at no longer exists, because it was deleted or hard-removed. Error code
invalid_cursor, fieldcursor, messageCursor expired or invalid. Restart the list without a cursor.
Error response (400)
{
"error": {
"type": "validation_error",
"code": "invalid_cursor",
"message": "Cursor expired or invalid. Restart the list without a cursor.",
"field": "cursor"
}
}
A stale cursor is an error, not a silent restart. The API does not fall
back to page one. Handle invalid_cursor by restarting the list from no
cursor, which re-reads everything from the beginning of that ordering.
This is uniform across every list endpoint, including /webhooks and /webhooks/{id}/events. No list endpoint falls back to page one on a cursor it cannot resolve.
Notes
- Cursors are position-specific. Reuse them only against the same endpoint with the same filters and sort.
- Pages are a moving window. Records created, deleted, or reordered between calls can be seen twice or missed. Deduplicate by
idwhen a complete snapshot matters. has_moreis never a false negative. On every list endpointhas_moreandnext_cursorare derived from the records that survived post-read filtering, not from the raw batch size, so a page trimmed by soft-deleted or hidden records still reportshas_more: trueand hands back a cursor.Retry-Afteris returned on a429. Reads are rate limited separately from writes.updated_after(supported on products, customers, and expenses) returns only records whoseupdated_atis greater than or equal to the value supplied, and forces the sort toupdated_at. The comparison is inclusive. See Products.