Errors & Refunds
Understand Sonna's upfront credit billing model, error responses, and automatic refund policy for Text-to-Speech.
Sonna's Text-to-Speech API uses an upfront deduction with automatic refund model. You are only billed for successful synthesis — any failure refunds your credits in the same request.
Speech is synchronous
Unlike long-running media jobs, TTS returns the finished audio in the response
— there is no job_id, no polling, and no reconciliation queue. Billing
resolves entirely within the single request.
Billing flow
- Balance check. The server computes the cost (per character × model rate, minus the 10% API discount) and verifies your balance. If it's not enough, you get
402and nothing is charged. - Upfront deduction. Credits are deducted before synthesis begins.
- Synthesis. The request is sent to the resolved provider (ElevenLabs / Gemini / Google).
- Settle. On success you get the audio URL. On any failure — validation, provider error, capacity — the deducted credits are refunded immediately before the error response returns.
Refund triggers
Credits are returned automatically when:
- Validation fails after deduction — e.g. the text exceeds the model/plan character limit (
400 TEXT_TOO_LONG), or the voice ID is invalid. - Access is denied — a Free-tier account requested an ElevenLabs or Gemini voice (
403 PAID_ACCESS_REQUIRED). - The provider errors or is over capacity — synthesis failed, timed out, or the provider rejected the request (
503).
In every case the refund is bound to the request and applied before the response is sent — you never need to reconcile or retry to recover credits.
Error responses
| Status | Code | Meaning |
|---|---|---|
400 | TEXT_TOO_LONG | Text exceeds the model's limit (or your plan cap) |
400 | — | text or voice missing, or the voice ID is invalid |
402 | — | Insufficient credits (nothing deducted) |
403 | PAID_ACCESS_REQUIRED | Free-tier account using an ElevenLabs or Gemini voice |
409 | DUPLICATE_REQUEST | Another synthesis is already in progress for your account |
429 | — | Rate limit exceeded — see Rate Limits |
503 | SERVER_BUSY | Gemini synthesis queue is full — retry shortly |
503 | PROVIDER_BUSY | Provider temporarily over capacity — retry after Retry-After |
Failed requests return a non-2xx status with an error message and, where applicable, a machine-readable code:
{
"error": "Text exceeds the maximum allowed length of 5,000 characters for this model and your plan.",
"code": "TEXT_TOO_LONG"
}