Klantly Developers

Pagination, filters and synchronising

Page through lists with a cursor, filter and sort, and keep changes in sync.

Lists

A list response has data (the objects) and meta (the pagination):

JSON
{
  "data": [],
  "meta": {
    "limit": 50,
    "next_cursor": "eyJpdiI6ImYvZUgxaFR5bVRHSTBXeDFGYmZrZWc9PSIsInZhbHVl…",
    "prev_cursor": null
  }
}

Paging with a cursor

Request the next page with the next_cursor from the previous response:

cURL
curl "https://app.klantly.com/api/v1/customers?limit=100&cursor=eyJpdiI6ImYvZUgxaFR5bVRHSTBXeDFGYmZrZWc9PSIsInZhbHVl…" \
  -H "Authorization: Bearer $KLANTLY_API_KEY"

When next_cursor is null, you are on the last page. A cursor points to a position in the sort order, not to a page number: records added in between do not shift anything. If you sort by updated_at, a record that changes while you page can show up again further on, so deduplicate on id. A cursor belongs to one sort order: do not use it with a different sort. limit ranges from 1 to 100; the default is 50. The cursor is encrypted: use it as you receive it and never build one yourself. A cursor is a few hundred characters long and encrypted; store it as free text and pass it back unchanged.

Filtering and searching

Filters go in filter[...], for example filter[status]=lead or filter[email]=jan@example.com. For customers, q searches several fields at once: name, email, company name and phone number. Which filters exist is listed per endpoint in the API reference. An unknown filter returns a validation error.

Sorting

sort=created_at sorts ascending, sort=-created_at descending. Descending by creation date is the default everywhere; only a conversation's messages run oldest to newest. You can choose created_at or updated_at; for events and for a conversation's messages only created_at. Which fields you can sort on and what the default is are listed per endpoint in the API reference.

Synchronising

To keep your own system up to date, periodically fetch what has changed:

  1. Remember the moment of your previous synchronisation.
  2. Request filter[updated_since]=<that moment>&sort=updated_at and go through all pages.
  3. Store the new moment.

Tip

Use a small overlap, for example one minute, so you never miss a change that happened exactly during your previous run.

Child objects do not always count: a payment, an attachment or a message updates the updated_at of the invoice, quote or conversation, but a note on a customer or deal does not. Track notes with the note.created, note.updated and note.deleted events.

You never see a deletion through filter[updated_since] — the record simply disappears from the list. Listen for the *.deleted events instead.

Events have no modified date: there you use filter[created_since] to fetch what happened since a moment. See Webhooks for catching up on missed messages.

Last updated on September 21, 2026