Pagination
List endpoints use one of three pagination styles depending on the domain. Read the API Reference for the exact parameters on a given endpoint; this page explains the patterns you'll encounter and which endpoints use each.
At a glance
| Style | Parameters | Used by |
|---|---|---|
ID cursors (after / before) | after, before | Notifications, row comments |
Keyset cursor (cursor / nextCursor) | limit, cursor | Bookings |
Offset (limit / offset) | limit, offset | Channels, workspace members, workspace teams |
| Limit-only (no continuation) | limit | Search, docs search, drive search |
| Not paginated | — | Board rows list, list-boards, booking types |
ID cursors — after / before
Some endpoints page using the _id of an item as the cursor. You pass the ID of the last (or first) item you saw back as after (or before) to fetch the adjacent page.
Notifications
GET /public/v1/notifications
after— return notifications after this notification ID.before— return notifications before this notification ID.
The response is { notifications, unreadCount, count }. There is no separate cursor field — the cursor is the _id of a notification. To page forward, take the last notification's _id and pass it as after on the next request:
# First page
curl "https://api.copera.ai/public/v1/notifications" \
-H "Authorization: Bearer cp_pat_your_token_here"
# Next page — use the last notification's _id from the previous response
curl "https://api.copera.ai/public/v1/notifications?after=665f0a1b2c3d4e5f60718293" \
-H "Authorization: Bearer cp_pat_your_token_here"
Row comments
GET /public/v1/board/{boardId}/table/{tableId}/row/{rowId}/comments
Same after / before cursor params (comment IDs), plus a visibility filter (all | internal | external, default all). Unlike notifications, this endpoint returns a relay-style pageInfo:
{
"items": [ /* ...comments... */ ],
"pageInfo": {
"endCursor": "665f0a1b2c3d4e5f60718293",
"startCursor": "665f0a1b2c3d4e5f60718210",
"hasNextPage": true,
"hasPreviousPage": false
}
}
To page forward, pass endCursor as after while hasNextPage is true.
Keyset cursor — cursor / nextCursor
Bookings
GET /public/v1/bookings
limit— page size, 1–100 (default 25).cursor— opaque keyset cursor from the previous response.
The response includes nextCursor and hasMore:
{
"bookings": [ /* ... */ ],
"nextCursor": "eyJpZCI6Ii4uLiJ9",
"hasMore": true
}
Loop while hasMore is true, passing nextCursor back as cursor:
curl "https://api.copera.ai/public/v1/bookings?limit=50&cursor=eyJpZCI6Ii4uLiJ9" \
-H "Authorization: Bearer cp_pat_your_token_here"
Offset — limit / offset
Classic page-through with a numeric offset.
| Endpoint | limit (default / max) | offset |
|---|---|---|
GET /chat/channels | 100 / 200 | from 0 |
GET /workspace/members | 100 / 500 | from 0 |
GET /workspace/teams | 100 / 200 | from 0 |
# Second page of 50 members
curl "https://api.copera.ai/public/v1/workspace/members?limit=50&offset=50" \
-H "Authorization: Bearer cp_pat_your_token_here"
Limit-only
Search-style endpoints cap the result count with limit but do not offer a continuation cursor — request a larger limit (up to the endpoint's max) or refine your query.
| Endpoint | limit (default / max) |
|---|---|
GET /search | 50 / 100 |
GET /docs/search | 20 / 50 |
GET /drive/search | 20 / 50 |
Docs and drive tree endpoints (/docs/tree, /drive/tree) are bounded by a depth parameter (default 3, max 10) and a parentId, not by limit/cursor.
Not paginated
A few list endpoints return the full set in one response:
GET /board/list-boardsGET /board/{boardId}/table/{tableId}/rows— supportsq,filter, andsort, but returns all matching rows.GET /booking-types
When iterating large result sets, add a short delay between requests to stay under the per-minute rate limit, and stop as soon as a hasMore / hasNextPage flag is false.