Skip to main content

Two styles, and when you meet each

Compago has two generations of list endpoints, and they page differently. The style is a property of the endpoint, not something you choose per request. Every list on the Developer API is cursor based. The offset endpoints are stable and are not going away.

Cursor pagination (Developer API)

These examples call the production host. While you build, replace https://api-harmony.compago.com with https://demo-api-harmony.compago.com and use a key from the Demo dashboard. See Environments.
Ask for a page, then follow the cursor the response hands back.
Every list response has the same envelope:
To fetch the next page, pass nextCursor back as cursor. Stop when nextCursor is null.

Rules worth knowing

limit accepts 1 to 100 and defaults to 20. A larger value is rejected with a 400, not silently reduced, so a client asking for 1,000 rows finds out rather than quietly looping on pages of 100.
Treat nextCursor as a string with no internal meaning. Do not parse it, build one, or reuse a cursor from a different endpoint. A cursor Compago did not issue is rejected with a 400 rather than being ignored, because a cursor that silently fell back to page one would turn a paging loop into an infinite one.
Rows come back by creation date descending, with the id breaking ties. The tie-break matters: without it, rows created in the same millisecond could be served twice or skipped entirely.
The envelope reports hasMore, not a total. Counting every matching row on each request means a full scan that gets slower as your history grows, so the endpoints do not do it. If you need a total, page through and count.
The cursor walks backwards from where you started, so rows created while you are paging are simply not part of the walk. To pick them up, start a fresh crawl and stop when you reach an id you have already seen, or filter on createdAtFrom.

Offset pagination (unversioned endpoints)

The older endpoints take page (from 1) and pageSize (up to 500), and return the total alongside the items:
Offset pages are not stable while rows are being created. A payment saved between your request for page 1 and your request for page 2 shifts every later row down by one, so a row can appear twice or not at all. For anything that has to be complete, such as reconciliation, use the Developer API.

Filtering instead of paging

Most list endpoints accept filters, and filtering is almost always cheaper than paging through everything and discarding rows client side. GET /developer/v1/payment alone accepts status, type, operationCode, createdAtFrom, createdAtTo, and the ids of the payment link, subscription, one-time payment or saved card the payment came from. Filters that accept several values are repeated:
The Developer API deliberately does not offer a free-text search parameter. Free-text matching cannot use an index, and one such query looping against production would compete for the same database connections your checkouts need. Filter on the structured fields instead.