Skip to content

Offset vs Cursor Pagination

Query Parameters

Offset

GET /users?page=2&limit=20&sortBy=createdAt:DESC&search=john&filter.role=$eq:admin
ParamDescriptionExample
pagePage number (1-based)2
limitItems per page20
sortBySort (multi allowed)createdAt:DESC
searchFull-text searchjohn
filter.{col}Filter by columnfilter.role=$eq:admin

Cursor

GET /users?limit=20&after=eyJpZCI6IjEwIn0&sortBy=createdAt:DESC
ParamDescriptionExample
limitItems per page20
afterForward cursor (Base64url)eyJpZCI6IjEwIn0
beforeBackward cursoreyJpZCI6NX0
sortBySortcreatedAt:DESC

Cursor mode activates automatically when after/before is present or paginationType: 'cursor' is set.

Response Format

Offset

json
{
  "data": [{ "id": "1", "name": "Alice" }],
  "meta": {
    "itemsPerPage": 20,
    "totalItems": 500,
    "currentPage": 1,
    "totalPages": 25,
    "sortBy": [["createdAt", "DESC"]]
  },
  "links": {
    "first": "/users?page=1&limit=20&sortBy=createdAt%3ADESC",
    "previous": null,
    "current": "/users?page=1&limit=20&sortBy=createdAt%3ADESC",
    "next": "/users?page=2&limit=20&sortBy=createdAt%3ADESC",
    "last": "/users?page=25&limit=20&sortBy=createdAt%3ADESC"
  }
}

Cursor

json
{
  "data": [{ "id": "10", "name": "Bob" }],
  "meta": {
    "itemsPerPage": 20,
    "hasNextPage": true,
    "hasPreviousPage": true,
    "startCursor": "eyJpZCI6IjEwIn0",
    "endCursor": "eyJpZCI6IjI5In0",
    "sortBy": [["createdAt", "DESC"]]
  },
  "links": {
    "current": "/users?limit=20&after=eyJpZCI6IjEwIn0",
    "next": "/users?limit=20&after=eyJpZCI6IjI5In0",
    "previous": "/users?limit=20&before=eyJpZCI6IjEwIn0"
  }
}

Released under the MIT License.