Skip to content
Jetrepo
Esc
navigateopen⌘Jpreview
On this page

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 to updated_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 nearest participate 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 nearest are 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.

Was this page helpful?