Errors

Standard error envelope, HTTP status codes, and the request_id you'll need for support.

Last updated

All Cocobox API errors return a JSON body with the same shape, no matter which endpoint you hit:

{
  "status": 401,
  "error": "unauthorized",
  "message": "Invalid or missing API key.",
  "request_id": "req_01HF2X7Y9KQRABCDE12345"
}
FieldMeaning
statusHTTP status code, mirrored in the body for clients that drop the response status.
errorMachine-readable error slug — stable across versions. Use this for branching logic.
messageHuman-readable explanation. Do not branch on this.
request_idGlobally unique id of the request. Include it when you contact support.

HTTP status codes

StatusWhen it happens
200Success.
201Resource created (API key creation, etc.).
204Success with no body (e.g. DELETE /api-keys/:id).
400Malformed JSON, missing required field, unknown field, bad enum value.
401Missing key, malformed key, key not found, key inactive, expired Auth0 token.
402Subscription credit pool empty for the chosen model.
403Scope violation (model not allowed, tools disabled, role insufficient).
404Unknown resource (model id, key id, MCP session).
409Conflict (e.g. trying to share a connection with someone who already has higher access).
413Request body too large. Currently 1 MiB.
422Validation error (e.g. sql_run received a non-read-only query without write permission).
429Rate-limited. See Retry-After header.
500Cocobox internal error. Safe to retry with exponential backoff.
502Upstream provider (Bedrock) unavailable. Retry.
504Upstream timeout. Retry.

Stable error slugs

Branch on error, not on message or status.

SlugStatusMeaning
unauthorized401Missing or invalid key / token.
key_inactive401Key exists but is_active = false.
scope_violation403Model not in allowed_models or other scope rule failed.
tools_disabled403MCP request with tools_enabled = false.
not_found404Resource doesn’t exist or you can’t see it.
session_expired404MCP session id unknown or expired.
validation_failed400 / 422Request body or arguments didn’t validate.
rate_limited429Per-minute or burst limit reached.
budget_exhausted429Per-key request budget reached.
insufficient_credits402Workspace out of credits for paid models.
connection_unreachable502Cocobox couldn’t dial your database. Check host / port / SSH.
query_too_dangerous422A guard refused the query (DML on a read-only role, schema migration on prod, etc.).
provider_error502Bedrock returned an error. Body includes the upstream code under details.
internal_error500Unexpected. Retry; if it persists, file a ticket with the request_id.

Retries

  • 5xx, 429, 502, 504 are safe to retry.
  • 400, 401, 403, 404, 409, 422 are not — fix the request.
  • Honor Retry-After on 429. Otherwise back off exponentially with jitter.

Sample error responses

Missing key

HTTP/1.1 401 Unauthorized
Content-Type: application/json

{
  "status": 401,
  "error": "unauthorized",
  "message": "Authorization header is required.",
  "request_id": "req_01HF2X7Y9KQRABCDE12345"
}

Out of credits

HTTP/1.1 402 Payment Required
Content-Type: application/json

{
  "status": 402,
  "error": "insufficient_credits",
  "message": "Workspace credit pool is empty for paid models.",
  "request_id": "req_01HF2X7Y9KQRZZZZZ12345",
  "details": {
    "model": "sonnet",
    "required_credits": 1,
    "available_credits": 0
  }
}

Rate-limited

HTTP/1.1 429 Too Many Requests
Retry-After: 8
Content-Type: application/json

{
  "status": 429,
  "error": "rate_limited",
  "message": "Burst limit of 50 req/min exceeded.",
  "request_id": "req_…"
}

Tool guard

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json

{
  "status": 422,
  "error": "query_too_dangerous",
  "message": "Statement is not read-only and the API key lacks write permission.",
  "request_id": "req_…",
  "details": { "statement_kind": "UPDATE" }
}