Authentication
Create an API key, send it with each request, and choose its scopes.
Create a key
API keys belong to an organization, not to a user. Removing someone from your team does not revoke the keys they created, so their integrations keep working.
Create a key in Fabric under Organization → API keys and choose its scopes. You cannot add scopes to a key later. If a key needs more, create a new one to replace it.
Fabric shows the key once, when you create it. It is stored hashed and cannot be recovered, only replaced. Keep it where your team can find it, and out of your repository.
Make a first call
GET /v1/me needs a valid key and no particular scope. It returns the organization the key belongs
to, so call it first to check that the key works.
curl https://fabric.inc/api/v1/me \
-H "Authorization: Bearer fab_sk_..."{
"apiKeyId": "key_...",
"organization": { "id": "org_...", "name": "Acme", "slug": "acme" },
"role": "member",
"scopes": ["catalog:read", "catalog:write"],
"brands": [
{ "id": "brd_...", "name": "Acme Outdoor", "isDefault": true, "mainDomain": "acme.com" }
]
}A 200 means the key, the header and the base URL are correct. Any later failure comes from the
request, not your setup.
The response also lists brands, which is where you get the brandId other endpoints ask
for. A key with no scopes still gets its own details, but its brands list is empty.
The scopes field shows what the key carries. Check it when a call returns
insufficient_scope.
Send the key
Send the key in either header:
curl https://fabric.inc/api/v1/me \
-H "Authorization: Bearer fab_sk_..."curl https://fabric.inc/api/v1/me \
-H "X-Api-Key: fab_sk_..."If both are present, the bearer token wins.
Scopes
Every endpoint requires a scope. A call with a key that lacks it returns
insufficient_scope, which names the missing scope.
| Scope | Grants |
|---|---|
catalog:read | Read products, values, attributes, categories, views and lists |
catalog:write | Create and change them, including archiving and deleting |
enrichment:write | Start enrichment runs, spend credits, write guidelines, review values |
publishing:read | Read destination connections, mappings and their history, publishing runs; preview a mapping and download an export |
publishing:write | Create connections and mappings, start and approve publishing runs |
org:read | Read the organization, its brands, its members and its API keys |
org:write | Change organization settings, manage keys and webhook endpoints |
Scopes do not include each other. catalog:write does not grant catalog:read, so the scopes
listed on a key are everything it can do, and an audit can read them directly. The creation screen
selects both by default.
Fabric ignores any scope on a key that it does not recognise, so a made-up scope grants nothing.
Roles
A key also carries an organization role, and Fabric checks it the same way it checks a person's role. A call needs both the scope and the role.
| Role | Can | Cannot |
|---|---|---|
member | Read everything in the organization, create connections and mappings, run a dry run, download a file export | Approve a publish to a feed or storefront; activate a mapping version; set a global config default |
owner | Everything |
A key holding publishing:write with the member role still cannot approve a publish. The two
checks fail with different codes. A missing scope always returns
insufficient_scope. A missing role returns
forbidden, except on publishing operations such as approving a publish
or activating a mapping version. Those check the role inside the operation and return
refused.
An owner key can approve its own publish
A single call with approve: true approves and publishes to a live storefront. This is
intended: a key with the owner role counts as your organization's approval. It also means the key
can write to production. Use the narrowest scopes and the member role for anything that only
reads or prepares.
Organization boundary
A key can reach only its own organization, and its reach cannot be widened. A second organization
needs a second key. A resource in another organization returns
not_found, not forbidden, so the API never confirms an id you do not
own.
Rotation and revocation
Revoke a key on the same screen and it stops working immediately, with no cache delay. Runs and mapping versions the key created still resolve afterwards. The audit trail records which key acted, and revoking the key does not remove that record.
To rotate a key, create the new key, move your integration to it, then revoke the old one. There is no limit on how long both keys can be active.