Skip to content

Ask AI

Ask anything about Destesi — setup, products, APIs.

Powered by Claude. Answers may be wrong — always verify against the docs.

Troubleshooting

Common failure modes, what they mean, and how to fix them. Every API failure returns a single JSON object with a stable, machine-readable error code (for example { "error": "worker_unavailable" }) — branch on that code and the HTTP status.

A job sits at queued and the console says “warming up”

Section titled “A job sits at queued and the console says “warming up””

What it means: nothing is wrong. The synthesis engine scales down to nothing when idle, and your request arrived while it was cold. The job is safely queued and starts as soon as the engine is ready.

Fix: wait. Warm-up can take several minutes.

  • Your call returned 202 with "status": "queued" — including on the sync: true path, which degrades to polling rather than failing.
  • Poll GET /v1/jobs/{id} rather than resubmitting. Resubmitting just queues a second clip and spends your character allowance twice. If you must retry safely, send an Idempotency-Key and the replay returns the original job.

What it means: no synthesis engine is configured at all — not busy, not cold.

This is deliberately loud. Text-to-Speech will not quietly substitute a different engine and hand you audio in a voice you didn’t ask for.

Fix: on hosted Destesi this is an incident — report it with the request id. Self-hosters: no engine is wired at all.

What it means: you sent instruct where it does not apply — to a voice whose capabilities don’t list it, or on a request routed at an external provider that has no such parameter. The control is a property of the voice, and the API refuses rather than dropping the parameter silently — a control that is sometimes applied and sometimes ignored is worse than one that says no.

Fix: read the voice’s capabilities from GET /v1/voices and either drop the control or choose a voice that supports it.

Related: 400 invalid_instruct (over 500 characters).

What it means: you reused an Idempotency-Key with a different request body. The key is already bound to another request, and Text-to-Speech won’t guess which one you meant.

Fix: use a fresh key for a genuinely new request, or resend the original body byte-for-byte to get the original job back.

What it means: the workspace has used its measured allowance of characters synthesized this month.

Fix: check GET /v1/stats to see where you stand, or move to a plan with a larger allowance.

What it means: you routed synthesis at an external provider. not_connected means this workspace has no credential for it; provider_error means the provider itself failed.

Fix: connect the provider in Connect, or drop the provider choice and use a built-in voice. A provider_error is upstream — retry, and report it with the request id if it persists.

What it means: the voice_id is not visible to the workspace this request runs in.

Fix:

  • Confirm the ID exists with GET /v1/voices for the current workspace.
  • If you authenticate with a token, check the X-Destesi-Workspace header points at the workspace you meant — one token spans every workspace you belong to, so it is easy to call the wrong one.

What it means: a clip plays but contains no (or barely any) sound.

Fix: treat it as an engine issue and retry the job. If it repeats, report it with the request id from the X-Request-Id response header.

error Cause Fix
missing_session No credentials were supplied. Sign in again, or add an Authorization: Bearer idn_pat_… header.
session_invalid The browser session was rejected (signed out or expired). Sign in again at account.destesi.io.
unknown_bearer_scheme The Bearer value is not an idn_pat_ token. Use a Personal Access Token from account.destesi.io/settings/api-tokens. The header does not fall back to a cookie.
missing_workspace_header A token was sent without X-Destesi-Workspace. Add the header with your workspace slug.
invalid_token The token was rejected by accounts (revoked, expired, or not valid for that workspace). Mint a fresh token, and confirm X-Destesi-Workspace names a workspace you belong to.

A revoked token fails on the very next call — Text-to-Speech re-validates against the central accounts service on every request, so there is no cached-credential window. Mint a fresh token if yours stopped working. See API access & the dst CLI.

A previously working audio_url now returns an error

Section titled “A previously working audio_url now returns an error”

What it means: signed audio URLs expire after one hour. After that the link is dead.

Fix: call GET /v1/jobs/{id}/audio to get a fresh redirect, or fetch the clip from your Drive library, where every finished job is permanently registered.

What it means: the job is not done, or it never produced audio (for example, it failed).

Fix: check the job state first with GET /v1/jobs/{id}. Only done jobs have downloadable audio.

What it means: the request text exceeds the 5,000-character limit.

Fix: split the text into chunks under 5,000 characters, synthesize each, and concatenate the resulting WAVs. For anything over 500 characters, also use sync: false and poll the job rather than blocking inline.

  • Confirm you are calling https://api.tts.destesi.io (the API host), not https://tts.destesi.io (the web console).
  • The GET /healthz and GET /readyz probes need no auth and return ok — use them to confirm the service is up before debugging your request.