Sort and paginate
Use stable sorting, Relay cursors, and REST pagination.
Cursors are bound to the root, locale, filter, search, and sort contract. Drop the cursor whenever any of those inputs changes.
Access
Use a Backend-scoped delivery permission. Preview session authorization applies separately.
Continue a connection
First page:
query Articles($after: String) {
article_all(
first: 25
after: $after
locale: "en-US"
filter: { featured: { eq: true } }
sort: [published_at_desc]
) {
items {
_id
title
}
page_info {
has_next_page
end_cursor
}
}
}
Send { "after": null }, then reuse page_info.end_cursor as after without changing the other arguments. REST uses the same page_info.end_cursor wire key:
curl 'https://delivery.example.com/rest/article?first=25&locale=en-US&filter[featured][eq]=true&sort=published_at_desc&after=END_CURSOR' \
-H 'x-api-key: YOUR_DELIVERY_KEY'
Use last with before for backward traversal. Do not combine forward and backward page sizes.
Sort behavior
- Page size defaults to 25. Values above 100 are capped at 100.
- Published delivery defaults to
published_at_desc; Draft and Release Preview defaults toupdated_at_desc. - Missing values sort last, with ID as the stable tie-breaker.
- Up to three combined sort plans are accepted for Content.
- Search relevance and
nearestparticipate ahead of field plans in the cursor contract. - Use only sort keys generated by GraphQL or OpenAPI.
- Draft and Release Preview supports ID and created, updated, or published timestamp sorts; field and relation sorts and
nearestare unavailable.
Combining first and last, or reusing a cursor with a changed query contract, produces a 400-class input error. A malformed REST page size uses the default; use positive sizes and do not rely on negative-size behavior. Legacy cursors are default-locale-only. No time-based cursor lifetime is promised.