Pass
next_cursor back as cursor until has_more is false. Keep every other query parameter the same.
Why cursors
Calls and messages arrive all the time. With page numbers, a new call on page 1 pushes an old one onto page 2 and you’d read it twice. Cursors remember the exact position (by creation time and id), so each item appears exactly once. Cursors are signed and remember the filters they were issued for. If you change a filter and keep the old cursor, you get422 invalid_request (“This cursor was issued for a different query”). Start again from the first page instead. Treat cursors as opaque: don’t parse or build them.
Walk every page
Lists that page differently
There aren’t any. Every list endpoint pages the same way, withlimit and cursor in and data, next_cursor and has_more out, including webhook deliveries, call events, scheduled calls and short lists like webhook endpoints. A few lists add extra fields next to data:
GET /v1/callsaddstotaland asummaryblock (today’s calls, completed, talk time, needs attention) for the filters you sent.GET /v1/inbox/threadsorders by last activity and addscounts(open, needs you, mine, unread).
for await (const call of kallabot.calls.list()) in TypeScript, for call in client.calls.list() in Python.