Errors are JSON with a stable code and a human-readable message.
Branch on code, never on message. Messages are written for humans and may be reworded; codes are part of the contract.

Reference

Retry strategy

Only unavailable is reliably transient. Retry it with exponential backoff and jitter, three attempts over a few seconds is usually enough.
Do not retry synthesis_failed in a loop. It usually indicates something about the request rather than a transient fault, and repeated attempts will fail the same way.

Handling errors on a live call

The 4xx codes are development-time problems and should never reach production traffic: validate voice and model IDs at configuration time, not per request. The ones that can occur mid-call are insufficient_credit, unavailable, and synthesis_failed. Each needs a defined behaviour:
  • insufficient_credit: alert operations. Callers should hear a graceful fallback, not silence. Monitor your balance so this never fires.
  • unavailable: retry once quickly. If it fails again, fall back to pre-recorded audio if you have it.
  • synthesis_failed: fall back immediately rather than retrying.
Keep pre-recorded audio for your most critical prompts: greeting, hold, and handoff. A line that degrades to recorded prompts is still a working line.

Errors never carry internal detail

Error messages describe what you can act on. They never include upstream diagnostics, infrastructure identifiers, or stack traces, full detail stays in Voho’s logs. If you need help diagnosing a specific failure, send the timestamp, the voice and model, and the X-Voho-* response headers to your Voho contact.