Errors

Base URL https://api.suisse-speech.ch/v1 · X-API-Key

Every error has the same shape:

{"error":{"code":"tts.unknown_voice","message":"Unknown voice.","request_id":"req_…","detail":null}}
  • code is stable and safe to branch on.
  • message is fixed text, not a description of what went wrong internally.
  • detail appears only for problems in your request that need explaining (chiefly markup) and is capped at 400 characters.
  • request_id is what to quote in a support request.

GET /capabilities returns the full list under errors. The families:

prefix when
tts.* synthesis
stt.* recognition
agent.* voice agents (Voice agents); on the WebSocket the code arrives in an error message
api.* the edges of the service, outside any endpoint: an unknown path or method (api.not_found), a body that cannot be read (api.invalid_request), the address-based limiter (api.rate_limited), and the answers given while the service itself is not reachable (api.unavailable, api.timeout, with request_id: null)
code HTTP retry?
*.invalid_request, tts.text_required, tts.unknown_voice, tts.unknown_language, tts.unsupported_format, tts.invalid_speed, tts.style_too_long, tts.invalid_ssml, stt.invalid_audio, agent.invalid_audio, agent.duration_limit 400 no: fix the request (agent.duration_limit: open a new session)
*.unauthenticated 401 no
*.forbidden, agent.not_enabled 403 no (agent.not_enabled: voice agents are released per account, contact us and we enable them)
api.not_found 404 no: unknown path, or a method the endpoint does not take
tts.text_too_long, stt.audio_too_large 413 no
stt.unsupported_format 415 no
*.rate_limited 429 yes, after Retry-After: a burst, or (with a detail saying so) the daily audio budget, which starts afresh at 00:00 UTC
*.entitlement_exhausted 429 no: the free minutes or the credit are used up
agent.usage_limit 429 no: the session reached its usage limit
*.capacity 429 yes, after Retry-After
*.plan_limit_reached 429 not by itself: reduce parallelism or raise the limit
tts.unavailable, stt.upstream_unavailable, agent.unavailable, api.unavailable 503 yes, with backoff
*.timeout 504 yes (agent.timeout: no audio and no message for 120 s; open a new session)
*.internal_error, tts.encode_failed 500 once, then contact us

Voice agents answer in two ways. Before the socket is open (the handshake and POST /agent/tokens), the HTTP status is the answer: 401, 429 with Retry-After, 503; the token endpoint also returns the JSON body above. Once the socket is open, the same codes arrive in an error message, and the HTTP status in the table is only their family; what tells you whether the session goes on is the close code, 1000, 1001, 1008, 1009, 1011 or 4000 to 4003 (Voice agents). The WebSocket error carries code, message, detail and request_id at the top level, not inside an error object.

Four different things answer with 429, and only error.code tells them apart. An HTTP client that reports only the status line hides this distinction, so log the response body of every 429.

Failures are deliberately uninformative about their cause. A credential problem on our side and a fault on our side both surface as unavailable. This is intentional: the error surface does not describe our internals.

Recommended client behaviour: retry 503/504 with exponential backoff and jitter, honour Retry-After exactly on 429, and never retry a 4xx other than those two without changing the request.

What will not change without notice

  • Voice identifiers and what they sound like.
  • Error code values.
  • The realtime frame vocabulary.
  • The meaning of the metering unit.

Things that will change and should be read at runtime: the voice list, the language list, formats, limits and capacity figures. GET /capabilities is the contract for those.