links.next is a cursor. Send it back as the cursor parameter — on a
POST /search, as cursor in the body — until it is null:
Pages stay put while records change
Contacts, organizations and deals are paged from the last record you received, not by position. A record created or deleted while you walk the list never makes you see a record twice or miss one, and a record edited mid-walk shows up again later with its new values. That is what makes a sync withupdated_since safe
— see Syncing.
Treat the cursor as opaque
Do not parse, construct, or store a cursor beyond one walk. Its contents are an implementation detail and change without notice. A cursor is only valid for the query that produced it. Send it with the same filters andsort; anything else — a cursor you built, one from another
endpoint, or one replayed with different filters — returns 400 invalid_cursor.
There is no total count
The response tells you whether another page exists (meta.has_more), not how
many records there are in total. Counting the filtered set would mean a second
full scan on every page, which gets slower exactly as a workspace grows.
If you need a count, page through and count what you receive.
Sorting
Passsort to order a collection, for example sort=-created_at for newest
first or sort=updated_at to walk changes in order. Prefix a key with - for
descending; records without a value sort last either way.
Choosing a limit
limit defaults to 50 and accepts up to 200. Larger pages mean fewer round
trips; smaller pages mean faster individual responses. For a bulk sync, 200 is
usually right.