Pagination
How to walk a whole list without losing anything.
A cursor, not a page number
Every list is paginated by cursor. A request takes two parameters:
| Parameter | Meaning |
|---|---|
limit | How many rows to return: 1 to 100, 50 by default |
starting_after | The cursor from the previous answer |
The answer always has one shape:
{
"data": [ … ],
"has_more": true,
"next_cursor": "eyJrIjoiMjAyNi0wOS0xMlQxMDowMDowMC4wMDBaIiwiaWQiOiJja3gxIn0"
}While has_more is true, pass next_cursor as starting_after and ask again. When the list ends, has_more is false and next_cursor is null.
cursor=""
while :; do
page=$(curl -sG "https://api.tg-desk.com/v1/contacts" \
-H "Authorization: Bearer $TYGY_API_KEY" \
--data-urlencode "limit=100" \
${cursor:+--data-urlencode "starting_after=$cursor"})
echo "$page" | jq -c '.data[]'
[ "$(echo "$page" | jq -r .has_more)" = "true" ] || break
cursor=$(echo "$page" | jq -r .next_cursor)
doneWhy not page numbers
Page numbers break when the data changes while you walk it: a new row shifts everything down, so one row arrives twice and another is skipped. A cursor points at a position, so that cannot happen.
For the same reason we do not return a total count. An exact number in a live list is stale the moment we send it, and computing it costs more than the page itself. Do not rely on counts — walk until has_more is false.
Order
Lists are newest-first, by last change. Messages inside a conversation are the opposite — oldest first, the natural reading order of a thread; order=desc flips it.
Only what changed
Lists accept updated_since. It takes an instant and returns only what changed after it:
curl -sG "https://api.tg-desk.com/v1/conversations" \
-H "Authorization: Bearer $TYGY_API_KEY" \
--data-urlencode "updated_since=2026-09-12T10:00:00Z"That is how a periodic sync works: note the time you started, walk the pages, then next time ask for changes since that moment. If you need to react quickly, subscribe to webhooks instead — they arrive at once, not on a timer.
A broken cursor
The cursor is opaque: do not parse it or build one yourself. Passing something of your own answers 422:
{
"error": {
"code": "validation_failed",
"details": [{ "field": "starting_after", "message": "Malformed cursor" }]
}
}← Previous: Authentication and scopes
Next: Errors →