Developers / Text to Speech
Generate speech synchronously
https://api.echonova.ai/v1/text-to-speech/syncGenerates speech for 1 to 500 characters in one call and returns the audio URL with the credits charged.
Headers
Bearer, a space, then your API key, which starts with ek_. Create keys in the portal under Developers, API Keys.
Request body
application/json
The text to speak, 1 to 500 characters. Leading and trailing whitespace is trimmed.
The id of a voice from List available voices. The voice fixes the dialect.
How fast the voice speaks.
How closely the voice follows the text. Leave it at the default unless you are tuning.
Diffusion steps. More steps are slower and cleaner.
Adds the vowel marks to Arabic text before it is read. Applies to Fusha voices only.
Reads numbers, dates, times, money, units, URLs and e-mails the way a speaker of the voice's dialect says them. On unless you send false.
Response
200 application/json Every response uses this envelope.
The result.
The id of the job the call created.
completed. A synchronous call creates its job already completed.
A signed link to the WAV file. It expires; read the job again for a fresh link.
Length of the audio in seconds.
Credits charged, a whole number.
true for a successful call.
Repeats the HTTP status.
null on success.
Errors
Same envelope, with success false and data null. All errors
When. text is an empty string or only whitespace.
Fix. Send at least one non-whitespace character.
When. text is missing or null; every rule on the field fails at once.
Fix. Send text as a JSON string.
When. text is a number, a boolean or an object.
Fix. Send text as a JSON string.
When. text is over the 500-character limit.
Fix. Split the text into several calls.
When. voiceId is an empty string.
Fix. Send an id from GET /v1/text-to-speech/voices.
When. voiceId is missing or null.
Fix. Send an id from GET /v1/text-to-speech/voices.
When. speed is below 0.5.
Fix. Send a speed from 0.5 to 2.
When. speed is above 2.
Fix. Send a speed from 0.5 to 2.
When. speed is not a JSON number, for example the string "1".
Fix. Send a number, not a string.
When. cfg is below 1.
Fix. Send a cfg from 1 to 5.
When. cfg is above 5.
Fix. Send a cfg from 1 to 5.
When. cfg is not a JSON number, for example the string "1".
Fix. Send a number, not a string.
When. numSteps is any other value.
Fix. Send one of the five values.
When. tashkeel is not true or false.
Fix. Send a JSON boolean.
When. The body or query carries a field the endpoint does not define.
Fix. Remove the field.
When. voiceId is not a well-formed id.
Fix. Copy the id exactly as GET /v1/text-to-speech/voices returned it.
When. The Authorization header is missing or is not Bearer ek_..., no key matches the token, or the key is deleted, disabled or its account is closed.
Fix. Send Authorization: Bearer ek_... with an enabled key from this environment.
When. The workspace balance cannot cover the charge for this call; nothing ran and nothing was charged.
Fix. Add credits to the workspace.
When. The workspace that owns the key has no subscription.
Fix. Check the workspace's plan in the portal.
When. The subscription is in a state other than active or trial.
Fix. Renew the subscription.
When. The key is restricted and Text to Speech is not among its services.
Fix. Edit the key and grant Text to Speech, or use another key.
When. No active voice has this voiceId.
Fix. List the voices again and pick one.
When. The JSON body is over 100 KB; the request is rejected before the API key is checked, so it has no Activity row.
Fix. Send a smaller body; long text belongs in several calls.
When. The request has a body whose Content-Type is not application/json.
Fix. Send Content-Type: application/json.
When. The key made more than 100 requests to one endpoint in 60 seconds, or one IP address made more than 100 requests to one endpoint in 60 seconds (the IP limit is counted before the key is checked, so it can answer with no key at all); a Retry-After header carries the seconds to wait.
Fix. Wait Retry-After seconds, then retry.
When. The call would take the key past its Credit Limit for this billing cycle; nothing ran and there is no Retry-After header.
Fix. Raise or clear the limit on the key, or wait for the next cycle.
When. An error the API did not classify.
Fix. Check the request, then retry after a short wait; contact support if it persists.
When. Speech generation was unavailable for the request; the charge is refunded.
Fix. Retry after a short wait.
When. A transient outage inside the API.
Fix. Retry after a short wait.
When. A transient timeout inside the API.
Fix. Retry after a short wait.
curl -X POST "https://api.echonova.ai/v1/text-to-speech/sync" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"الطقس اليوم جميل والسماء صافية في المدينة","voiceId":"66e5ef3a9c1d2b4f8a7e6c01"}'{
"data": {
"jobId": "66e5f0c2a1b2c3d4e5f60718",
"status": "completed",
"audioUrl": "https://storage.example.com/tts/tts-output.wav?X-Amz-Signature=...",
"durationSeconds": 3.4,
"creditsConsumed": 41
},
"success": true,
"statusCode": 200,
"errorMessage": null
}