Pagination and filters
Walk through long lists one page at a time and filter for what matters.
Endpoints that list objects return one page at a time, newest first. Each response says whether there are more items and carries the cursor for the next page.
A list response
{
"object": "list",
"data": [
{ "id": "ltr_8Kq2wX4mN7pR", "object": "letter", "status": "posted" }
],
"has_more": true,
"next_cursor": "eyJpZCI6Imx0cl84S3Eyd1g0bU43cFIifQ"
}| Field | What it is |
|---|---|
data | The items on this page, complete, newest first. |
has_more | true when there are more items after this page. |
next_cursor | The value to send as cursor to fetch the next page. null on the last page. |
In the example each item is shortened. In a real response, each item is the full object.
Parameters
| Parameter | What it does |
|---|---|
limit | How many items per page, from 1 to 100. Default: 20. |
cursor | The next_cursor of the previous page. Leave it out to fetch the first page. |
The cursor is an opaque string: do not build or change it. When fetching the next page, keep the same filters and the same limit as the first one. Items created after you started walking the list only show up in a new listing, from the first page.
Filters
All filters are optional and can be combined.
| Endpoint | Filters |
|---|---|
GET /v1/letters | status, reference, created_after, created_before |
GET /v1/verifications | status, reference, created_after, created_before |
GET /v1/balance/transactions | type, created_after, created_before |
GET /v1/events | type, object_id, created_after, created_before |
statusandtypetake one of the values listed in each endpoint's reference.referencefinds items with exactly thatreferencevalue. See Metadata and reference.created_afterincludes items created at or after that moment.created_beforeincludes items created before it. Use an ISO 8601 date and time, such as2026-10-01T00:00:00Z.object_idshows the events of one object, such as every event of a letter.
For example, every letter posted in October 2026:
curl "https://api.cartaflow.com.br/v1/letters?status=posted&created_after=2026-10-01T00:00:00Z&created_before=2026-11-01T00:00:00Z&limit=100" \
-H "Authorization: Bearer $CARTAFLOW_API_KEY"Remember to URL-encode values: the + of a time zone offset, for example, becomes %2B. UTC times ending in Z avoid that.
Walk every page
async function* listAll(path, params = {}) {
let cursor;
do {
const query = new URLSearchParams({ ...params, limit: '100', ...(cursor ? { cursor } : {}) });
const response = await fetch(`https://api.cartaflow.com.br/v1${path}?${query}`, {
headers: { Authorization: `Bearer ${process.env.CARTAFLOW_API_KEY}` },
});
const page = await response.json();
yield* page.data;
cursor = page.has_more ? page.next_cursor : undefined;
} while (cursor);
}
for await (const letter of listAll('/letters', { status: 'posted', created_after: '2026-10-01T00:00:00Z' })) {
console.log(letter.id, letter.reference);
}To follow statuses, use webhooks
Walking lists is good for reports and reconciliation. To know when each letter changes status, use webhooks instead of listing over and over.