JQL Fundamentals
Pagination
Offset/limit pagination and retrieveV2 cursor pagination.
JQL supports classic offset pagination through retrieve and keyset cursor pagination through retrieveV2.
retrieve: offset and limit
retrieve reads __meta__.offset and __meta__.limit, orders the queryset, then slices rows as offset:offset+limit. Response extras include filtered and displayed counts.
1{
2 "__meta__": {
3 "schema": "model",
4 "namespace": "tickets.Ticket",
5 "intent": "retrieve",
6 "authenticationClass": "jwt",
7 "filter": {
8 "status": "open"
9 },
10 "ordering": "-created",
11 "offset": 0,
12 "limit": 20
13 },
14 "id": null,
15 "title": null,
16 "created": null
17}retrieveV2: cursor pagination
retrieveV2 is a drop-in read intent for model namespaces. Without cursor, it behaves like offset/limit. With a cursor, it applies keyset filters anchored to the previous page.
1{
2 "__meta__": {
3 "schema": "model",
4 "namespace": "objects.Customer",
5 "intent": "retrieveV2",
6 "authenticationClass": "jwt",
7 "ordering": [
8 "-created",
9 "id"
10 ],
11 "limit": 25
12 },
13 "id": null,
14 "reference": null,
15 "created": null
16}When the page is full and ordering fields can be read, __extras__.nextCursor is an opaque base64-encoded JSON cursor. Pass it back verbatim:
1{
2 "__meta__": {
3 "schema": "model",
4 "namespace": "objects.Customer",
5 "intent": "retrieveV2",
6 "authenticationClass": "jwt",
7 "ordering": [
8 "-created",
9 "id"
10 ],
11 "limit": 25,
12 "cursor": "eyJjcmVhdGVkIjogIjIwMjYtMDctMjJUMDA6MDA6MDBaIiwgImlkIjogIjEwMSJ9"
13 },
14 "id": null,
15 "reference": null,
16 "created": null
17}nextCursor is null when no rows are returned, the page has fewer rows than limit, or ordering values cannot be extracted.
Ordering guidance
Always include deterministic ordering for cursor pagination. A timestamp plus id is a good pattern: ["-created", "id"]. For mutable sort fields, include a stable tiebreaker.
See filters and queries and /developer/data-hooks.