Policy
VERSIONING.
Fifty-two percent of developers were hit by an unannounced breaking change last year. This page is what we do instead.
The promise
Eight rules we hold ourselves to
One version in the path
Every endpoint lives under /api/v1. There is no header version and no implicit default that drifts underneath you.
Additive only inside v1
Within v1 we add endpoints, add optional parameters and add fields. We never remove a field, rename a field, narrow a type, tighten a validation rule or change the meaning of an existing value.
New fields can appear at any time
Parse defensively: ignore fields you do not know. Adding a field is not a breaking change, and your client must tolerate it.
Twelve months of runway
If a version is ever retired, it keeps answering for at least twelve months from the announcement, with a migration guide published on day one.
Ninety days of notice, minimum
No endpoint, field or behaviour is withdrawn with less than ninety days notice. Affected responses carry Deprecation and Sunset headers for the whole window.
Unversioned changes are on the record
Additive changes ship without a version bump, and every one of them is written into the changelog and marked as unversioned. There is no quiet change.
The spec is the contract
The OpenAPI document the server publishes is the contract. If the document and this page ever disagree, the document wins and the page is a bug.
Old SDKs keep working
The API stays compatible with released SDK versions. Upgrading an SDK may surface new fields; it will never be required to keep an existing integration alive.
Definitions
What counts as breaking
Breaking: removing or renaming a field or endpoint, adding a required parameter, changing a type, adding a value to an enum a client must exhaustively handle, changing default sorting or pagination behaviour, or making an existing validation rule stricter.
Not breaking: adding an endpoint, adding an optional parameter, adding a response field, adding a new error code for a condition that previously returned a generic error, or loosening a validation rule.
How to pin
Dated versions inside v1
Pin a key, upgrade when you choose
The path stays /api/v1. Behaviour that would break a working integration ships as a new dated version instead. Pin a key to a date under API keys and it stays on that behaviour until you move it.
Override one call
Send QN-Version: 2026-12-01 to answer a single call under another version, without touching the key. Every response reports QN-Version, where the version came from and which version is stable today.
Dry-run the next version
Add ?version=next to any call to see exactly what the upcoming version returns. It changes nothing and it is the cheapest way to find out whether an upgrade costs you work.
Read the differences
GET /v1/versions lists every dated version we serve, what changed in each one, which version your key is pinned to and which one answered that call.
2026-09-01 (stable today)
- First dated version of the v1 surface.
- Cursor paging and offset paging both work; offset paging carries Deprecation and Sunset headers.
- List responses report total and offset in meta when offset paging is used.
2026-12-01 (preview)
- Offset paging is rejected: send the next_cursor value as ?cursor= instead.
- List meta no longer reports offset or total; it reports next_cursor and has_more only.
- Responses carry the resolved version in meta.version.
Status today
Where v1 stands
v1 is in private beta. One version is live, nothing is deprecated, and no sunset has been announced. Offset pagination is the single planned deprecation: cursors are already available and offset will carry Deprecation headers before v1 leaves beta.
Every change is listed on the changelog.