| API | Pagination style | How it works |
|---|---|---|
| REST API (JTL-Wawi, SCX) | Page-based | Pass pageNumber and pageSize as query parameters |
| GraphQL API (JTL-Wawi) | Cursor-based | Pass first (page size) and after (cursor) as query variables |
Page-based Pagination (REST)
The REST API uses page-based pagination. Each response includes the current page of items plus metadata telling you the total number of items, how many pages exist, and whether there are more pages to fetch.Making a Paginated Request
Response Structure
Every paginated REST response follows this structure:Metadata Fields
| Field | Type | Description |
|---|---|---|
totalItems | number | Total items across all pages |
pageNumber | number | Current page |
pageSize | number | Number of items per page |
totalPages | number | Total number of pages |
hasNextPage | boolean | Whether more pages exist after this one |
hasPreviousPage | boolean | Whether pages exist before this one |
nextPageNumber | number | null | The next page number, or null if this is the last page |
previousPageNumber | number | null | The previous page number, or null if this is the first page |
items | array | Items for this page |
Requesting a Specific Page
Pass pagination parameters in the query string:| Parameter | Type | Description |
|---|---|---|
pageNumber | number | The page number (starts at 1) |
pageSize | number | Items per page |
Fetching the Next Page
UsehasNextPage and nextPageNumber to determine if there are more results:
Fetching All Pages
To retrieve every item across all pages, loop untilhasNextPage is false:
Cursor-based Pagination (GraphQL)
The GraphQL API uses cursor-based pagination. Instead of page numbers, you use an opaque cursor string to request the next set of results. This is more reliable for large, frequently changing datasets because new or deleted records don’t shift the page boundaries.Making a Paginated Request
Passfirst (page size) and optionally after (cursor) as query variables:
pageInfo object tells you whether more pages exist and provides the cursor for the next page.
Response Structure
Metadata Fields
| Field | Type | Description |
|---|---|---|
nodes | array | Items for this page |
pageInfo.hasNextPage | boolean | Whether more results exist beyond this page |
pageInfo.endCursor | string | Opaque cursor to pass as after for the next page |
totalCount | number | Total number of matching items across all pages |
Fetching the Next Page
Pass theendCursor from the previous response as the after variable:
endCursor from each response as the after variable in the next request. Stops when hasNextPage is false.
Best Practices
Use the smallest page size you need. Use smaller page sizes for UI-driven fetching (10-20 items). Use larger sizes only for background sync or batch jobs (50-100 items). Don’t rely on total counts for logic. BothtotalItems (REST) and totalCount (GraphQL) can change between requests as data is created or deleted. Use them for display only, not for control flow.
Handle empty pages gracefully. If a page has no items (e.g., records were deleted between requests), the items array will be empty. Don’t treat this as an error:
Quick Reference
| Question | REST (page-based) | GraphQL (cursor-based) |
|---|---|---|
| How do I set page size? | pageSize query parameter | first variable |
| How do I get the next page? | Use nextPageNumber | Use endCursor as after |
| How do I know when I’m done? | hasNextPage is false | pageInfo.hasNextPage is false |
| What’s the total count? | totalItems | totalCount |
| Can I jump to a specific page? | Yes (pageNumber=5) | No (traverse from the start) |
Next Steps
Rate Limiting
Understand request quotas, especially important when fetching many pages.
Error Handling
Handle errors that may occur during paginated fetches.
Using Platform APIs
Full guide to querying the GraphQL API with filtering, sorting, and pagination.
Webhooks
Instead of polling pages for changes, use webhooks to get notified in real time.