The public API
The v1 REST surface: authentication, available resources, idempotency, entity scoping, and where the OpenAPI description lives.
ReferenceFor Developers
Basics
The API is served under `/api/v1`. Every request authenticates with an organization API key; requests without a valid key are rejected. A machine-readable description of the surface is published at `/api/v1/openapi.json`, and `/api/v1/capabilities` reports what the calling key is permitted to do.
| Resource | Purpose |
|---|---|
| /api/v1/legal-entities | The entities in the organization — the scope every other call operates in. |
| /api/v1/journal-entries | Reading and creating journal entries. |
| /api/v1/reports | Financial statement data. |
| /api/v1/audit-events | The audit trail. |
| /api/v1/webhooks | Managing webhook subscriptions. |
| /api/v1/capabilities | What the authenticated key can do. |
| /api/v1/openapi.json | The OpenAPI description of the surface. |
Entity scoping
Every accounting record belongs to a legal entity, so most calls require one. Fetch the entity list first and hold the identifiers rather than hard-coding them — an organization can add entities, and a hard-coded identifier is a bug waiting for that day.
Idempotency
Creating operations accept an idempotency key. Retrying with the same key returns the original result rather than creating a second record, and the response indicates when a request was replayed rather than newly processed.
Integration practice
- Treat a timeout as unknown rather than failed, and retry with the same idempotency key.
- Back off exponentially on retries rather than hammering.
- Handle validation errors as data problems to surface, not as transient failures to retry.
- Log the request identifier from responses — it is what support will ask for.
- Test against a non-production entity before pointing at live books.
- Prefer webhooks over polling for change notification.
Common questions
No. Unbalanced entries are refused at posting, through every interface. Build the complete entry and post it in one call.
See alsoHow the general ledger works
Call `/api/v1/capabilities`. Reading it at startup is better than inferring permissions from failures.
Use a dedicated legal entity for integration testing. It keeps test data out of the entities you report from while exercising the same code path.
Was this useful?

