Menu

Concepts

Pagination

Cursor pagination: limit, cursor, has_more, and filters bound to cursors.

Every list answers one page at a time, newest first, and hands you a cursor for the next page. Cursors are exact: a row is never skipped or repeated between pages, even when rows are written while you page.

json
{
  "data": [ { "id": "0b8e2c6d-4f1a-4b7e-9d3c-6a5f4e3d2c1b", "name": "Jane Doe" } ],
  "has_more": true,
  "next_cursor": "eyJ2IjoxLCJrIjpbIjIwMjYtMTAtMjEgMDk6MzA6MDAuMTIzNDU2KzAwIiwiMGI4ZS4uLiJdfQ"
}

Parameters

  • limit: 1 to 200, default 50 (some lists allow fewer, the reference says which). A value outside the range is clamped, not refused.
  • cursor: the next_cursor of the previous page. Leave it out for the first page.
  • order: where a list offers it, for example updated_at_asc on leads for incremental sync.

Walking a list

bash
cursor=""
while :; do
  page=$(curl -s "https://api.dmhero.ai/v1/leads?limit=200&tag=webinar${cursor:+&cursor=$cursor}" \
    -H "Authorization: Bearer $DMHERO_API_KEY")
  echo "$page" | jq -c '.data[]'
  [ "$(echo "$page" | jq -r '.has_more')" = "true" ] || break
  cursor=$(echo "$page" | jq -r '.next_cursor')
done

Filters are bound to the cursor

A cursor remembers the filters and the sort order of the request that produced it. Send it with the same filters; sending it with different ones answers 400 API_CURSOR_INVALID_400, because the position would mean nothing in the other list. To change filters, start again without a cursor.

Cursors are opaque

A cursor is a token, not a contract: do not build or edit one. It does not expire, but it describes a position, so a cursor kept for weeks still works and simply continues from where it pointed. An edited cursor answers 400.

Incremental sync

To mirror leads into another system, page with order=updated_at_asc and updated_after set to the newest updated_at you stored last time. Each run reads only what changed. The CRM sync recipe combines this with the lead.updated webhook.

Note: GET /v1/campaigns also accepts the offset it has always taken, for existing Clay tables. New code should use cursor.
Pagination | DM Hero Developers