Skip to content

Errors & limits ​

Error format ​

Every error has the same shape, and code is stable across releases. Branch on code, not on the message.

json
{
  "error": {
    "code": "APPROVAL_REQUIRED",
    "message": "This action needs your approval.",
    "requestId": "req-8f2c…",
    "details": { "approvalId": "…" }
  }
}

message is safe to show to people. Quote requestId when you contact support.

CodeHTTPMeaning
UNAUTHENTICATED401No valid session. Sign in again.
FORBIDDEN403Signed in, but not allowed (role, workspace, or missing client header).
POLICY_DENIED403A workspace policy blocks this tool or connector.
NOT_FOUND404Doesn't exist, or isn't yours.
VALIDATION_FAILED400The request is invalid. details.issues lists each field.
CONFLICT409Clashes with existing data (e.g. a slug already taken).
INVALID_STATE409Not possible right now (e.g. cancelling a finished run).
CONNECTION_REQUIRED409Connect the account first. details.toolkitSlug says which.
APPROVAL_REQUIRED409Needs approval. details.approvalId identifies it.
IDEMPOTENCY_CONFLICT409An idempotency key was reused with different input.
RATE_LIMITED429Too many requests. Back off and retry.
UPSTREAM_FAILED502The model or integration provider returned an error.
INTEGRATION_UNAVAILABLE503The integration provider isn't available.
UPSTREAM_TIMEOUT504The provider timed out.
INTERNAL_ERROR500Something went wrong on our side.

Validation errors list every problem:

json
{ "error": { "code": "VALIDATION_FAILED", "message": "Request validation failed.",
  "details": { "issues": [{ "path": "name", "message": "Too small: expected string to have >=1 characters" }] } } }

Limits ​

LimitValue
Sign-in and register (/auth/*)20 requests per minute
Everything else600 requests per minute
Request body15 MB (room for a 10 MB attachment in base64)
Message length20,000 characters
Attachments5 per message, 10 MB each
Run streamingOne stream stays open up to 30 minutes; reconnect to continue
Model and tool usageThe workspace plan's monthly token budget; runs stop with RATE_LIMITED when it's used up

Pagination ​

Lists that can grow take limit (1–100, default 50) and cursor, and return:

json
{ "items": [ … ], "nextCursor": "50" }

Pass nextCursor back as cursor until it is null.

Idempotency ​

Tool execution (POST /integrations/tools/{toolSlug}/execute) accepts an idempotencyKey (8–200 characters). Repeating a request with the same key and input returns "status": "duplicate" instead of running the tool twice; the same key with different input fails with IDEMPOTENCY_CONFLICT.

Lex by Gavalytics AI