Overview
All list endpoints in the OpenFX v1 API use cursor-based pagination. Unlike offset-based pagination, cursors provide stable, consistent results even when new resources are created or existing resources are modified between page requests.Cursor-based pagination is the standard for financial APIs because it guarantees you will never skip or duplicate records when paginating through results — critical when reconciling transactions or payments.
Query Parameters
Every list endpoint accepts these pagination parameters:| Parameter | Type | Default | Description |
|---|---|---|---|
limit | integer | 50 | Number of items to return per page. Minimum 1, maximum 200. |
starting_after | string | — | Return items created after the resource with this ID. For forward pagination. |
ending_before | string | — | Return items created before the resource with this ID. For backward pagination. |
Response Envelope
All list endpoints return a consistent response shape:| Field | Type | Description |
|---|---|---|
items | array | The page of results. May be empty if no results match. |
pagination.hasMore | boolean | true if more results exist beyond this page. |
pagination.nextCursor | string or null | The cursor to pass as starting_after to fetch the next page. null when hasMore is false. |
Paginating Through All Results
To retrieve all results, repeatedly fetch pages using thenextCursor value until hasMore is false.
Date Range Filtering
Most list endpoints support date range filtering using bracket notation on thecreatedAt field:
| Parameter | Type | Description |
|---|---|---|
createdAt[gte] | ISO 8601 datetime | Return items created at or after this timestamp. |
createdAt[lte] | ISO 8601 datetime | Return items created at or before this timestamp. |
Filter Parameters
List endpoints support resource-specific filters alongside pagination. Filter parameters use camelCase:| Parameter | Available On | Description |
|---|---|---|
customerId | payments, accounts, counterparties, transactions | Filter by customer. |
accountId | transactions, transfers | Filter by account. |
status | payments, customers, accounts | Filter by lifecycle status. |
type | transactions, accounts, entities | Filter by resource type. |
rail | payments, inbound payments | Filter by payment rail (e.g., ach, swift). |
direction | transactions | Filter by debit or credit. |
Why Cursors, Not Offsets
Offset-based pagination has serious problems with financial data:| Problem | Offset Pagination | Cursor Pagination |
|---|---|---|
| New records inserted | Items shift — you may see duplicates or skip items | Stable — cursor position is fixed |
| Records deleted/modified | Items shift unpredictably | Unaffected — cursor references a specific record |
| Deep pages | Slow — database must skip N rows | Fast — database seeks directly to cursor position |
| Concurrent requests | Results may be inconsistent across pages | Results are always consistent |
Best Practices
Always use the
nextCursor value. Do not attempt to construct cursor values or extract IDs from the items array for pagination. Always use the nextCursor returned in the pagination object.Use the maximum
limit for bulk operations. When fetching all records (e.g., for reconciliation), set limit=200 to minimize the number of API calls.Combine date filters with pagination. For large datasets, narrow your query with
createdAt[gte] and createdAt[lte] before paginating. This reduces total pages and improves response times.Handle empty pages gracefully. A response with
"items": [] and "hasMore": false is valid — it means no results match your query.Related
- Resource IDs — how UUIDv7 IDs enable time-ordered cursor pagination
- Rate Limiting — manage request volume when paginating large datasets
- API Reference — see pagination parameters on every list endpoint