Walking pages
has_more is false. At that point next_cursor is null.
Passing both returns
400 conflicting_cursors.
Cursors are opaque
A cursor is base64url and encodes an ordering position. Do not parse, construct or modify one — a cursor we did not issue returns400 invalid_cursor rather
than an empty page, so a mangled cursor fails loudly instead of looking like the
end of the list.
Why no offset
?page=47 degrades as the offset grows — the database counts past every skipped
row — and it is wrong in a way that is hard to see: records arrive while you are
reading. Calls complete, usage rows land. With an offset, an insertion shifts
every later page and you silently re-read or skip records. A cursor names a
position in the ordering, so it stays correct regardless of what arrives.
Once an offset parameter is documented it cannot be withdrawn without breaking
clients, which is why there has never been one here.
