OpenAI TTS API reference — audio.speech.create mapped to EasyVoice
This page is a flat parameter-by-parameter reference for developers who know OpenAI's audio.speech.create endpoint and need the equivalent reference for EasyVoice's OpenAI-compatible TTS API. Unlike the migration guide — which walks through the narrative steps of porting existing code — this page is a searchable reference: every parameter accepted by audio.speech.create, its type, whether it is required or optional, its valid values on OpenAI, and the EasyVoice equivalent behavior. It also covers the complete error-code surface — 401, 400, 429, and 5xx — with what each code means and the correct handler for each, plus the request and response body shapes so you can validate an integration at the HTTP level without relying on any client SDK. The EasyVoice endpoint https://easyvoice.ae/api/v1/audio/speech accepts the same JSON body shape as audio.speech.create; only the base URL and the API key environment variable change.
5,000 characters per day free, no credit card. Pro $9.99/mo unlimited vs OpenAI $15/1M (tts-1) / $30/1M (tts-1-hd).
audio.speech.create parameters — EasyVoice equivalent table
The audio.speech.create endpoint accepts five parameters. Below is the full parameter reference with the EasyVoice equivalent behavior at https://easyvoice.ae/api/v1/audio/speech.
model (string, optional on both): OpenAI accepts 'tts-1' (standard quality, $15/1M chars) or 'tts-1-hd' (higher fidelity, $30/1M chars). EasyVoice runs Kokoro-82M as a single synthesis model. EasyVoice accepts 'kokoro-82m', 'tts-1', and 'tts-1-hd' as valid model values — the OpenAI names are mapped as aliases for drop-in compatibility. Omitting the field also succeeds on EasyVoice. No 400 is returned for any of these model strings.
voice (string, required): OpenAI accepts exactly six values — 'alloy', 'echo', 'fable', 'onyx', 'nova', 'shimmer'. EasyVoice accepts any voice ID in its catalog (56 voices total as of 2026): af_alloy, am_echo, bm_fable, am_onyx, af_nova, bf_lily for direct OpenAI-equivalent mappings, plus 50 additional voices. Sending an unrecognized voice ID on EasyVoice returns 400 with a JSON error body identifying the invalid field.
input (string, required): The text to synthesize. OpenAI imposes a 4,096 character maximum per request. EasyVoice's free tier has a daily quota of 5,000 characters across all requests — a single request can consume up to that remaining quota. EasyVoice Pro is unlimited per request. The field is required on both APIs; omitting it returns 400.
response_format (string, optional): OpenAI accepts 'mp3', 'opus', 'aac', 'flac', 'wav', 'pcm'. EasyVoice accepts 'mp3', 'wav', and 'opus'. Default on both APIs is 'mp3'. Sending an unsupported format on EasyVoice returns 400. For most production integrations, mp3 and wav cover all use cases; opus is the right choice for real-time streaming or WebRTC transport.
speed (number, optional): OpenAI accepts a range of 0.25 to 4.0, default 1.0. EasyVoice supports a similar speed range applied as a post-synthesis time-stretch. Values outside the supported range return 400. The speed adjustment is applied after synthesis rather than at the model level, meaning it does not affect voice character — only tempo.
Request and response shape
Request shape (identical on both APIs): HTTP POST to the endpoint with two required headers — Authorization: Bearer YOUR_API_KEY and Content-Type: application/json — and a JSON body containing the parameters described above. A minimal valid EasyVoice request body is: {"voice": "af_alloy", "input": "Hello."}. A complete request with all optional parameters: {"model": "kokoro-82m", "voice": "af_alloy", "input": "Hello from EasyVoice.", "response_format": "mp3", "speed": 1.0}.
Response shape on success (HTTP 200): Content-Type audio/mpeg for mp3, audio/wav for wav, audio/opus for opus. Body: raw audio bytes with no JSON envelope and no base64 encoding. response.arrayBuffer() in JavaScript (browser or Node.js), response.content in Python requests, ioutil.ReadAll(resp.Body) in Go — all return the audio bytes directly, ready to write to a file or pipe to a media player. The response does not include a JSON body, an id field, or a status field; there is no polling step. The audio is complete when the connection closes.
Response headers on success include Transfer-Encoding: chunked (confirming audio is streamed as generated rather than buffered entirely before first byte), Content-Type (as above), and optionally X-Request-Id for distributed tracing. If your integration monitors response headers, Transfer-Encoding: chunked confirms streaming is active and first-byte latency will be lower than the full synthesis duration.
Error codes — 401, 400, 429, and 5xx
401 Unauthorized: The Authorization header is missing, malformed, or contains an invalid or revoked API key. The response body is a JSON error object. Common causes: incorrect copy-paste of the API key, using a staging key against production (or vice versa), or a key that has been rotated out. Fix: retrieve the correct key from the EasyVoice dashboard, set it in the appropriate environment variable, and retry. The 401 is deterministic — retrying with the same invalid key will always fail. Do not implement retry logic for 401.
400 Bad Request: The request body is missing a required field (voice or input), contains an unrecognized voice ID, specifies an unsupported response_format, or provides a speed value outside the valid range. The error response body identifies which field is invalid. Fix: inspect the error body for the field name, correct it against the parameter table above, and retry. 400 is also deterministic — do not retry without fixing the request.
429 Too Many Requests: On the free tier, 429 is returned when the 5,000 character daily quota is exhausted. The quota resets at UTC midnight; retrying before the reset will fail. On Pro, 429 signals a server-side burst rate limit (too many concurrent requests from the account). Fix for free-tier 429: wait for the UTC midnight quota reset or upgrade to Pro. Fix for Pro 429: implement exponential back-off with jitter — start at a 1-second delay, double on each retry, cap at 60 seconds. Do not implement a tight retry loop without back-off; it will trigger continued 429s.
5xx Server Errors: 500 Internal Server Error, 502 Bad Gateway, 503 Service Unavailable, 504 Gateway Timeout. These indicate transient server-side issues. Fix: implement exponential back-off with jitter (same pattern as Pro 429). 503 is the most common transient error during high server load. 504 may indicate that a very long input text is timing out the upstream synthesis — consider splitting inputs over approximately 3,000 characters into multiple requests if 504 errors occur consistently on specific payloads.
Switch to EasyVoice if you need an OpenAI-compatible API endpoint with identical request shapes and error semantics where the only code changes are the base URL and the API key. Stay on OpenAI if your production error-handling logic has been tuned specifically to OpenAI's response timing and you cannot absorb the testing overhead of re-validating error paths against a new endpoint.
What is the EasyVoice base URL?
EasyVoice's OpenAI-compatible TTS endpoint is https://easyvoice.ae/api/v1/audio/speech. This is the only URL change required when switching from OpenAI's TTS API at the HTTP level. The path segment /audio/speech is identical to OpenAI's path structure, so URL-building code in your TTS service module changes only the base domain — not the path, not the query string, not the header format.
For HTTP libraries with a configurable base URL, set baseURL or base_url to 'https://easyvoice.ae/api/v1'. For direct HTTP calls, replace 'https://api.openai.com/v1/audio/speech' with 'https://easyvoice.ae/api/v1/audio/speech'. The Authorization header format (Bearer token), the Content-Type (application/json), the response format (raw audio bytes), and the error code semantics (401/400/429/5xx) are identical between the two endpoints.
Code samples
Real working code, not pseudo-code. Every request below assumes you've set EASYVOICE_API_KEY and OPENAI_API_KEY as env vars where shown.
Request and response — curl
Full request/response shape against the EasyVoice OpenAI-compatible endpoint# Minimal valid request (voice + input required)
curl -X POST https://easyvoice.ae/api/v1/audio/speech \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"voice":"af_alloy","input":"EasyVoice TTS API — parameter reference."}' \
--output out.mp3
# Response: HTTP 200, Content-Type: audio/mpeg, body = raw MP3 bytes (no JSON wrapper)
# Full request with all optional parameters
curl -X POST https://easyvoice.ae/api/v1/audio/speech \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "kokoro-82m",
"voice": "af_alloy",
"input": "EasyVoice TTS API — parameter reference.",
"response_format": "mp3",
"speed": 1.0
}' \
--output out.mp3
# Error codes: 401 bad key | 400 bad param | 429 quota/rate | 5xx serverVoices to try on the free tier
Every voice below is callable via the same voice parameter — preview audio samples and read the full character profile.
Frequently asked questions
Which audio.speech.create params does EasyVoice support?▾
EasyVoice supports all five audio.speech.create parameters: model (mapped to kokoro-82m; tts-1 and tts-1-hd accepted as drop-in aliases), voice (any of 56 catalog IDs), input (text string, required), response_format (mp3/wav/opus), and speed (0.25–4.0). The request body shape is identical to OpenAI's; only the base URL changes.
What does a 429 from the EasyVoice TTS API mean?▾
429 Too Many Requests on EasyVoice's free tier means the 5,000 character daily quota is exhausted — the quota resets at UTC midnight and retries before then will fail. On Pro, 429 signals a burst rate limit. Fix: exponential back-off starting at 1 second, capped at 60 seconds. Free-tier 429s clear automatically at UTC midnight.
Is response_format the same as OpenAI's on EasyVoice?▾
EasyVoice supports mp3, wav, and opus — the three most common formats in OpenAI's list. EasyVoice does not support aac, flac, or pcm as of 2026. Default is mp3 on both APIs. Sending an unsupported format returns 400. For most production integrations, mp3 and wav cover all playback and processing use cases.
What is the EasyVoice base URL for OpenAI-compatible requests?▾
https://easyvoice.ae/api/v1/audio/speech — the only change from OpenAI's api.openai.com/v1/audio/speech is the base domain. The path /audio/speech is identical. For libraries with a configurable baseURL, set it to https://easyvoice.ae/api/v1. Authorization header format, Content-Type, and response handling are unchanged.
How does EasyVoice handle the model parameter?▾
EasyVoice maps all known OpenAI model values to Kokoro-82M: sending model: 'tts-1', 'tts-1-hd', or 'kokoro-82m' all succeed with no error. Omitting the model parameter also succeeds. This drop-in compatibility means existing OpenAI-shaped code with the model field set works on EasyVoice without any defensive parameter removal.
Related OpenAI migration guides
Migrate from OpenAI TTS to EasyVoice in 5 lines
OpenAI TTS to EasyVoice migration guide: 5-line code diff in Python + JS. Model, voice, response_format mapping. Streaming compatible. $9.99 flat vs $15/1M.
OpenAI TTS quickstart — first audio in 5 steps, no credit card
OpenAI TTS quickstart alternative. EasyVoice: 5 steps, no credit card, first audio in under 2 minutes. Account, API key, curl request, mp3 playback — free tier.
OpenAI TTS streaming alternative — chunked audio with ReadableStream and iter_content
OpenAI TTS streaming alternative. EasyVoice supports chunked transfer — ReadableStream in JS, iter_content in Python. Same HTTP transport as audio.speech.create, no SDK.
Vendor comparison: EasyVoice vs OpenAI TTS
Side-by-side feature comparison covering voices, languages, pricing tiers, free limits, API surface, and the why-people-look / where-each-wins breakdown.
Developer-focused OpenAI migration in /tts-api
The developer-onboarding angle of the same migration — request body compatibility deep-dive, streaming behavior, ChatGPT plugin/Realtime API guidance, and the official OpenAI SDK constraint.
Start migrating off OpenAI TTS today
5,000 characters per day free, no credit card. Pro $9.99/mo unlimited replaces OpenAI's $15-$300/mo bills once you cross 666K characters per month.