Errors
Status codes the delivery API returns and what causes each one.
Delivery errors come back as JSON with the matching HTTP status, as Storyblok’s do.
{ "error": "Unauthorized" }Status codes
| Parameter | Type | Description |
|---|---|---|
200 | OK | Success. A list endpoint returns 200 with an empty array when nothing matches — that is not an error. |
401 | Unauthorized | The token is missing, unrecognised, revoked, or belongs to a deleted branch. Those are the only causes. |
404 | Not Found | No story with that slug or id on this branch — including an unpublished story requested without a preview token. |
500 | Server Error | An unexpected failure. Safe to retry; delivery reads are idempotent. |
200OKSuccess. A list endpoint returns 200 with an empty array when nothing matches — that is not an error.
401UnauthorizedThe token is missing, unrecognised, revoked, or belongs to a deleted branch. Those are the only causes.
404Not FoundNo story with that slug or id on this branch — including an unpublished story requested without a preview token.
500Server ErrorAn unexpected failure. Safe to retry; delivery reads are idempotent.
Debugging a 401
A 401 here is always about the token itself — there is no session, no origin check and no rate limit that produces one. Work through these in order:
- Confirm the token is an Exacta token. Storyblok delivery tokens do not authenticate against Exacta, and the dashboard lists both side by side.
- Confirm it has not been revoked, and that its branch still exists.
- Confirm it is being sent as
?token=. AnAuthorizationheader is not read by the delivery API.
Empty responses that are not errors
/datasources, /datasource_entries and /tags return 200 with an empty collection, because they are not synced yet. A client that calls them on boot keeps working rather than failing on a 404 — but it will receive nothing.