API key scopes
Every API key carries one or more scopes — permission flags that control which endpoints the key can reach. Scopes are set at key creation and are immutable after that; to change a key's scopes, revoke it and create a new one.
The nine scopes
| Scope | Grants |
|---|---|
products:read | List and read individual products |
products:write | Reserved (no write endpoints today) |
orders:read | List and read individual orders |
orders:write | Create orders and update order status |
customers:read | List and read individual customers |
customers:write | Create and update customers |
reports:read | Pull sales / customer-spend / inventory reports |
webhooks:read | List and read webhook endpoints |
webhooks:write | Create, update, and delete webhook endpoints |
The dashboard labels them with a friendlier format when you're picking permissions on a new key:
- Products — Read / Products — Write
- Orders — Read / Orders — Write
- Customers — Read / Customers — Write
- Reports — Read
- Webhooks — Read / Webhooks — Write
All nine are checkboxes. products:read is preselected; the rest are
opt-in.
Endpoint → required scope
| Method & path | Scope |
|---|---|
GET /api/v1/products | products:read |
GET /api/v1/products/{id} | products:read |
GET /api/v1/orders | orders:read |
GET /api/v1/orders/{id} | orders:read |
POST /api/v1/orders | orders:write |
PATCH /api/v1/orders/{id} | orders:write |
GET /api/v1/customers | customers:read |
GET /api/v1/customers/{id} | customers:read |
POST /api/v1/customers | customers:write |
PATCH /api/v1/customers/{id} | customers:write |
GET /api/v1/reports/sales | reports:read |
GET /api/v1/reports/customers | reports:read |
GET /api/v1/reports/inventory | reports:read |
GET /api/v1/webhooks | webhooks:read |
GET /api/v1/webhooks/{id} | webhooks:read |
POST /api/v1/webhooks | webhooks:write |
PATCH /api/v1/webhooks/{id} | webhooks:write |
DELETE /api/v1/webhooks/{id} | webhooks:write |
What happens when a scope is missing
A key that's missing a required scope fails with HTTP 403 and a descriptive error:
{
"error": "Insufficient permissions. This key lacks the \"orders:write\" scope."
}
The check runs before any other validation — so you'll see the 403 even if your payload is also malformed. Add the scope (by revoking the key and recreating it with a wider permission set) to proceed.
Heads-up: products:write is reserved
The products:write scope exists in the enum and can be selected when
creating a key, but there are no product write endpoints yet. A key
with only products:write can authenticate but has nothing to do — every
call it tries will either fail a scope check (if it hits a read endpoint)
or 404 (if it hits an endpoint that doesn't exist).
When we ship POST /api/v1/products, PATCH /api/v1/products/{id}, and
DELETE /api/v1/products/{id}, they'll use this scope. For now, treat it
as a placeholder.
Recommended scope combinations
| Use case | Scopes |
|---|---|
| Reporting dashboard (read-only analytics over your data) | products:read, orders:read, customers:read, reports:read |
| ERP order sync (pull orders in one direction) | orders:read |
| CRM sync (push customer records in from your CRM) | customers:read, customers:write |
| Webshop integration (create orders from an external cart) | products:read, customers:read, orders:write |
| Fulfillment tool (mark orders shipped/delivered) | orders:read, orders:write |
| Event receiver setup (register a webhook endpoint from code) | webhooks:read, webhooks:write |
| BI nightly sync (structured report data into a warehouse) | reports:read |
| Full automation (one integration handling everything) | all nine |
When in doubt, go narrower. A dedicated read-only key for your BI tool protects you if the tool's credentials leak — the blast radius is "they can see my data" instead of "they can create bogus orders."
One key per integration
We recommend one API key per distinct integration, not one shared key across everything. Why:
- Revocation is per-key. If one integration's credentials leak, you revoke just that key — the others keep working.
lastUsedAtis per-key. You can tell which integration is idle.- Rate limits are per-key. Splitting workloads across keys raises your effective limit (see the overview for rate limit details).
- Audit clarity. Every action says which key took it.
There's no cap on the number of keys per company.
Next: Pagination.
