Conventions
Behaviors that apply across every endpoint. Read this once and the rest of the API is predictable.
Response envelope
Every response is a JSON object with data and error. Exactly one is non-null.
{
"data": { "id": "…", "name": "Cash", "...": "…" },
"error": null
}Error codes
| HTTP | code | Meaning |
|---|---|---|
| 401 | UNAUTHORIZED | Invalid or missing API key. |
| 402 | payment required | Organization has no active subscription. |
| 403 | FORBIDDEN | Authenticated, but not allowed. |
| 404 | NOT_FOUND | Resource doesn't exist. |
| 409 | CONFLICT | Idempotency conflict (see below). |
| 422 | VALIDATION_ERROR | Request failed validation; see details. |
| 429 | RATE_LIMITED | Too many requests; slow down. |
Idempotency
Write endpoints accept an Idempotency-Key header. Send a unique key per logical
operation; if the request is retried with the same key, the original result
is returned instead of performing the operation twice. Keys are remembered for
24 hours.
curl -X POST "$FLYWHEEL_API/journal-entries" \
-H "Authorization: Bearer $FLYWHEEL_KEY" \
-H "Idempotency-Key: invoice-1042-post" \
-H "Content-Type: application/json" \
-d '{ "...": "…" }'Reusing a key with a different payload returns 409 CONFLICT.
Rate limits
The API allows 120 requests per 60-second window, per API key. Exceeding it
returns 429 RATE_LIMITED. Back off and retry; spread bulk work over time or use
batch journal entries to do more
per request.
Pagination
List endpoints use cursor pagination: pass a limit and follow the returned
next_cursor to fetch the next page, rather than numeric offsets. This stays
correct and fast even as data grows.
To trim response size, GET /journal-entries also accepts a fields parameter — a
comma-separated allowlist of columns (e.g. fields=id,entry_number,status) — and
returns a lean column set by default (it omits the heavy source_data). Pair it
with count_journal_entries (GET /journal-entries/count) to size a result set
before fetching it.
Next
- API reference — every endpoint, with try-it-out.