Developers

    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.