API versions
Dated API versions, the pin your organisation gets on its first request, the FurniOps-Version header, and how webhook endpoints choose the shape of their events.
The FurniOps API is versioned by date. A breaking change ships only in a new dated version; the versions before it keep their shape, because FurniOps rewrites responses and webhook events back to the version you asked for. You upgrade when you choose to, one request or one endpoint at a time.
Served versions
| FurniOps-Version | Status |
|---|---|
| 2026-10-04 | latest |
| 2026-10-01 | supported |
The latest version is 2026-10-04. Every change so far has been additive, so the two
versions have the same shape today; the changelog lists each version's breaking
changes as they come.
Additive and breaking changes
Additive changes reach every version as soon as they are released, so write your client to tolerate them:
- new endpoints, and new optional request parameters and fields;
- new fields in responses and event payloads;
- new event types (an endpoint subscribed to
*receives them); - new values in an enum, such as a new
statusor a new errorcode.
Ignore fields you do not know, and treat an enum value you do not know as "other". Anything else, such as removing or renaming a field, changing its type or meaning, or making an optional parameter required, is breaking, and ships only in a new version.
Choosing a version
Your organisation's pin
The first authenticated request your organisation makes without a FurniOps-Version header
pins it to the version served at that moment. From then on, every request without the header is
served the pinned version, so an integration that never sends the header never changes shape on
its own.
Per request: FurniOps-Version
Send the header to ask for a version explicitly, whatever the pin:
curl https://api.furniops.com/v1/products \
-H "Authorization: Bearer $FURNIOPS_API_KEY" \
-H "FurniOps-Version: 2026-10-04"- The response names the version it was served in its own
FurniOps-Versionheader. - A version FurniOps does not serve answers
400with the codeunsupported_version. - The SDK sends no header unless you set
apiVersion, in the client options (every call) or a call's options (that call only). Its types follow the latest version, so settingapiVersionto the latest one keeps the types and the shapes in step.
Test a new version by sending its header from a branch of your code, then roll it out request by request. Sending the header everywhere is the most predictable setup.
Webhook endpoints have a version too
Events delivered by webhook are shaped for the endpoint's api_version, named in each
delivery's FurniOps-Version header. It defaults to the version the creating request was served
(its header, otherwise your pin), and you change it with
PATCH /v1/webhook-endpoints/{id}:
curl -X PATCH https://api.furniops.com/v1/webhook-endpoints/$ENDPOINT_ID \
-H "Authorization: Bearer $FURNIOPS_API_KEY" \
-H "If-Match: $ETAG" \
-H "Content-Type: application/json" \
-d '{"api_version": "2026-10-04"}'Each attempt, retries included, is shaped for the version the endpoint is on at the moment it is
sent, so a delivery retried after you switch arrives in the new shape.
To upgrade a receiver without downtime, deploy a handler that accepts both shapes (switch on the FurniOps-Version header), then change the endpoint.
The change feed and the stream are shaped by the request's version, like any other response.
The change feed
The ordered, replayable log of every change you can see, read with a cursor, long-polled with wait, or streamed live over server-sent events.
Catalogues and licences
Your own catalogue, the network catalogue, and how a licence narrows what you can see of it by source and by field group, the same way on every path.