Skip to content

Error handling for AI clients ​

SandBase does not expose one universal error schema. Branch on HTTP status first, then parse the response shape documented for the endpoint family. Do not assume that every response contains code, param, request_id, or a specific message string.

Public response shapes ​

Core /v1/* middleware and several model or resource endpoints return a flat error:

json
{"error":"organization rate limit exceeded"}

Agents platform resources (/v1/agents*, /v1/mcp-connections*, /v1/secrets*, /v1/skills*) return an OpenAI-style object with a stable code. See Agents platform errors:

json
{"error":{"type":"invalid_request_error","code":"invalid_request","param":null,"message":"invalid request"}}

OpenAI-compatible gateways retain an OpenAI-compatible envelope. POST /v1/messages retains the Anthropic-compatible envelope:

json
{
  "type": "error",
  "error": {
    "type": "invalid_request_error",
    "message": "max_tokens is required"
  }
}

HTTP status handling ​

StatusMeaningClient action
400Invalid input or unsupported parameterFix the request using the selected endpoint and model schema.
401Missing, invalid, revoked, or expired credentialReplace or rotate the credential; do not retry unchanged.
402The request cannot be funded or a spending limit was reachedResolve billing or key limits before retrying.
403The credential lacks permission, or a compatibility surface maps a spending failure to 403Inspect the documented envelope and use an authorized key.
404Model or resource not foundVerify the current model name or resource ID.
409Resource state conflictRead the latest resource state before deciding whether a retry is safe.
429Organization request limit or video concurrency limitRetry with bounded exponential backoff and jitter.
500, 502, 503, 504SandBase or upstream transient failureRetry only when the operation is safe to repeat.

Authentication and rate-limit messages ​

Documented authentication messages include:

  • missing API key in Authorization header
  • invalid API key
  • API key has been revoked
  • API key has expired

A scoped key used outside its scope returns 403 with a nested body instead: {"error":{"code":"insufficient_scope","message":"API key is not authorized for this endpoint","request_id":"..."}}. Agents platform resources return the same code in their own envelope.

The documented rate-limit message is organization rate limit exceeded (the organization's assigned requests-per-minute limit, shared by all of its API keys). A 429 response does not currently include Retry-After or X-RateLimit-* headers, and there is no published universal RPM or concurrency default.

Model and resource lookup ​

Use GET /v1/models to discover enabled model IDs and GET /v1/models/{id_or_name} to inspect a model before execution. Treat a resource ID as opaque and verify it with the relevant list or get operation. Do not construct a different polling URL from an ID prefix.

Retry algorithm ​

Use bounded exponential backoff with jitter:

text
delay = min(base_delay * 2^attempt, max_delay) + random_jitter

Apply these rules:

  • retry 429 after a client-computed delay;
  • retry transient 5xx responses only a small, bounded number of times;
  • do not retry an unchanged 400, 401, 402, 403, or 404 request;
  • check idempotency before repeating any create, trigger, or external-action request;
  • retain partial output when a stream fails and decide whether continuing or restarting is safe;
  • surface the final HTTP status and sanitized endpoint-specific error to the caller.

Agents platform errors ​

Agents, Sessions, Skills, MCP connections, and Secrets return one envelope. For most codes, message is a fixed, safe sentence; invalid_request may carry a short explanation, such as which input shape or option is not supported. Branch on code, not on message.

json
{"error":{"type":"invalid_request_error","code":"conflict","param":null,"message":"conflicting request"}}

type is authentication_error for 401, server_error for 5xx, and invalid_request_error otherwise.

HTTPcodeMeaningWhat to do
400invalid_requestMalformed or unknown fields, failed validation, or an unsupported optionFix the request; do not retry unchanged
400skill_not_foundA referenced Skill or version is not availableFix the Agent's skills
401unauthorizedMissing, invalid, or conflicting API key headersCheck Authorization / X-API-Key
402spending_limit_exceededKey spending limit or organization balance exhaustedAdd credits or raise the limit
403insufficient_scopeThe key is scoped and cannot use Agents resourcesUse a standard Console-created key
403org_disabledThe organization is not permitted to run AgentsContact support
404not_foundThe resource does not exist in your organizationCheck the ID
409conflictStale row_version, a state that does not allow the change, or an Idempotency-Key reused with a different bodyRead the resource again, then decide
409session_input_pendingEarlier input is still being deliveredWait; do not resend with a new key
409session_input_expiredInput admission expiredInspect history before sending again
409session_environment_unavailableThe execution environment is unavailableWait or create a new Session
413request_too_largeThe request body, or the Session configuration frozen from it, exceeds the size limitSend a smaller body; do not retry unchanged
429quota_exceededAgents quota exceededRetry later
502executor_rejected, executor_contract_errorThe execution layer rejected the request or answered unexpectedlyCheck the Agent configuration, then retry
503executor_unavailable, storage_unavailable, skill_unavailable, tenant_unavailable, tenant_provisioning_failed, authorization_unavailable, admission_unavailable, internal_errorA dependency is temporarily unavailableRetry with backoff and the same Idempotency-Key

skill_runtime_incompatible can also appear; it is returned as 503 with the message internal error.

Streaming failures ​

After a streaming response has started, a failure may arrive in the protocol's stream format instead of as a new HTTP status. Treat the stream as incomplete, close it, retain any partial content needed by the application, and retry only when the request is safe to repeat.

See also ​