FurniOpsDocs
API reference

API reference

Every FurniOps API operation, generated from the public OpenAPI document, with the conventions they share.

The FurniOps API is a JSON API over HTTPS. Each operation has its own page in this section, generated from the same OpenAPI document the SDK and the server are built from, so its parameters, bodies, responses and error codes are exactly what the server enforces.

Base URL

https://api.furniops.com

Every path starts with /v1. HTTPS only.

Authentication

Send an API key, or an OAuth access token, as a bearer token on every request:

curl https://api.furniops.com/v1/products \
  -H "Authorization: Bearer $FURNIOPS_API_KEY"

A test key (fo_test_…, fo_rk_test_…) reaches your sandbox, a live key your live data; an access token is live unless the request sends FurniOps-Mode: test. Each operation lists the scopes it needs; see the scope table and Authentication.

Conventions

TopicRule
BodiesJSON, sent with Content-Type: application/json. Unknown fields in a request body are refused.
IDsPrefixed and opaque: prod_…, var_…, ofr_…, src_…, run_…, evt_…. A malformed ID or one with the wrong prefix answers 404.
MoneyAn integer in minor units with a lowercase ISO 4217 currency: 94900 and usd is $949.00.
TimesRFC 3339 in UTC: 2026-10-04T10:00:00Z.
Absent fieldsLeft out, not sent as null, unless the schema says null has a meaning.
VersionsFurniOps-Version (the latest is 2026-10-04) pins the response shape; see API versions.
RetriesPOST takes an Idempotency-Key; PATCH of sources and webhook endpoints takes If-Match.
ListsCursor pagination: limit, starting_after, ending_before.
ErrorsProblem details with a stable code.
LimitsRate budgets by class, stated in RateLimit headers.

Headers you send

HeaderWhen
Authorization: Bearer <key>Always.
FurniOps-ModeOptional: live or test. Lets an OAuth access token act in test mode; a key's mode is its own.
FurniOps-VersionOptional: the API version to answer in.
Idempotency-KeyOn every POST but POST /v1/sources/{id}/test.
If-MatchOn PATCH /v1/sources/{id} and PATCH /v1/webhook-endpoints/{id} (required).
If-None-MatchOptional on a GET: 304 when unchanged.
Content-Type: application/jsonWith a body.

Headers you get

HeaderOn
Request-IdEvery response. Quote it to support.
FurniOps-VersionEvery successful response: the version the body is shaped for.
ETagEvery successful JSON GET.
RateLimit, RateLimit-PolicyEvery budgeted response.
Retry-After429 rate_limited, 429 quota_exceeded, 503 overloaded and 409 idempotency_request_in_progress.
Location202 from POST /v1/exports: the new export's URL.
Idempotent-Replayed: trueA replayed POST.

Operations

The sidebar groups operations by resource. Each page shows the request, every response with its schema, the error codes it can answer, a curl example and the matching SDK call. The interactive "try it" console is turned off: send real requests from your own terminal, with your own key.

The OpenAPI document itself is the source of truth for code generators: it ships in @furniops/contracts as openapi/public.json.

On this page