Errors

All errors follow a standard format:

JSON

doc_url links to the docs page for that error type. Include request_id when you contact support.

Error Types

The four you'll actually hit while building:

StatusTypeSDK ExceptionDescription
401authentication_errorAuthenticationErrorInvalid or missing API key
402billing_errorBillingErrorRun or cost limit reached, or balance depleted
422validation_errorValidationErrorInvalid request parameters
429rate_limit_errorRateLimitErrorToo many requests

Every SDK exception maps to one status. Catch the specific class you can recover from:

Python

The SDK retries 429 and 500+ responses with exponential backoff for idempotent methods (GET, PUT, DELETE), and for the run-creating POSTs, which carry an idempotency key so a retry returns the original run instead of starting a second one. Any other POST or PATCH is never retried, to prevent duplicate side effects.

All error types and `error.details` conventions
StatusTypeSDK ExceptionDescription
400invalid_request_errorValidationErrorInvalid request
403permission_errorPermissionDeniedErrorInsufficient permissions
404not_foundNotFoundErrorResource not found
409conflict_errorConflictErrorResource conflict (duplicate, not active)
500+api_errorAPIErrorServer error (automatically retried for GET/PUT/DELETE)
  • Errors that carry a machine-readable app code (e.g. feature_disabled, from_template_conflict, RUN_LIMIT_REACHED) put it in error.details.error_code, with any recovery context (missing, connect_urls, rejected_fields, …) as sibling keys under error.details. The Python SDK surfaces it as the exception's .code.
  • Query params are strict: an unknown query parameter is rejected with 422 (error.details.error_code = "unknown_query_parameter", with a did-you-mean hint). Analytics params (utm_*, gclid, fbclid, _) are ignored. Unknown fields in request bodies are silently ignored.

Billing Error Codes

A 402 billing_error carries a machine-readable code plus an error.details object with the context you need to recover (BillingError.code / BillingError.details in the SDK). The two you must handle:

codeMeaningKey details fields
RUN_LIMIT_REACHEDMonthly included runs exhaustedruns_used, runs_limit, period_end, overage_available (whether overage can actually be enabled for your account — false without an active subscription to bill it to)
TOKEN_BALANCE_DEPLETEDPrepaid token balance exhausted (API/developer billing). Top up, or connect your Claude subscription for local developmentbalance_micros, balance_usd, topup_url, connect_claude_url
Python
All billing codes, plus the two 429 guards
codeMeaningKey details fields
OVERAGE_CAP_REACHEDUsage overage spend cap hitoverage_used_cents, overage_cap_cents, period_end, overage_settings_url (raise the cap or upgrade)
TRIAL_EXPIREDTime-boxed trial has endedtrial_ends_at, upgrade_url
COST_LIMIT_REACHEDFair-usage cost backstop hitruns_used, runs_limit, period_end
SUBSCRIPTION_BLOCKEDPayment issue (past_due / unpaid)subscription_status
END_USER_RUN_LIMIT_REACHEDOne end-user hit your per-end-user run sub-cap (other end-users unaffected)end_user_id, runs_used, runs_limit, period_end
END_USER_COST_LIMIT_REACHEDOne end-user hit your per-end-user cost sub-capend_user_id, cost_used_cents, cost_limit_cents, period_end

Two more guards return 429 rate_limit_error (not 402):

  • END_USER_RATE_LIMITED: an end-user burst past your per_end_user_rate_per_minute setting. details carry end_user_id, limit_per_minute, retry_after, plus a Retry-After header. Configure all three sub-caps via client.settings.update(...); see Users.
  • SANDBOX_CONCURRENCY_LIMIT: too many runs in flight at once. details.scope says which ceiling: account (your own burst; details carry your concurrent_runs and limit) or platform (overall capacity, no counts). Wait for in-flight runs to finish and retry after the Retry-After header. Need more concurrency? Contact support to raise your account cap.

Run-Level Failures

The exceptions above cover problems reaching the API. A run can also fail upstream: an expired Claude credential, an exhausted quota, a model rate limit. The HTTP request succeeds (no exception), but the run ends with status "failed", the message in run.output, and a machine-readable class in run.error_code. Always check it before trusting output:

Python
Run `error_code` reference

Transient codes are retry-safe; credential codes need re-auth first.

codeMeaningRun statusRetry safe?
oauth_revokedThe connected Claude subscription credential was revoked or expiredfailedAfter reconnecting OAuth
subscription_quota_exhaustedThe connected Claude subscription hit its usage quotafailedAfter the quota window resets
model_unavailableThe requested model is not available on the connected Claude planfailedAfter switching model or upgrading the plan
api_credit_balanceThe upstream provider key ran out of creditfailedAfter the balance is restored
rate_limitedUpstream model rate limit hit mid-run (auto-retried on scheduled runs)failedYes
overloadedThe upstream provider was overloaded or down (5xx/overload, auto-retried on scheduled runs)failedYes
sandbox_boot_timeoutThe sandbox never started; nothing executedfailedYes (auto-retried on scheduled runs)
sandbox_quota_exhaustedThe execution platform was at capacity, so no sandbox could be created; nothing executedfailedNot immediately — the same limit will refuse a retry; wait, then retry
incomplete_streamThe stream died before finishing; the agent may have partially executedfailedReview output first
internal_timeoutAn internal service timed out while the run was starting or executingfailedYes
service_unreachableA service the run depends on was unreachablefailedYes
sandbox_unavailableThe sandbox could not be provisioned, or was lost mid-runfailedYes (auto-retried on scheduled runs when nothing had executed yet)
storage_errorA temporary storage error interrupted the runfailedYes
internal_errorUnclassified platform error; reported automatically on our sidefailedYes, then contact support
unknownUnclassified upstream error; the message is in run.outputvariesReview output first

Next: Limits · Going Live

Was this page helpful?