Skip to main content

Error envelope

All API errors return a structured JSON envelope with three fields:
{
  "error": "Human-readable error message.",
  "reason_code": "machine_readable_code",
  "request_id": "req_abc123xyz"
}
FieldTypeDescription
errorstringA human-readable description of the error. Suitable for display to developers.
reason_codestringA stable, machine-readable code for programmatic error handling. Will not change.
request_idstringA unique identifier for this request. Include this in support requests for debugging.

HTTP status codes

StatusMeaningWhen returned
400Bad RequestInvalid request body, missing required fields, malformed JSON
401UnauthorizedMissing, invalid, or revoked API key
403ForbiddenValid key but insufficient permissions for this action
404Not FoundResource does not exist or is not owned by this customer
409ConflictIdempotency key reuse with different parameters, or state conflict
422Unprocessable EntityRequest is well-formed but semantically invalid
429Too Many RequestsRate limit exceeded. Check Retry-After header.
500Internal Server ErrorUnexpected server error. Retry with backoff.
503Service UnavailableService temporarily unavailable. Retry with backoff.

Reason codes

Authentication errors

reason_codeHTTPDescription
auth_error401Session has expired or is invalid
invalid_credentials401Invalid email or password
invalid_api_key401API key is missing, malformed, or not recognized
api_key_revoked401API key has been revoked
api_key_expired401API key has passed its expiration date
account_suspended403Customer account has been suspended
account_not_found404No account found for the given credentials

Rate limiting

reason_codeHTTPDescription
rate_limited429Too many requests. Check Retry-After header for wait time.

API key errors

reason_codeHTTPDescription
api_key_not_found404The specified API key does not exist
api_key_limit_reached409Maximum number of API keys reached for this customer

Run errors

reason_codeHTTPDescription
run_not_found404The specified run does not exist or is not owned by you
run_already_cancelled409The run has already been cancelled
run_not_cancellable409The run is in a terminal state and cannot be cancelled
run_not_awaiting_input409Signal sent to a run not in awaiting_input state
invalid_signal_type400Signal type is not accepted for this awaiting_input prompt

Validation errors

reason_codeHTTPDescription
validation_error400Request body fails schema validation
conflict409Resource state conflict (e.g., duplicate idempotency key with different params)

General errors

reason_codeHTTPDescription
not_found404The requested resource was not found
internal_error500An unexpected server error occurred
service_unavailable503The service is temporarily unavailable

Handling errors programmatically

Use reason_code for programmatic error handling instead of parsing the error message string. The reason_code is stable and will not change between API versions.
const res = await fetch(`${API_BASE}/v1/runs/run_nonexistent`, {
  headers: { Authorization: `Bearer ${API_KEY}` },
});

if (!res.ok) {
  const err = await res.json();
  switch (err.reason_code) {
    case "run_not_found":
      console.log("Run does not exist");
      break;
    case "invalid_api_key":
      console.log("API key is invalid — check credentials");
      break;
    case "rate_limited": {
      const retryAfter = res.headers.get("Retry-After");
      console.log(`Rate limited — retry after ${retryAfter}s`);
      break;
    }
    default:
      console.log(`Error: ${err.error} (request_id: ${err.request_id})`);
  }
}

Rate limiting details

When you receive a 429 Too Many Requests response, the Retry-After header tells you how many seconds to wait:
HTTP/1.1 429 Too Many Requests
Retry-After: 30
Content-Type: application/json

{
  "error": "Rate limit exceeded. Please wait before retrying.",
  "reason_code": "rate_limited",
  "request_id": "req_abc123"
}
Best practices:
  • Implement exponential backoff with jitter for automated retries.
  • Respect the Retry-After value — do not retry before it expires.
  • If you consistently hit rate limits, consider reducing your request rate or contacting support for a limit increase.

Getting help

When contacting support about an API error, always include:
  1. The request_id from the error response.
  2. The reason_code.
  3. The HTTP status code.
  4. The timestamp of the request.
This allows the support team to locate your request in the backend logs for fast debugging.