Concepts

Pagination

Every list endpoint takes the same two query parameters and returns the same envelope.

GET /api/v1/<resource>?limit=50&cursor=<next_cursor from the previous page>
Parameter Type Notes
limit integer 1 to 100. The default is 50. Any other value returns 400.
cursor string The next_cursor value of the previous response. A cursor that does not decode returns 400.
{
  "data": [],
  "next_cursor": "eyJrIjoiMjAyNi0wOC0xOVQxMjowMDowMC4wMDArMDA6MDAiLCJpIjoiN2M5ZTY2NzktNzQyNS00MGRlLTk0NGItZTA3ZmMxZjkwYWU3In0"
}

next_cursor is null on the last page.

Cursors are opaque#

Pass the cursor back as you received it. Do not build or edit a cursor.

Order#

Lists run from newest to oldest, by created_at, received_at or sent_at descending, and then by id. Cursors are keyset cursors on that pair. A row added while you page through a list does not shift the pages and does not cause duplicates.

Walk every page#

cursor=""
while :; do
  page=$(curl -s "https://app.anymail.watch/api/v1/prospects?limit=100&cursor=$cursor" \
    -H "Authorization: Bearer $ANYMAIL_TOKEN")
  echo "$page" | jq -c '.data[]'
  cursor=$(echo "$page" | jq -r '.next_cursor // empty')
  [ -z "$cursor" ] && break
done

Each page is one request against your rate limit.

Exceptions#

  • Companies use an offset cursor. The cursor is still opaque. The list is assembled in memory because the temperature filter works on a value computed from events. If companies are imported while you page, a page can skip a row or repeat one at a boundary.
  • Mailboxes are not paginated. next_cursor is always null.
  • Offers apply the status filter to the page after it is fetched. A page can hold fewer than limit rows while next_cursor is not null. Keep paging until next_cursor is null.

Date filters#

Date parameters such as created_since and since accept any ISO 8601 value, for example 2026-09-01 or 2026-09-01T00:00:00Z.