API endpoints
One page per resource, carrying both directions: what a write accepts and what a read answers. This page carries only what every resource shares.
The resources
A path below is relative to /api/v1; … stands for
/organisations/{organisation}, because data with a figure or a month in it belongs to one
company. A resource with no write path is read only.
| Resource | Writing it | Reading it | What it carries |
|---|---|---|---|
| Organisations | - | /organisations | The companies the credential may read |
| Account types | - | /account-types | The system account types an account carries |
| Sections | - | /sections | The section tree a statement is built from |
| Tags | - | /tags | The accounting-standard tags an account can carry |
| Currencies | - | /currencies | The group's currencies and its rate settings |
| KPIs | - | /kpis, …/kpi-values | The KPI names, and one KPI's figures |
| Periods and years | - | …/periods, …/years | The months and years a company can report |
| Accounts | /accounts | /accounts | The accounts, with the type each one reports under |
| Trial balance | /trial-balances | /trial-balances | One month of debit and credit movement per account |
| Statements | - | …/statements/{statement} | The profit and loss, the balance sheet and the cash flow |
| Invoices | /invoices | /invoices | Sales documents with their lines |
| Bills | /bills | /bills | Purchase documents with their lines |
| Journal lines | /transactions | /transactions | Ledger lines, journal by journal |
| Operational data | /operation-data | /operation-data, …/{dataset} | Figures for the dashboard and report blocks |
| Exchange rates | - | …/exchange-rates | The rate between two currencies for a month |
| Consolidation | - | …/consolidation/{dataset} | CTA, NCI, journal vouchers, adjustments and intercompany |
| Intercompany transactions | - | …/intercompany-transactions | The elimination postings between the group's companies |
| Request history | /requests | /requests | What was sent, and what it wrote |
A write also has /validate on the end of its path, which runs every check and writes nothing.
Scopes
A credential is given scopes, one per resource and action, and a token carries one ability per scope:
scope:<resource>.<action>. A request whose credential holds no scope for it is
refused with 403, before anything is read or written. A credential given only read scopes
cannot write, and one given only write scopes cannot read.
| Resource | Write scope | Read scope |
|---|---|---|
| Organisations, account types, sections, tags, currencies, KPIs, periods and years | - | reference.read |
| Accounts | accounts.write | accounts.read |
| Trial balance | trial_balance.write | trial_balance.read |
| Statements | - | statements.read |
| KPIs | - | kpis.read |
| Invoices | invoices.write | invoices.read |
| Bills | bills.write | bills.read |
| Journal lines | transactions.write | transactions.read |
| Operational data | operation_data.write | operation_data.read |
| Exchange rates | - | exchange_rates.read |
| Consolidation | - | consolidation.read |
| Intercompany transactions | - | intercompany.read |
Six resources are pairs - accounts, trial balance, invoices, bills, journal lines and operational data - and
every other resource is read only. Every vocabulary shares one scope, reference.read, because a
caller needs all of them before it can ask for a figure.
Writing: what every write shares
The URL names the resource. No wrapper noun, no verb. The company is always in the path, because data belongs to a company.
The body is an envelope: the declarations that apply to the whole payload, and the records themselves.
{
"declarations": { "…": "…" },
"records": [ { "…": "…" } ]
}
| Declaration | What it means |
|---|---|
source_reference | Your own id for the feed, 1–64 characters, required. Rows are held per source, so two feeds writing the same month do not overwrite each other. |
mode | What happens to stored rows the payload does not carry. The default differs by resource — each resource's page states its own. |
webhook_url | Called once when the request finishes or fails. Five second timeout; a slow endpoint of yours never delays the write. |
Declarations about amounts — period, scenario, value_basis,
rate_direction, base_currency — apply to every resource except accounts, which
carries no month and no amounts.
The fields a resource accepts, and how it is read
GET /api/v1/schemas/accounts
GET /api/v1/schemas/consolidation
No token needed, so an integration can be built before a credential exists. For a resource a feed writes into,
the answer is a JSON Schema of that resource's declarations and records, plus
identity (which fields make two records the same record), record_limit (your
group's own figure when the call carries a live token, the default otherwise), limits, and
every error_codes entry.
The same answer states how the resource is read, under read: the scope it needs, the parameters
it takes with their type and allowed values, and the fields it answers. A resource that is only read -
statements, kpi-values, exchange-rates, consolidation,
and the vocabularies - answers that contract alone. A parameter the contract does not state is refused by
name, so what it states is exactly what the endpoint accepts.
A resource that does not exist answers 404 with the resources that do.
What a write answers
202 Accepted, with Location pointing at the request's own URL:
{
"id": 87,
"organisation_id": 141,
"kind": "trial_balance",
"source_reference": "netsuite-monthly",
"period": "2026-09",
"status": "written",
"records_received": 412,
"counts": { "created": 412, "updated": 0, "unchanged": 0, "rejected": 0 },
"suppressed": 0,
"warnings": [],
"failure": null,
"result": {},
"recalculation": "pending",
"written_at": "2026-10-23T06:14:02+00:00",
"links": {
"self": "…/organisations/149/requests/87",
"results": "…/organisations/149/requests/87/results"
}
}
status is written or failed. unchanged means the record
was identical to what is already stored and nothing was written for it. recalculation is
null for resources that do not recalculate the reports, and pending turning into
done or failed at the request's own URL for those that do.
Idempotency-Key header and a repeated request answers
with the first one and writes nothing. Without it, a retried send is a second write — correct for a month
sent whole, wrong for a payload that only adds.Reading: what every read shares
Two levels. The vocabularies are shared by the whole group - the organisations, the account types, the sections, the tags, the currencies, the KPI names, and each company's periods and years. They are not under a company's path, because every company in that group answers them the same way. Everything that carries a figure belongs to one company, and its path names that company.
A company that is not yours answers 404. The API never confirms that another
group's company exists, so not_found is the answer rather than 403.
Lists page the same way. Every list takes page and per_page (50
unless stated, at most 200) and answers data beside page, per_page,
total and has_more. The record limit that applies to a write does not apply to a
read; the requests-per-minute limit does.
A month is Mon-YYYY - Jul-2026 - in a read's parameters and in
its answer, and a date is YYYY-MM-DD. Operational data is the one exception: its rows are
stored and read as YYYY-MM, the same way a write states such a row's month.
A figure states what it is: its amount at stored precision, the currency it is presented
in, its basis - movement, balance, debit or credit -
its scenario and the period it belongs to. A caller never has to guess which basis it received.
A statement answers as the report draws it: the sections in order, each with its label and
its amount, and the lines behind a section when ?detail=1 is asked for.
A read answers the same number as the screen. That is what the API is measured against: the same account, the same month and the same scenario answer one figure in a read and in a cell report.
A read is not a report. A report is a worksheet - cells, formulas, layouts, drills - and a caller that can read the accounts, the months, the statements and the figures can build its own view. Exporting to Excel or PDF, report images and report schedules are not part of the API.
The same reads are offered to an AI client as tools. Each tool is one of these reads for one company, with the same answers and the same refusals - see AI connectors (MCP).
Not available
- A report, its definition or its drills. A caller reads the data behind a report, not the report.
- Paging beyond the last fifty requests. Older requests are reachable by id.
- Deleting or reversing. A correction is a new request for the same month.