Assistant CoreAssistant Core
Developer API

Errors and limits

Handle API errors, idempotency, rate limits, and WebSocket close codes.

HTTP and SSE errors

Every /v1 error uses the following stable shape, including authentication and validation failures.

{
  "code": "RATE_LIMITED",
  "message": "Request rate limit exceeded",
  "details": null,
  "request_id": "req_01K...",
  "retryable": true
}

In SSE, the same data is sent in the terminal error event. Always retain request_id for investigation.

CodeTypical HTTPRetry?Action
INVALID_API_KEY401NoCheck the key, its checksum, and the Authorization header. Deleted keys also return this code.
API_KEY_EXPIRED401NoThe key expired or its rotation grace period ended; use the replacement key.
API_KEY_REVOKED401NoUse an active credential.
INSUFFICIENT_SCOPE403NoCreate a key with the required scope.
IP_NOT_ALLOWED403NoCall from an IP in the key's allowlist.
ASSISTANT_INACTIVE403NoReactivate the assistant.
FEATURE_NOT_AVAILABLE403NoCheck the owner's plan, feature access, and requested model.
FILE_UPLOAD_DISABLED403NoEnable file uploads for the assistant.
VOICE_DISABLED403NoEnable voice for the assistant.
ACTOR_CONFLICT409NoUse a different external_user_id.
INSUFFICIENT_CREDITS429Not immediatelyThe owner must add credits.
RATE_LIMITED429YesWait for Retry-After.
IDEMPOTENCY_CONFLICT409NoUse a new key or the original body.
REQUEST_IN_PROGRESS409YesWait, then retry the same key and body.
CONVERSATION_NOT_FOUND404NoCheck assistant, external user, and UUID.
MESSAGE_NOT_FOUND404NoCheck the message ID and external user.
FILE_NOT_FOUND404NoUpload the file for the same external user; details.file_id names it.
RESPONSE_NOT_FOUND404NoCheck the ID and external user; retry after the response finishes.
INVALID_CURSOR400NoPass last_id from the same conversation as after.
VALIDATION_ERROR422NoFix the request; details.errors lists the fields.
UNSUPPORTED_FILE_TYPE415NoUpload a supported type whose contents match its extension.
FILE_TOO_LARGE413NoUpload a file of at most 25 MiB.
INVALID_AUDIO_FORMAT400NoUse a supported codec, rate, and channel count.
CONTEXT_TOO_LARGE400NoStart a new conversation.
UPSTREAM_UNAVAILABLE503YesBack off and retry with a limit.
RATE_LIMIT_UNAVAILABLE503YesBack off and retry; the API fails closed.
INTERNAL_SERVER_ERROR500YesRetry with backoff and report the request_id.

Retry only when retryable is true or this documentation explicitly permits it. Use exponential backoff with jitter, cap the number of attempts, and keep the same idempotency key for the same logical operation.

Rate limits

Responses can include:

HeaderMeaning
RateLimit-LimitMaximum requests in the current window.
RateLimit-RemainingRequests remaining.
RateLimit-ResetSeconds until the current window resets.
Retry-AfterSeconds to wait after a 429.
X-Request-IDIdentifier for tracing and support.

Limits are shared by all keys of an assistant, so adding keys does not add capacity. Default limits:

BucketLimit
All API requests120/minute
Chat responses30/minute
Voice session creation20/minute

The Enterprise plan allows 600 requests, 120 chat responses, and 60 voice sessions per minute. Limits use a sliding one-minute window. Read response headers instead of hard-coding these values.

WebSocket errors

{
  "type": "error",
  "sequence": 8,
  "error": {
    "code": "INVALID_EVENT_ORDER",
    "message": "Audio frames require input_audio.start",
    "retryable": false
  }
}

Close codes:

CodeMeaning
1000Normal completion.
1002Protocol violation.
1008Authentication, policy, ordering, or limit violation.
1009JSON or binary frame is too large.
1011Provider or server failure.

Never reconnect with the same session token. For retryable failures, request a new token from your backend and open a new connection. For 1008, fix the credential, origin, event order, or limit issue first.

Contacting support

Send the endpoint, timestamp, HTTP status or close code, request_id, session_id, and public credential prefix. Never send the full API key, session token, raw audio, or unnecessary personal data.

On this page