Skip to content

API versioning & changelog policy

The partner API versions by date, Stripe-style: 2026-09-22, the current version, is the baseline the whole app platform launched on.

Three ways a request’s version is decided, in priority order:

  1. An explicit OneBooks-Version request header.
  2. Your app’s pinned version, set in the console (defaults to unset).
  3. The current version, if neither of the above is set.

Every response echoes the resolved version back in an OneBooks-Version header, so you can always confirm what you got — including from code that didn’t set the header itself.

Terminal window
curl -s https://api.getonebooks.com/invoices \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "OneBooks-Version: 2026-09-22"

A version that doesn’t exist, or one that’s past its sunset date, is rejected:

{
"statusCode": 400,
"code": "UNSUPPORTED_API_VERSION",
"message": "This OneBooks-Version is not supported. See the API versioning guide for the supported versions."
}

New apps should pin explicitly once you’ve integrated against a version, rather than floating on “whatever is current” — that way a future breaking release doesn’t change your app’s behavior until you decide to move. Pin on your app’s Overview tab in the console, under API version (org admins only). Pinning is per-app, not per-request; the header is for cases like testing an upcoming version ahead of repinning.

A pin isn’t permanent: Follow the current version on the same panel removes it, and your app goes back to following the current version, as a new app does. Scripting it, that’s PUT /developer/apps/:id/api-version with { "apiVersion": null } — the key is required, so an empty body is a 400, not an unpin — which answers:

{ "apiVersion": "2026-09-22", "pinned": false, "current": "2026-09-22" }

Send a supported version instead of null to pin one. API requests pick up a pin change within a minute: each app’s pin is cached for up to 60 seconds. The pin also sets the apiVersion stamped on your webhook deliveries.

Hosted functions follow the same order. ctx.api sends OneBooks-Version only when your app is pinned, with the pinned version; an unpinned app’s function calls carry no version header and resolve like any other request of your app. A OneBooks-Version your code passes in init.headers overrides it for that call. Testing locally, runLocally() sends one only when you pass its apiVersion option.

Breaking (needs a new version)Additive (ships without one)
Removing an operation, parameter or response propertyA new endpoint
Making a previously-optional request field requiredA new optional request/response field
Changing a field’s type or meaningA new event type
Narrowing an enum’s accepted valuesA new enum value appended to an existing one you’re not exhaustively switching on

Every partner-surface change is checked against a frozen snapshot of the previous version before it ships, specifically to catch accidental breaks — so a version bump is a deliberate, documented decision, not something that happens quietly inside a patch release.

A version stays fully supported for 12 months after its successor ships. After that, requests pinned to it are rejected with UNSUPPORTED_API_VERSION — migrate before the sunset date shown for your pinned version.

VersionReleasedStatusSunsets
2026-09-222026-09-22Current—

Changelog tracks what shipped in each version, in prose.