Pagination & errors
One error envelope everywhere, cursor pagination on the transaction feed, and predictable rate limits.
The error envelope
Every error response, on any endpoint and any status code (400, 401, 403, 404, 405, 429), has the same shape:
{
"error": {
"code": "not_found",
"message": "Not found."
}
}Branch on error.code, which is a stable machine-readable string, rather than parsing error.message, which is human-facing and may be reworded.
Pagination
Transactions (cursor)
The transaction feed is cursor-paginated because bank feeds are insertion-heavy: new rows land at the top on every sync. A cursor keeps your walk stable where page numbers would skip or repeat rows. Each page returns up to 100 transactions, newest first:
{
"next": "https://api.endute.com/v1/accounts/6f2b.../transactions?cursor=cD0yMDI2LTA2LTI4",
"previous": null,
"results": [ /* up to 100 transactions, newest first */ ]
}- Follow the
nextURL to get the next page. Whennextisnullyou have reached the end. previouswalks back toward the newest rows.- The page size is fixed; there is no page-size parameter.
Treat the id as your idempotency key
id as you ingest.Investment activities (capped list)
Investment activities are not cursor-paginated: some rows (such as cash dividends) have no trade date, so they have no stable cursor position. Instead the list is returned in full up to a hard cap of the newest 500 rows, with a truncated flag:
{
"truncated": false,
"results": [ /* investment activities, newest first */ ]
}When truncated is true, narrow the window with the from and to date parameters to see older rows.
Rate limits
These limits apply across the API:
| Scope | Limit | Notes |
|---|---|---|
| Per API key | 120 requests / minute | Burst control on a single key. |
| Per developer account | 50,000 requests / day | Fair-use ceiling across all of your keys. |
| Unauthenticated | 30 requests / minute per IP | Backstop for requests without a valid key. |
When you exceed a limit you get a 429 with a Retry-After header (seconds to wait) and the error envelope with code throttled:
HTTP/1.1 429 Too Many Requests
Retry-After: 42
{
"error": {
"code": "throttled",
"message": "Request was throttled. Expected available in 42 seconds."
}
}Respect Retry-After and back off rather than retrying immediately.
Paths and methods
- Paths have no trailing slash. Use
/v1/accounts, not/v1/accounts/. A mistyped path returns the same error envelope as any other failure, not a redirect. - The API is read-only. Only
GET(andHEAD) are supported. Any other method, includingOPTIONS, returns405 Method Not Allowedin the error envelope. - Ids in paths are validated by type; a malformed id is a
404, and another account's id is also a404(never a 403, which would confirm it exists).
