Pagination
Cursor-based pagination in Navixy GraphQL API
When querying lists of entities (devices, assets, users, etc.), the API returns paginated results. This prevents overwhelming responses when you have thousands of records.
To control which results appear and in what order, see Filtering and sorting.
The rules on this page apply to every product of the API, with one exception. Console and IAM lists have a different default page size and page backward differently. See the end of Pagination parameters.
Where pagination applies
The API has two types of queries for fetching data:
Single-entity queries return one item by ID. They use singular names:
device,asset,schedule.List queries return multiple items matching your criteria. They use plural names:
devices,assets,schedules.
Pagination applies to all list queries. They return connection types following a consistent pattern: devices returns DeviceConnection, assets returns AssetConnection, auditEvents returns AuditEventConnection, and so on.
Many nested fields are also paginated, for example Workspace.devices or AssetGroup.currentAssets. You can identify paginated fields by their return type (anything ending in Connection) or by the presence of first, after, last, and before arguments.
Pagination types are described in separate sections of each entity's page. See Asset pagination types as an example. You can also use introspection to explore them in your GraphQL client.
The Connection pattern
Navixy GraphQL API uses Relay Cursor Connections, a pagination standard from the GraphQL community. Instead of traditional page numbers, they use opaque cursors that point to specific positions in the result set.
Using cursors instead of page numbers enables the following:
Stable results: If new items are added while you're paginating, you won't see duplicates or miss items.
Efficient: The database can resume from exact positions without re-scanning.
Flexible: Works well with real-time data that changes frequently.
Paginated query structure
Every paginated query returns a Connection type with this structure (we're using the device entity as an example, but the principle is the same):
Reading results
You can access entities in two ways:
edges[].node: Includes a cursor for each item (useful when you need cursors)nodes[]: Direct array of entities (simpler when you only need the data)
Check pageInfo.hasNextPage to determine if more data is available.
Pagination parameters
Pagination arguments are passed directly to the query:
first
Int
Number of items to fetch from the start (default: 20, max: 100)
after
String
Cursor: fetch items after this position
last
Int
Number of items to fetch from the end
before
String
Cursor: fetch items before this position
Use first/after for forward pagination (most common). Use last/before for backward pagination.
Requesting more than 100 items doesn't cap the page at 100: it returns a validation error.
The Console connections, accessibleOrganizations and accessibleWorkspaces, follow Console's own rules: a default page size of 50, backward paging only from a cursor, and a total that can be approximate. See Console API reference. The IAM connections use the same page size and backward paging. roleHolders pages forward only and returns no total. See IAM API reference.
Forward pagination
Start by requesting the first page, then use endCursor to get subsequent pages.
First page
Response:
Next page
To fetch the next page, pass endCursor from the previous response as the after argument:
Repeat this pattern, using each response's endCursor as the next request's after until hasNextPage is false.
Backward pagination
Use last and before to paginate from the end of the result set. This is useful for showing the most recent items first.
Previous page
To get the previous page, use startCursor as the before argument:
How total count works
The total field returns information about how many items match your query. Because counting can be expensive for large datasets, the API provides a precision field that indicates how the count was determined:
EXACT
The count is exact.
APPROXIMATE
The count isn't exact. The description of the connection's total field says how it can differ from the number of items you can page through.
total counts only the entities that your roles let you read. Every count is EXACT, except accessibleWorkspaces of Console, which is APPROXIMATE: its count can exceed the number of workspaces that the connection returns. Handle APPROXIMATE in your UI, for example by displaying "About 10,000 results", and treat a precision that you don't know as APPROXIMATE.
Best practices
Choose an appropriate page size. Use 20–50 items for UI lists, up to 100 for background sync. The default is 20 if not specified, and the maximum is 100 per request.
Keep sort parameters consistent. A cursor encodes a position in one sort order. Changing orderBy between requests returns no error, but the next page is then cut at a position that means nothing in the new order, so items are skipped or repeated. Always use the same orderBy value when paginating through a result set. If you need a different sort order, start pagination from the beginning.
Don't store cursors long-term. Cursors are meant for immediate pagination within a session. They may become invalid after data changes affecting sort order, server updates, or extended time periods.
Handle empty results. Always check for empty nodes or edges arrays before processing results.
No random page access. Cursor-based pagination doesn't support "jump to page 50": you can only navigate sequentially through results. This is a deliberate trade-off for stability and performance. If you need random access to pages, consider limiting the result set with filters first.
See also
Filtering and sorting: Narrow list queries and control result order
Error handling: Understand error structure, codes, and common error scenarios
Last updated
Was this helpful?