Versioning
The version is in the path: every endpoint lives under /external/v1.
What we may change within v1
Section titled “What we may change within v1”Additive changes ship within v1. New fields on an existing response, new endpoints, new error codes, new enum members. These land without a version bump and without prior coordination.
So parse leniently: ignore fields you do not recognise, and do not use a strict schema validator that rejects unknown properties. A client that fails on an unexpected key will break on a change that was safe for everyone else.
Specifically, plan for:
- New keys appearing in any object, including inside the full statement’s nested records.
- New error codes. Match on the
codeyou know and fall back to the HTTP status for anything else — the status is always meaningful even when the code is new to you. - New endpoints appearing in the reference.
What we will not change within v1
Section titled “What we will not change within v1”- No field is removed, and no field changes meaning. If a value’s definition needs to change, the new definition arrives as a new field.
- No field changes type, including the integer-cents representation of money.
- No path or
operationIdis renamed, so generated clients stay valid. - No existing error code is renamed or remapped to a different HTTP status.
- No operation is narrowed to fewer kinds of key. An endpoint open to partner and provider keys stays open to both; a provider-only endpoint may be opened to partner keys later, but nothing published is ever closed. See which endpoints each key reaches.
That last set includes some specifics worth naming, because they are committed and can no
longer be withdrawn inside v1: the tax identifiers on the discovery records (tax_id on a
provider, ein on an entity); the sixteen error codes and the statuses they map to; the
key sets of all three totals objects — the income statement’s ten,
net_other_income_cents included, the balance sheet’s three and the cash flow report’s
five; and the presentation hints carried by the full statement (title_tooltip,
percentage_comment) — which you should ignore, but which are published and will keep
arriving.
Breaking changes
Section titled “Breaking changes”Anything not covered above lands as /external/v2. If that happens:
v1is maintained in parallel — a v2 does not switch off v1.- The migration window is agreed with you in advance, not announced as a deadline.
- We will not change the meaning of a
v1field to avoid cutting av2.
Practical advice
Section titled “Practical advice”- Pin nothing but the major version. There is no minor version to track;
/external/v1is the whole contract. - Log unknown fields rather than failing on them. It gives you a cheap signal that something was added, without an outage.
- Store the
accounting_basisand the effective period alongside any figure you keep. Both are returned on every report for exactly this reason: a number without them is not reproducible later. The effective period is thestart_date/end_datepair on a range report, and theas_of_dateon a balance sheet. - Treat this reference as the contract, not any document we have sent you. It is generated from a specification that lives beside the code and is checked against the running routes on every change, so it cannot quietly drift out of date.