The close, as an API
Reconciliations, accruals, entries, flux and the trial balance, per call, across every set of books you keep.
{ "period": "2026-09", "entities": [ "ent_0141", "ent_0142", "ent_0143" ], "flux_threshold": { "pct": 10, "amount": "5000.00" }, "approvers": ["role:senior_accountant"], "stream": true}
- 09:14:21trial_balance.tiedent_0141AR and AP tie; cash has 3 open items
- 09:14:18entry.postedent_0142je_0907 · approved by M. Okafor
- 09:14:12flux.flaggedent_0143Payroll +18.4% vs August · 2 entries cited
- 09:14:09entry.awaiting_approvalent_0142je_0912 · Utilities accrual · 1,240.00
- 09:14:06accrual.proposedent_0142Utilities · three-month average · 1,240.00
- 09:14:04reconciliation.openent_01413 bank lines unmatched · 418.20
- 09:14:02reconciliation.matchedent_0141Operating account · 212 of 215 lines
- 09:14:01close.startedent_0143Period 2026-09 · 5 workers queued
- 09:14:01close.startedent_0142Period 2026-09 · 5 workers queued
- 09:14:00close.startedent_0141Period 2026-09 · 5 workers queued
Built for the people who keep other people's books
- Accounting firms
- Fund administrators
- Bookkeeping platforms
- Vertical SaaS
The close is not reserved. The opinion is. Workers reconcile and tie out; opinions and signatures stay with the people the law names.
One call, every entity
Run the close for every entity in one request.
Matched line by line
Bank lines meet ledger lines; what doesn't match comes back open.
Variances, explained
Flux past your threshold comes back with the entries that moved it.
Six workers, one key
One call per job, each returning typed JSON you can check.
POST/v1/workers/close
Close orchestrator
Runs the other five in order, per entity, and reports what's still open.
returns close_summary · event[]
POST/v1/workers/reconciliations
Reconciliations
Bank and card feeds against the ledger. Open items come back named.
returns match[] · open_item[]
POST/v1/workers/accruals
Accruals
Costs incurred but not yet billed, with the basis attached.
returns entry[]
POST/v1/workers/entries
Journal entries
Recurring and adjusting entries, drafted and held for approval.
returns entry[]
POST/v1/workers/flux
Flux
Movement past your threshold, with the entries behind it.
returns variance[] · cited_entries[]
POST/v1/workers/trial-balance
Trial balance
Ties subledgers and bank to the general ledger and names any break.
returns tie_out[] · break[]
Nothing posts unapproved
Approval takes a person's own token, so the server key can never post an entry.
{ "object": "entry", "id": "je_0912", "entity": "ent_0142", "period": "2026-09", "status": "proposed", "proposed_by": "accruals", "memo": "Utilities accrual", "lines": [ {"account":"6100","debit":"1240.00"}, {"account":"2100","credit":"1240.00"} ], "basis": "Three-month average", "approval": { "required": true, "approver": "role:senior_accountant" }}
{ "object": "entry", "id": "je_0912", "status": "posted", "approved_by": { "id": "usr_7f2a", "name": "M. Okafor" }, "posted_at": "2026-10-02T14:12:09Z"}
{ "object": "entry", "id": "je_0912", "status": "returned", "reason": "Book the invoice: 1312.40"}
What stays reserved
Ask for a reserved act and the call returns BLOCKED, naming who can do it.
One key, every door
Request it once; every call prices from one rate card.
No record, no charge
A refusal, a retry or an unavailable upstream meters nothing.
Start with one entity
Tell us whose books you keep and which workers you need first.
Received.
We’ll reply by email.