REST over the business graph
Parties, agreements, obligations, work, dimensions, and events as resources — the same objects the interface and the agents use rather than a flattened export shape.
Platform · platform & data
Most ERP APIs are a second surface with their own auth model, their own idea of what a valid transaction is, and their own gaps. Ours goes through the same data layer and the same policy engine as the interface — which means an API key cannot do something a person with the equivalent role could not.
What it does
Parties, agreements, obligations, work, dimensions, and events as resources — the same objects the interface and the agents use rather than a flattened export shape.
An API key is an actor with its own permission set, subject to the same conflict matrix. A key that could create vendors and release payments is rejected at creation.
Every mutating call takes an idempotency key. A retried request cannot create a duplicate transaction, which matters more in accounting than almost anywhere else.
A journal entry submitted via API passes the identical invariant checks — balance, period state, account validity, dimensions. There is no privileged path.
Signed, retried with backoff, and replayable from a cursor, so a consumer that was down for an hour can catch up rather than silently missing events.
Ledger, documents, and the complete audit trail in open formats, on demand or scheduled into your warehouse. Leaving has to be technically possible or the rest is talk.
The common architecture treats the API as a parallel entry point, which produces two problems that both show up in security review. The auth model diverges from the UI’s, so answering "what can this integration do" requires reasoning about two systems. And business rules that live in the interface layer get bypassed, which is how integrations quietly post things the UI would have refused.
Routing the API through the same data access layer and the same policy engine removes both. An API key is an actor in the permission model. A journal entry submitted by an integration faces the same invariant checks as one entered by a person or proposed by an agent.
In most APIs a retried request creating a duplicate record is an annoyance. In a ledger it is a duplicate transaction, and duplicates in accounting are expensive and awkward to unwind because the correction is itself a new entry.
Every mutating endpoint requires an idempotency key and returns the original result on replay. Network timeouts, client retries, and queue redelivery are all normal and none of them should be able to double-post a bill.
We publish a bulk export path deliberately, and it lowers our own switching cost. A vendor whose export is undocumented or partial has a commercial reason for that, and it is worth noticing which of your systems fall into that category.
Ledger, documents, and the full audit trail come out in open formats. If you leave, the audit trail goes with you — an audit record that evaporates at contract end satisfies nobody’s retention policy.
There is no API for authoring policies or granting authority levels. Those are administrative actions performed in a surface that automation cannot reach, because an integration able to widen its own permissions makes the whole model decorative.
Limits
REST and webhooks today. GraphQL is on the roadmap and we would rather say that than list it as available.
Published per tier. Bulk operations go through the export and import paths rather than by looping a transactional endpoint, and we will tell you when you are using the wrong one.
Deliberate. Authoring policy and granting authority happen in an administrative surface automation cannot reach, because a key that can widen its own scope has no scope.
Questions
A technical walkthrough of the API, the permission model, and the export path — without a salesperson on the call.