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 — no Authorization: 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 (a 404,
    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 — status must be active, archived or disabled.
  • 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.

Was this helpful?