Skip to content
POST
https://api.voice213.com/api/v1/tts
Try it
curl -X POST https://api.voice213.com/api/v1/tts \
  -H "Authorization: Bearer $VOICE213_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "(نبرة حماسية ومنعشة) خويا، شفت الساعة الجديدة؟ مقاومة للماء وبسوار جلدي أصلي!",
    "model": "voice213-pro-2",
    "voice": "ryad",
    "dialect": "algerian"
  }'
{
  "success": true,
  "audioUrl": "https://pub-5d56f47943d84bbda9b38f1a6f9962e6.r2.dev/tts/66f1c0a4e1b2c3d4e5f60718/1727254800000-9f3c2a7b1d4e6f80.mp3",
  "model": "voice213-pro-2",
  "voice": "ryad",
  "cost": 1.2,
  "currency": "DZD",
  "chars": 56,
  "billableChars": 100,
  "remainingCredit": 4998.8,
  "words": 9,
  "quality": "pro2",
  "dailyProCount": 0,
  "dailyProLimit": null
}

Turns a script into speech in Algerian, Tunisian or Libyan darija. It's the one endpoint for every voice-over: choose the model with model and the voice with voice, and switch either one from one request to the next.

{
  "text": "مرحبا بيكم في Voice213",
  "model": "voice213-pro-2",
  "voice": "kenza"
}

The endpoint answers in one of two formats. Both take all five models and all 30 voices:

  • Studio format, the default: you get a link to an MP3 file, and the voice-over is saved to your History in the web app.
  • Inline format: name the voice with voiceId instead of voice, and the audio comes back inside the response as a WAV data URL. Nothing is stored.

Voice213 picks the format from the body: a request with a voiceId, or with a dialect of 1, 2 or 3, uses the inline format; any other request uses the studio format.

​Pricing

Voice-overs are billed per character of text, spaces and punctuation included, at the price of the model you choose:

ModelmodelPer 1,000 charactersPer million characters
Voice213 LiteDefaultvoice213-lite9 DA9,000 DA
Voice213 Lite 2Newvoice213-lite-28 DA until 31 December 2026, then 15 DA8,000 DA until 31 December 2026, then 15,000 DA
Voice213 Provoice213-pro20 DA20,000 DA
Voice213 Pro 1.5voice213-pro-1.539 DA39,000 DA
Voice213 Pro 2Newvoice213-pro-212 DA until 31 December 2026, then 24 DA12,000 DA until 31 December 2026, then 24,000 DA
  • Every request is billed at least 100 characters, so a short line costs the same as a 100-character one.
  • Tone directions such as (نبرة واثقة وهادئة) are performed, not read, and aren't billed when they're at most 100 characters long, parentheses included. A longer one is billed like the rest of the text.
  • A text with nothing to speak, such as one made only of tone directions, is refused with 400 EMPTY_TEXT.
  • Tone directions stay free, but they can't outweigh the spoken text: a text may be at most twice its billable characters plus 1,000 characters long, or it's refused with 400 TEXT_TOO_LONG. See Too much unspoken text.
  • Nothing is charged when a voice-over fails. While one runs, its price is set aside from your API credit: see Several voice-overs at once.

To know the price before you generate, send the same body to Estimate Cost. It's free. See API Pricing & Limits for worked examples.

Authorizations

Authorizationstringrequired

Your API key as a Bearer token: Bearer sk_live_.... You can send it in an x-api-key header instead. See Authentication.

Body

application/json
textstringrequired

The script to speak, up to 5,000 words in either format. Every word counts toward the limit, tone directions included. A text with nothing to speak, such as one made only of tone directions, is refused with 400 EMPTY_TEXT. A text longer than twice its billable characters plus 1,000, every character counted, is refused with 400 TEXT_TOO_LONG. Long texts take longer to generate: split very long scripts.

modelstringdefault: voice213-lite

The voice model: voice213-lite, voice213-lite-2, voice213-pro, voice213-pro-1.5 or voice213-pro-2. Capitalization doesn't matter, and the short forms lite, lite-2, pro, pro-1.5 and pro-2 work too. An unknown model is refused with 400 UNKNOWN_MODEL, which lists the models you can use, and a model paused for the API with 503 MODEL_DISABLED. See List Models for their prices, and Voice Models to choose one.

voicestringdefault: nariman

Studio format: the voice, any of the 30 voice IDs, such as nariman, ryad or kenza. Capitalization doesn't matter. An unknown voice is refused with 400 UNKNOWN_VOICE, which lists the voice IDs. Ignored in the inline format (a request with voiceId or a numeric dialect).

voiceIdstring

Inline format: the voice, any of the 30 voice IDs that List Voices returns. Capitalization doesn't matter. Sending voiceId switches the request to the inline format. An unknown ID is refused with 400 Invalid voice ID.

dialectstring | numberdefault: algerian

The dialect: algerian, tunisian or libyan. The numbers 1, 2 and 3 work too, but they switch the request to the inline format, which reads the voice from voiceId and ignores voice (without voiceId, Nariman speaks). With voice, send the dialect by name. Any other value is read as Algerian. See Dialects.

Studio format: an approximate length for the voice-over, in seconds. The voice adjusts its pace to come close to it, for example to fit a 15-second video.

qualitystring

The older name for the model, still accepted so existing integrations keep working: standard (Voice213 Lite), lite2, pro, pro1.5 or pro2. Unlike model, an unknown quality isn't refused: it uses Voice213 Lite. When a request has both, model wins. Prefer model in new code.

Response: studio format

application/json
successbooleanrequired

true.

audioUrlstringrequired

A link to the voice-over, an MP3 file at 128 kbps. The voice-over is also saved to your History in the web app. In the rare case the file can't be stored, audioUrl carries the MP3 itself as a data URL (data:audio/mp3;base64,…) and nothing is saved to History, so check for the data: prefix before downloading it.

modelstringrequired

The model that spoke, such as voice213-pro-2.

voicestringrequired

The voice that spoke, such as kenza.

costnumberrequired

What the request cost, in dinars.

currencystringrequired

DZD.

charsnumberrequired

The characters of text, without its free tone directions (those of up to 100 characters) and with runs of spaces counted once.

billableCharsnumberrequired

The characters billed: chars, or 100 when chars is lower.

remainingCreditnumberrequired

Your API credit after the request, in dinars.

wordsnumberrequired

The words in text, not counting tone directions, punctuation and emoji. The 5,000-word limit counts tone directions too.

qualitystringrequired

The model under its older name, such as pro2, for integrations that still read it.

dailyProCountnumberrequired

Always 0: API requests don't use the web app's daily Pro allowance.

dailyProLimitnullrequired

Always null: the API has no daily limit on Pro models.

Response: inline format

application/json
successbooleanrequired

true.

dataobjectrequired

The result.

Show properties
audiostringrequired

The speech as a data URL: data:audio/wav;base64, followed by the WAV file, base64-encoded (mono, 16-bit, 24 kHz).

formatstringrequired

audio/wav.

modelstringrequired

The model that spoke, such as voice213-lite.

textLengthnumberrequired

The length of text as sent, in UTF-16 code units (JavaScript's text.length). It isn't the count TEXT_TOO_LONG uses.

wordCountnumberrequired

The words in text, not counting tone directions, punctuation and emoji. The 5,000-word limit counts tone directions too.

charsnumberrequired

The characters of text, without its free tone directions (those of up to 100 characters) and with runs of spaces counted once.

billableCharsnumberrequired

The characters billed: chars, or 100 when chars is lower.

costnumberrequired

What the request cost, in dinars.

currencystringrequired

DZD.

remainingCreditnumberrequired

Your API credit after the request, in dinars.

​How the voice performs your script

  • The default delivery is a warm, confident advertising voice. Tone directions in parentheses change it for the text that follows.
  • Common spelling mistakes are corrected before the text is spoken, and prices and percentages are read the local way: 2500 دج becomes «خمسة وعشرين مية دينار».
  • French and English words are pronounced the way a local speaker says them.
  • Tashkeel in the text is respected: a diacritized word is pronounced as written.

​Several voice-overs at once

One key can have up to 20 voice-overs running at the same time. A voice-over runs until its audio is ready or it fails, even if your client stopped waiting for it. Once 20 are running, the next one gets 429 Rate limit exceeded: Concurrent request limit exceeded: retry when one of them has ended. See Rate Limits.

Each running voice-over also sets its price aside from your API credit until it's charged (when it succeeds) or fails (nothing is charged). A voice-over that arrives while others run is refused with 402 INSUFFICIENT_CREDIT when what's left after them can't cover it. The balance in that 402 is your API credit less what the others have set aside. See Insufficient API credit.

Errors

StatusErrorWhen
400text is requiredStudio format without text, or with only spaces.
400Missing 'text' in request bodyInline format without text, or with only spaces.
400UNKNOWN_MODELmodel isn't one of the five models. The body lists the models you can use.
400UNKNOWN_VOICEStudio format with a voice that isn't one of the 30 voice IDs. The body lists the voices.
400Invalid voice ID: '<id>'Inline format with a voiceId that isn't one of the 30 voice IDs.
400EMPTY_TEXTtext has nothing to speak, such as a text made only of tone directions.
400Max 5000 words exceededtext is over 5,000 words, tone directions included, in either format. The body has words and maxWords.
400TEXT_TOO_LONGtext is longer than twice its billable characters plus 1,000: too much of it is tone directions, spaces or invisible characters. The body has chars and maxChars.
401Missing API key. Pass it as 'Authorization: Bearer sk_live_...'The request has no key.
401Invalid or inactive API keyThe key is wrong, switched off or deleted.
402INSUFFICIENT_CREDITYour API credit, less what your other running voice-overs have set aside, can't cover the request. The body has required and balance.
403Account deactivatedThe account that owns the key is deactivated or suspended.
403API_ACCESS_BLOCKED (in code)API access is switched off for the account.
429Rate limit exceeded: RPM limit exceeded or Rate limit exceeded: Daily limit exceededYour key's requests per minute or per day.
429Rate limit exceeded: Concurrent request limit exceededYour key already has 20 voice-overs running. Retry when one of them ends.
500Internal server error processing TTS requestInline format: the voice-over couldn't be generated. Retry. Nothing was charged.
500Server errorStudio format: something went wrong on our side, such as reading or charging your API credit. Retry. Nothing was charged.
502Failed to generate audio. No points consumed.Studio format: the voice-over couldn't be generated. Retry. Nothing was charged.
503MODEL_DISABLED (in code)The model is paused for the API. The body names it in model. Use another model.
503TOOL_DISABLED (in code)Voice-overs through the API are paused. Retry later.
503MAINTENANCE (in code)The API is down for maintenance. Retry later.

See Errors for the full list.

Was this page helpful?