Skip to main content

Pagination

List endpoints return their results one page at a time, newest first, using keyset pagination: you ask for the page that comes after the last item you have. Unlike page numbers, this stays correct while new items keep arriving. This page explains the parameters, the response fields and how to walk a whole list.

Parameters​

ParameterMeaning
limitHow many items to return. The default and the maximum depend on the list (see below). A value out of range fails with 422 validation_error.
afterThe id of the last item of the previous page. The response starts right after it. Leave it out for the first page.

GET /emails also takes before, the id of an item, to fetch the items newer than it.

Response​

Every list answers with the same envelope:

{
"object": "list",
"has_more": true,
"next_cursor": "pay_01a0b904297873e8b3524a26fdca0ab5",
"data": [
{ "object": "payment", "id": "pay_01a0b904...", "status": "paid" },
{ "object": "payment", "id": "pay_01a0b903...", "status": "pending" }
]
}
FieldMeaning
dataThe items of this page
has_moretrue when there is at least one more page
next_cursorPayments lists only: the value to pass as after for the next page, or null on the last page. It is the id of the last item in data.

On lists without next_cursor, pass the id of the last item in data as after. The result is the same.

Limits per list​

ListsDefault limitMaximum
Email: emails, received emails, contacts, templates, logs20100
Payments: payments, transactions, e-invoices20100
Support: conversations50100
Support, Products and CRM: tickets, products, orders, customers50200

A few small lists, such as domains, webhooks and broadcasts, return every item in one response.

Conversation messages page differently, by sequence number: GET /chat/conversations/{id}/messages takes after_seq (the seq of the last message you have) and a limit of up to 200, 100 by default. That is how you sync a conversation incrementally.

Walk through a whole list​

Fetch a page, process it, and keep going while has_more is true:

# First page
curl "https://api.hatang.dev/payments?limit=100" \
-H "Authorization: Bearer $HATANG_API_KEY"

# Next page: pass next_cursor (or the last id) as after
curl "https://api.hatang.dev/payments?limit=100&after=pay_01a0b904297873e8b3524a26fdca0ab5" \
-H "Authorization: Bearer $HATANG_API_KEY"
tip

Filters such as status stay the same on every page: send them with each request together with after. Each page is one request against the rate limit, so use the largest limit you can handle.

Next steps​

View this page as Markdown