Errors
The API uses standard HTTP status codes. Error responses have a JSON body with a
short, stable machine-readable code in detail:
{ "detail": "insufficient_scope:data:write:links" }
Check the HTTP status first, then branch on detail for specifics. The codes
are stable strings you can match on.
Status codes
| Status | Meaning |
|---|---|
200 |
Success |
201 |
Created |
202 |
Accepted — queued for background processing (e.g. a message send or a channel sync) |
400 |
Bad request — a value was invalid or a required field was missing |
401 |
Not authenticated — missing, malformed, or revoked key |
403 |
Authenticated, but not allowed — missing scope or permission |
404 |
Not found — unknown resource, id, or an object not in your entity |
405 |
The operation isn't available for this resource |
409 |
Conflict — a uniqueness rule was violated (e.g. duplicate slug) |
422 |
The request was understood but could not be processed |
429 |
Rate limit exceeded (see Rate limits) |
Common error codes
Authentication (401)
missing_bearer_token— noAuthorization: Bearer …header.invalid_token— the token isn't a Zingasuite key.invalid_or_revoked_key— the key is unknown, revoked, or expired.
Authorization (403)
insufficient_scope:<scope>— the key lacks a required scope, e.g.
insufficient_scope:data:write:links.permission_denied:<op>:<model>— the key's owner can't perform this
operation on this object type, e.g.permission_denied:create:links:shortlinks.app_not_in_key_scope:links— the key is confined to other apps.app_not_subscribed:links— the workspace has no Zingalinks plan (its own or a
paid ZingaConnect plan, which bundles it).plan_upgrade_required:links:starter— the operation needs Starter or above
(custom domains).membership_revoked— the key owner is no longer an active member of the
entity.
Requests (400 / 404 / 405 / 409 / 422)
link_not_found/domain_not_found— no such row in your workspace (a404,
also returned for a malformed id).slug_taken— that slug is already in use on that domain (409).invalid_slug— the slug had illegal characters, or is one of the reserved
words the edge needs.invalid_status—statusmust beactive,archivedordisabled.invalid_host— the domain isn't a valid hostname.host_taken— that host is already claimed (409).
Because codes are stable, you can build reliable handling — for example, treat
any insufficient_scope:* as "widen this key's scopes", 409 slug_taken as
"already exists, read it instead of creating it", and any
plan_upgrade_required:* as a prompt to upgrade rather than a retryable error.