Skip to content

Error codes

The REST API and MCP server return errors with the same shape:

{
"error": {
"code": "workspace_slug_taken",
"message": "The slug 'acme' is already in use. Try 'acme-corp' or pick another.",
"request_id": "req_xyz123"
}
}
  • code: machine-readable, stable. Changing it is a breaking change.
  • message: human-readable, can change.
  • request_id: paste it if you open a ticket — we find the log instantly.
HTTPCodeWhat happens
400invalid_requestMalformed parameter. Check message for detail.
400validation_failedField validation failure (slug too short, invalid hex color, etc).
401unauthorizedNo token or expired token.
401invalid_tokenToken doesn’t sign with the expected key. Maybe you rotated the machine key.
403forbidden_by_scopeYour token lacks scope for this action.
403requires_confirmationDestructive op, missing confirmed: true.
404not_foundResource doesn’t exist or you can’t see it.
409workspace_slug_takenSlug already in use.
409state_conflictResource is in a state that doesn’t allow this op (e.g. delete while provisioning).
422enterprise_onlyAction only available on Enterprise plan.
422pro_requiredAction only on Pro+.
429rate_limitedToo many requests. Check Retry-After header.
HTTPCodeWhat happens
500internal_errorBug on our side. Report with request_id.
502upstream_errorSomething upstream failed. Retry with backoff.
503service_unavailableMaintenance or partial degradation. Retry.
  • workspace_slug_invalid — disallowed chars (only a-z 0-9 -).
  • workspace_slug_too_short — minimum 3 chars.
  • workspace_slug_reserved — reserved word (auth, api, app, admin, etc.).
  • workspace_provisioning_failed — initial provisioning blew up. Check details.
  • redirect_uri_invalid — not a valid URL or uses a forbidden scheme.
  • redirect_uri_localhost_only_devhttp://localhost dev-only (Pro+ allows override).
  • client_secret_revoked — secret is no longer valid. You rotated more than 24h ago.
  • idp_oauth_failed — Google/GitHub/MS rejected the credentials. Verify client_id/secret.
  • idp_metadata_invalid — SAML XML malformed or unsigned.
  • idp_already_configured — provider already in this workspace.
  • payment_method_required — you moved to Pro with no valid card.
  • subscription_past_due — you need to resolve payment to continue.
  • signups_blocked — you hit your spending cap. Raise it or wait for next period.
  • webhook_url_invalid — URL is not https or doesn’t respond to HEAD.
  • webhook_secret_required — endpoint registered but missing secret (rare, our bug).

These come from the instance directly, not the control plane. Standard OAuth 2 shape:

{ "error": "invalid_grant", "error_description": "..." }

Common:

  • invalid_grant — code expired, redirect_uri mismatch, code reused.
  • invalid_clientclient_id/secret wrong.
  • unsupported_grant_type — you passed a grant type we didn’t enable for your app.
  • access_denied — user aborted consent.

Report it on GitHub with request_id. The canonical list is the backend codes; this doc lags occasionally.