Keys and access
The CMS uses three kinds of credentials. Keep them apart: a delivery key never works on the Management API, and an API key never works on the delivery API.
| Credential | Header | Where it lives | What it can do |
|---|---|---|---|
| Avvyr API key | x-api-key | Scripts, CI, your backend | Everything under /v1/cms: sites, types, entries, publishing |
Public delivery key cms_pub_… | x-cms-key | Anywhere, the browser included | Read published content of one site |
Preview key cms_prv_… | x-cms-key | Your site's server only | Read published content and drafts of one site |
Management API
https://api.avvyr.com/v1/cms takes a normal Avvyr API key (or a signed-in user in the app).
- The tenant needs the CMS add-on. Without it every call returns
403 ADDON_NOT_AVAILABLE. - A key restricted to scopes needs
product:readto read andproduct:writeto change anything. - An unrestricted key needs the same administrator rights as a person editing the CMS in the app.
GET /v1/cms/sites lists the tenant's sites and their ids.
Delivery keys
Each site gets one public key and one preview key when it is created. Send the key in the x-cms-key header. ?key= works too, for places where you cannot set a header.
curl https://api.avvyr.com/v1/content/{siteId}/version -H "x-cms-key: cms_pub_…"
- A key belongs to one site. A key for another site returns
401 CMS_KEY_INVALID. - Delivery responses send
Access-Control-Allow-Origin: *and never read cookies, so the public key can be used straight from the browser. Published content is public on your site anyway. - The preview key reads drafts. Keep it in server-only environment variables.
- The plain-text keys are shown once, in the response to
POST /v1/cms/sites. Avvyr only stores a hash; the app shows each key's prefix.
Rotating a key
curl -X POST https://api.avvyr.com/v1/cms/sites/{siteId}/keys/public/rotate -H "x-api-key: $AVVYR_API_KEY"
# { "key": "cms_pub_…" }
Use preview instead of public for the preview key. The old key stops working within a minute, because validated keys are cached for 60 seconds.
Preview tokens
Reading a draft needs two things: the preview key, which proves the request comes from your site's server, and a preview token, which proves an editor opened the preview recently.
The editor creates the token when someone clicks preview, and opens your site's preview URL with it:
https://www.example.com/?entryId=…&path=%2Fom-oss&locale=sv&token=1767225600000.Q2x…
Your server passes the token on in x-cms-preview-token (or ?token=) together with the preview key. A token is valid for one hour and is signed per site. You can also create a link yourself with GET /v1/cms/sites/{siteId}/preview-link?entryId=&locale=, which returns { url, token, expiresAt }.
Errors
| Status | errorCode | Meaning |
|---|---|---|
| 401 | CMS_KEY_REQUIRED | No x-cms-key |
| 401 | CMS_KEY_INVALID | Unknown key, or a key for another site |
| 403 | CMS_PREVIEW_KEY_REQUIRED | A draft route called with the public key |
| 401 | CMS_PREVIEW_TOKEN_INVALID | Missing or expired preview token |
| 403 | ADDON_NOT_AVAILABLE | The tenant does not have the CMS add-on (Management API) |