Errors & rate limits

Error format#

Every error response uses the same JSON shape and an appropriate HTTP status code:

JSON
{
  "statusCode": 403,
  "code": "FORBIDDEN",
  "message": "Missing required scope: govern:checkpoints:write"
}
FieldDescription
statusCodeThe HTTP status code, repeated in the body.
codeA stable, machine-readable error code.
messageA human-readable description, safe to log.

Status codes

StatusWhen it happens
400 Bad RequestA required field is missing or invalid — e.g. action omitted on a checkpoint, or tool_name omitted on a tool_call scan.
401 UnauthorizedThe API key is missing, malformed, revoked, or used from a disallowed IP.
403 ForbiddenThe key is valid but lacks the required scope.
404 Not FoundThe referenced resource (e.g. a checkpoint ID) does not exist in this workspace.
429 Too Many RequestsThe rate limit was exceeded. Honor the Retry-After header.
500An unexpected server error. The message is generic; retry with backoff.

Rate limits#

The API enforces a sliding-window, per-key limit.

  • Default: 600 requests per minute per API key.
  • Response when exceeded: 429 Too Many Requests with a Retry-After header (seconds to wait).
text
HTTP/1.1 429 Too Many Requests
Retry-After: 12

Polling etiquette

When polling a checkpoint with GET /v1/checkpoints/{id}, keep a minimum of 1 second between polls of the same checkpoint — tighter polling is rejected. Prefer the long-poll endpoint GET /v1/checkpoints/{id}/wait, which holds the connection open and returns as soon as the state changes, so you make far fewer requests.

Idempotency#

Write endpoints (POST /v1/checkpoints, POST /v1/secure/scan) accept an optional Idempotency-Key header so retries are safe:

Idempotency-Key: 4f1e9c2a-7b3d-4a1f-9c8e-2d6b0a5f1e33

Reusing the same key with a different request body is rejected — a key is bound to the payload it was first seen with. Use a fresh UUID per logical operation, and reuse it only when retrying that exact operation.

Maetra AI DocsGovern agents before they act.