Guide

Pagination

List endpoints return one page at a time, with a cursor that points at the next. Pass it back to get the next page; stop when there is none.

How it works

Lists use cursor pagination. Instead of a page number, every page carries an opaque cursor for the page after it. Cursors stay correct while records are being added — a new deal created while you page through the list does not push a record you have already seen onto the next page, or make you skip one.

Parameters

ParameterWhat it does
cursorThe page to fetch: meta.next_cursor or meta.prev_cursor from the previous response. Leave it out for the first page.
limitItems per page, 1 to 100. Default 25. Values outside the range are clamped.

Most list endpoints name the page size limit; a few name it per_page, with the same range and default. Each endpoint's reference lists exactly the parameters it takes, along with its filters and sort order.

The response

A page has three parts:

  • data — the records on this page.
  • meta — next_cursor and prev_cursor (null at either end), per_page and path.
  • links — next and prev as ready-made URLs. first and last are always null: a cursor list has no page numbers to jump to.
Response · 200 · one record shown
{
  "data": [
    {
      "id": "01a15c2e-4b7a-7f3e-9c1d-2e8f6a0b4c71",
      "title": "Hemstäd RUT – Henrik Ny",
      "value_cents": 320000,
      "currency": "SEK",
      "stage": "sent"
    }
  ],
  "links": {
    "first": null,
    "last": null,
    "prev": null,
    "next": "https://api.closepact.com/v1/api/deals?filter%5Bstatus%5D=open&limit=25&cursor=eyJjcmVhdGVkX2F0IjoiMjAyNi0xMC0xMiIsIl9wb2ludHNUb05leHRJdGVtcyI6dHJ1ZX0"
  },
  "meta": {
    "path": "https://api.closepact.com/v1/api/deals",
    "per_page": 25,
    "next_cursor": "eyJjcmVhdGVkX2F0IjoiMjAyNi0xMC0xMiIsIl9wb2ludHNUb05leHRJdGVtcyI6dHJ1ZX0",
    "prev_cursor": null
  }
}

Fetching everything

Request the first page, then keep requesting with cursor set to the last meta.next_cursor until it is null. Send your filters and limit with every request — the cursor holds only the position, not the query.

# First page
curl -G 'https://api.closepact.com/v1/api/deals' \
  -H "Authorization: Bearer $CLOSEPACT_API_KEY" \
  --data-urlencode 'filter[status]=open' \
  -d limit=100

# Next page: the same request, plus meta.next_cursor from the last response
curl -G 'https://api.closepact.com/v1/api/deals' \
  -H "Authorization: Bearer $CLOSEPACT_API_KEY" \
  --data-urlencode 'filter[status]=open' \
  -d limit=100 \
  -d cursor=eyJjcmVhdGVkX2F0IjoiMjAyNi0xMC0xMiIsIl9wb2ludHNUb05leHRJdGVtcyI6dHJ1ZX0

Good to know

  • Cursors are opaque. Do not build or decode them; their format can change.
  • Build the next request yourself from next_cursor. links.next is convenient, but not every endpoint carries your filters over into it.
  • Use limit=100 for bulk reads. Fewer pages means fewer requests against your rate limit.
  • Prefer webhooks to polling. To learn what changed, subscribe to events rather than re-reading whole lists.