beatraDocs

Errors & retries

The error envelope, the retryable rule, and the full error code table.

The table below is auto-generated from Beatra's public runtime error taxonomy.

Every public Beatra error response uses the standard error envelope. The error.code field is one of the stable public values below; the error.retryable boolean tells the client SDK whether a naive retry could succeed.

Every error body is:

{
  "error": {
    "code": "<machine code>",
    "type": "<error family>",
    "message": "<human description>",
    "retryable": true,
    "param": "/field",
    "details": {},
    "request_id": "<the same value as the X-Request-Id response header>"
  }
}

How to branch

You seeYou should
retryable: trueAfter a brief backoff, retry the exact same request with the same Idempotency-Key. Honor Retry-After when present. 429 responses include X-RateLimit-* headers.
retryable: falseRetrying as-is produces the same outcome. Change the request, fix credentials, or surface the error to the user. Looping on a non-retryable error is a bug.
error.paramWhen present, a JSON Pointer (RFC 6901) to the offending field in the request body.
error.type / error.details / error.request_idStable family, correction facts, and the trace identifier.
error.messageDiagnostic prose, not a branchable contract. For a task that reaches terminal failure after a provider response, it preserves the provider's wording after credential, signed-URL, control-character, and length safety handling.

When present, error.details.recovery adds a branchable action without changing the top-level error envelope. requires_input_change says whether the submitted content must change. client_request_id: new means the corrected or terminal work is a new logical request; otherwise follow retryable and the endpoint's idempotency rules.

{
  "details": {
    "recovery": {
      "action": "fix_arguments_and_resubmit",
      "requires_input_change": true,
      "client_request_id": "new"
    }
  }
}

Auth / Account

codeHTTPretryabledescription
unauthorized401noMissing or malformed authentication credentials. Send Authorization: Bearer <API key>.
invalid_api_key401noAPI key is invalid, disabled, revoked, or unknown. Create or rotate keys in the console (Developer → API keys) and retry with the new key.
api_key_region_mismatch400noAPI key region prefix does not match this endpoint. Call the API host matching the key's region, or use a key issued for this region.
3 more
codeHTTPretryabledescription
tenant_disabled403noTenant has been suspended or disabled. Contact support; retrying cannot succeed.
forbidden403noCaller does not have permission for this operation. Use a credential with the required permission; retrying unchanged cannot succeed.
email_send_failed502yesLogin-code email could not be delivered (transient send failure). Request a new code after a brief backoff.

Billing

codeHTTPretryabledescription
insufficient_balance402noInsufficient credits: this request was not started and nothing was charged. Add credits at https://console.beatra.cn/wallet?intent=buy — they take effect immediately; then retry this same request. No reinstall or re-authorization is needed.
billing_failed500yesCharge or refund attempt failed after retries. Retry with the same Idempotency-Key / client_request_id; the identity guarantees no double charge.
payment_provider_unavailable503noPayment checkout provider is not configured for this payment method. Choose another payment method in the console.

Capacity and availability

codeHTTPretryabledescription
rate_limited429yesCaller-side rate limit exceeded. Retry after the Retry-After interval; X-RateLimit-* headers report the active budget.
model_unavailable503yesThe requested model is not currently available. Retry with backoff, switch to another selectable model (beatra.models.list or GET /v1/catalog/models), or use model=auto. When present, details.reason and details.available_at give the cause and the expected recovery time.
model_request_failed502yesThe model request failed after retryable service errors. Retry with backoff; if it persists, adjust inputs or choose another model.
4 more
codeHTTPretryabledescription
model_timeout504yesThe model request timed out. Retry with backoff.
model_rate_limited429yesModel capacity was rate-limited. Retry after a backoff.
model_output_invalid502yesThe model returned a result that cannot be delivered, such as missing or corrupt audio, or a generated file that could not be retrieved. The task fails and its charge is refunded; submit a new request.
internal_error500yesUnclassified server-side error. Retry with the same idempotency identity; if it persists, report the request_id.

Other error codes

Request validation15 ⌄
codeHTTPretryabledescription
invalid_request422noRequest body fails structural validation. param points to the first offending field; details.errors lists every failure with its loc and reason. Fix the named fields and resend.
skill_package_format_invalid422noSkill package identity is malformed. Use a lowercase hyphenated slug of at most 64 characters and a valid SemVer package version.
unsupported_capability400noCapability does not exist or is disabled. GET /v1/catalog/capabilities lists the currently available capabilities.
unsupported_model400noModel does not exist or is not selectable for this capability. Discover selectable models with beatra.models.list or GET /v1/catalog/models, or use model=auto.
unsupported_option422noThe selected concrete model does not support a requested value or control. param identifies the field and details.candidate_failures[] carries a specific failure code such as unsupported_resolution, unsupported_duration, or unsupported_aspect_ratio, plus the received and supported values. Change the named field or choose a different model; with model=auto this is returned only when no candidate can satisfy the request.
no_eligible_model422noNo live model can honor the complete model=auto request. details.candidate_failures[] lists each provider-neutral rejection; change only the incompatible fields or pick a listed concrete model.
voice_model_incompatible422noThe requested voice does not resolve on the requested model. Use model=auto, a compatible model, or another voice from the voices list.
unsupported_input_modality422noThe selected model does not support an input modality in the request (such as image, audio, or file input). param points to the first offending field; remove it or choose a model that supports it.
context_length_exceeded422noThe request exceeds the selected model's context window. Shorten the input or choose a model with a larger context window.
safety_rejected400noThe request did not pass content safety review. Ask the user to review the prompt and every input resource, then edit or replace content that may be unsafe before submitting a new task with a new client_request_id. Retrying the same content will not help.
content_filtered502noA safety filter blocked the output mid-generation. Rephrase the prompt or switch models; an identical retry is usually blocked again.
not_found404noRequested HTTP resource or endpoint was not found. Check the path and identifier; retrying unchanged cannot succeed.
streaming_not_yet_implemented501noLegacy compatibility code for older deployments where stream=true was recognized but not enabled.
invalid_window422noTime range is invalid.
invalid_cursor400noPagination cursor is malformed.
Callbacks3 ⌄
codeHTTPretryabledescription
callback_url_required422noA callback URL is required when a callback signing key is selected. Add callback_url or remove callback_signing_key_id.
callback_signing_key_not_found404noCallback signing key does not exist or is not visible to this account. List signing keys in the console and pass a current key id.
callback_signing_key_inactive422noCallback signing key is retired and cannot be selected for a new task. Select an active key, or omit the key id for unsigned delivery.
Media inputs5 ⌄
codeHTTPretryabledescription
invalid_media422noMedia input is malformed or cannot be decoded. Re-export or re-encode the file and submit it again; param names the offending field.
unsupported_media_type422noMedia input type is not supported for this capability. Convert to a supported format (see the capability page or model constraints) and resend.
media_too_large413noMedia input exceeds the allowed size. Compress or trim the input, or upload it first and pass an artifact reference.
media_fetch_failed422yesBeatra could not access an input resource. Check that the resource is reachable over HTTPS, or upload it and pass an artifact reference.
upload_stalled408yesAn upload stopped sending data for too long, or ran past the upload time limit. Send the same PUT to the same upload URL again; if the upload grant has expired, request a new one with beatra.assets.upload.
Tasks and resources13 ⌄
codeHTTPretryabledescription
task_not_found404notask_id does not exist or does not belong to this account. Use the task_id returned at creation; list recent tasks with GET /v1/tasks or beatra.tasks.list.
conflict409noThe operation conflicts with the resource's current state — for task cancellation this means execution continues. Follow details.action (usually: keep polling the same task); do not resubmit the work.
result_undeliverable502noThe completed result could not be delivered because it is too large, too deeply nested, or not valid JSON. Do not resubmit the same lookup.
artifact_not_found404noartifact_id does not exist or does not belong to this account. Upload the media again and use the newly returned artifact id.
voice_not_found404novoice_id does not exist or does not belong to this account. List available voices with GET /v1/voices or beatra.voices.list.
voice_activation_required422noThis voice is a free preview and can't be used for speech until it is activated. Confirm the activation price with the user, then call beatra.voices.activate.
voice_unavailable422noThe cloned voice can no longer be restored from its saved sample. This is permanent; do not retry. Contact support. This request is not charged or is refunded; the original clone fee is not refunded.
voice_retired422noThis voice is no longer supplied. Select another voice; details may name a replacement. The selected voice is never silently replaced. This request is not charged or is refunded.
price_confirmation_required422noThe activation quote has expired or changed. Show the new quote to the user, get their consent, then call beatra.voices.activate again with the new confirmation_token and confirm_credits.
voice_preview_expired422noThis preview voice has expired and can no longer be activated or used. Clone the voice again.
voice_sample_rejected422noThe voice sample was rejected. See details.reason, fix the sample, and clone again with a new client_request_id.
voice_limit_reached409noThis account already has the maximum number of cloned voices waiting for activation. Activate one, or delete one in the desktop app or with DELETE /v1/voices/{voice_id}; waiting voices also expire after 7 days.
voice_activation_daily_limit429noThis account has activated 3 voices today, the daily limit. Nothing was charged. To activate more voices today, contact Beatra support; the limit resets at 00:00 UTC (08:00 Beijing time).
Idempotency and response mode2 ⌄
codeHTTPretryabledescription
idempotency_conflict409noSame Idempotency-Key / client_request_id was used with a different request body. Submit changed work with a NEW identity; to retry identical work unchanged, reuse the original. Inspect the existing task before choosing.
request_in_progress409yesSame idempotency identity matches an in-flight request. Retry later with the same identity; the original response will be returned.

Warnings

codedescription
option_ignoredA control or option was ignored because the model does not support it; the request still succeeds.
markup_degradedSome markup was removed, read as written, or shortened to the model's limit because the model does not support it.
markup_adjustedSome markup was written incorrectly and was corrected or skipped; the message gives the reason and the correct form. The request still succeeds.
voice_retiringThe voice is scheduled for retirement; the message gives the date and any recommended replacement.
direction_unavailableThe AI Director could not direct all or part of the text. Those sentences come back as written, and that part is not charged. When field is voice, the voice you named cannot read this script; choose another voice.
effect_unavailableThe chosen voice cannot perform an effect the user asked for, or the effect could not be kept because the text is close to the voice's per-call length limit; effect names it and substitute says what was used instead. When effect is voice_gender, no voice of the requested gender reads this language yet.
instruction_unsupportedThe instructions ask for something not yet supported, such as translation, rewriting the text or assigning several speakers. That part is ignored.
no_voice_availableNo voice can be recommended: none reads this language, the model you named has no voice for this language, the text is longer than every voice's limit, or the voices that read it are temporarily unavailable. The script still comes back.

Markup parsing can also return other warnings: markup_escape, unclosed_markup, unrecognized_markup and unknown_markup.

details.reason values

These are the reasons used by the ElevenLabs models and the AI Director; other capability pages document their own reasons.

model_unavailable

reasondescription
voice_temporarily_busyThe voice is being prepared or restored; retry after retry_after_seconds.
voice_temporarily_unavailableThis cloned voice cannot be restored right now; other voices work. available_at gives the recovery time when known.
creation_temporarily_unavailableNew clones with this model are paused; omit model to use the default voice clone at the same price. available_at gives the recovery time when known.

rate_limited

reasondescription
speech_inflight_limitTwo ElevenLabs speech tasks (free clone previews included) are already in progress; wait for one to finish.
voice_creation_daily_limitThe account used today's three clones with this model; resets at 08:00 Beijing time (00:00 UTC).
director_inflight_limitTwo AI Director tasks are already in progress on this account; wait for one to finish.
director_busyThe AI Director is at capacity; retry after retry_after_seconds.

insufficient_balance

reasondescription
director_estimateThe balance does not cover the AI Director's estimate for this text plus that of any other AI Director task in progress; the charge itself is the actual usage.

Asynchronous task failures

A generation can be admitted successfully and later end with status: failed. REST task reads, MCP beatra.tasks.get, and callbacks return the same Task.error object with code, type, message, retryable, optional param, optional details, and request_id. A failed task read is the task's final state, not an MCP protocol error.

model_output_invalid means the model completed successfully but Beatra could not download the generated artifact after repeated attempts. No result artifact is available for that failed task.

MCP tool errors

A failed MCP tool call returns a tool result with isError: true and structuredContent.error carrying the same vocabulary as the REST envelope — code, type, message, retryable, optional param (JSON Pointer into the tool arguments), optional details — plus the JSON-RPC jsonrpc_code. Branch on code and retryable exactly as with REST.

One MCP-only code exists: insufficient_scope (the device authorization lacks a required scope; missing_scopes names them — re-run the Beatra device authorization; retrying without re-authorizing cannot succeed). Unexpected server failures surface as internal_error tool results, never as bare HTTP errors.


Generated from 54 public runtime error codes. 25 internal, admin, or provider-ingress codes are intentionally omitted from public docs.

Last updated

On this page

Markdown
Errors & retries | Beatra Docs