curl --request POST \
--url https://restapi.deepdub.ai/api/v1/tts \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"model": "dd-etts-3.0",
"targetText": "Hello world, welcome to Deepdub.",
"locale": "en-US",
"voicePromptId": "bd1b00bb-be1c-4679-8eaa-0fcbfd4ff773"
}
'import requests
url = "https://restapi.deepdub.ai/api/v1/tts"
payload = {
"model": "dd-etts-3.0",
"targetText": "Hello world, welcome to Deepdub.",
"locale": "en-US",
"voicePromptId": "bd1b00bb-be1c-4679-8eaa-0fcbfd4ff773"
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
model: 'dd-etts-3.0',
targetText: 'Hello world, welcome to Deepdub.',
locale: 'en-US',
voicePromptId: 'bd1b00bb-be1c-4679-8eaa-0fcbfd4ff773'
})
};
fetch('https://restapi.deepdub.ai/api/v1/tts', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://restapi.deepdub.ai/api/v1/tts",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'model' => 'dd-etts-3.0',
'targetText' => 'Hello world, welcome to Deepdub.',
'locale' => 'en-US',
'voicePromptId' => 'bd1b00bb-be1c-4679-8eaa-0fcbfd4ff773'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://restapi.deepdub.ai/api/v1/tts"
payload := strings.NewReader("{\n \"model\": \"dd-etts-3.0\",\n \"targetText\": \"Hello world, welcome to Deepdub.\",\n \"locale\": \"en-US\",\n \"voicePromptId\": \"bd1b00bb-be1c-4679-8eaa-0fcbfd4ff773\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://restapi.deepdub.ai/api/v1/tts")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"dd-etts-3.0\",\n \"targetText\": \"Hello world, welcome to Deepdub.\",\n \"locale\": \"en-US\",\n \"voicePromptId\": \"bd1b00bb-be1c-4679-8eaa-0fcbfd4ff773\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://restapi.deepdub.ai/api/v1/tts")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"model\": \"dd-etts-3.0\",\n \"targetText\": \"Hello world, welcome to Deepdub.\",\n \"locale\": \"en-US\",\n \"voicePromptId\": \"bd1b00bb-be1c-4679-8eaa-0fcbfd4ff773\"\n}"
response = http.request(request)
puts response.read_body{
"success": false,
"message": "Invalid request: missing required field 'targetText'"
}{
"success": false,
"message": "Unauthorized: invalid or missing API key"
}{
"success": false,
"message": "InsufficientCredits: your account has no remaining credits"
}{
"success": false,
"message": "Max generation minutes allowed reached"
}{
"success": false,
"message": "Voice prompt `bd1b00bb-be1c-4679-8eaa-0fcbfd4ff773` does not exist"
}{
"success": false,
"message": "RateLimit: concurrent request limit exceeded"
}{
"success": false,
"message": "Internal server error"
}Generate and stream TTS audio
Generate and stream TTS audio based on the provided text. Returns an audio stream in the specified format (default MP3). Supported formats: mp3, opus, mulaw. For wav or s16le output, use the WebSocket API.
curl --request POST \
--url https://restapi.deepdub.ai/api/v1/tts \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"model": "dd-etts-3.0",
"targetText": "Hello world, welcome to Deepdub.",
"locale": "en-US",
"voicePromptId": "bd1b00bb-be1c-4679-8eaa-0fcbfd4ff773"
}
'import requests
url = "https://restapi.deepdub.ai/api/v1/tts"
payload = {
"model": "dd-etts-3.0",
"targetText": "Hello world, welcome to Deepdub.",
"locale": "en-US",
"voicePromptId": "bd1b00bb-be1c-4679-8eaa-0fcbfd4ff773"
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
model: 'dd-etts-3.0',
targetText: 'Hello world, welcome to Deepdub.',
locale: 'en-US',
voicePromptId: 'bd1b00bb-be1c-4679-8eaa-0fcbfd4ff773'
})
};
fetch('https://restapi.deepdub.ai/api/v1/tts', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://restapi.deepdub.ai/api/v1/tts",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'model' => 'dd-etts-3.0',
'targetText' => 'Hello world, welcome to Deepdub.',
'locale' => 'en-US',
'voicePromptId' => 'bd1b00bb-be1c-4679-8eaa-0fcbfd4ff773'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://restapi.deepdub.ai/api/v1/tts"
payload := strings.NewReader("{\n \"model\": \"dd-etts-3.0\",\n \"targetText\": \"Hello world, welcome to Deepdub.\",\n \"locale\": \"en-US\",\n \"voicePromptId\": \"bd1b00bb-be1c-4679-8eaa-0fcbfd4ff773\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://restapi.deepdub.ai/api/v1/tts")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"dd-etts-3.0\",\n \"targetText\": \"Hello world, welcome to Deepdub.\",\n \"locale\": \"en-US\",\n \"voicePromptId\": \"bd1b00bb-be1c-4679-8eaa-0fcbfd4ff773\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://restapi.deepdub.ai/api/v1/tts")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"model\": \"dd-etts-3.0\",\n \"targetText\": \"Hello world, welcome to Deepdub.\",\n \"locale\": \"en-US\",\n \"voicePromptId\": \"bd1b00bb-be1c-4679-8eaa-0fcbfd4ff773\"\n}"
response = http.request(request)
puts response.read_body{
"success": false,
"message": "Invalid request: missing required field 'targetText'"
}{
"success": false,
"message": "Unauthorized: invalid or missing API key"
}{
"success": false,
"message": "InsufficientCredits: your account has no remaining credits"
}{
"success": false,
"message": "Max generation minutes allowed reached"
}{
"success": false,
"message": "Voice prompt `bd1b00bb-be1c-4679-8eaa-0fcbfd4ff773` does not exist"
}{
"success": false,
"message": "RateLimit: concurrent request limit exceeded"
}{
"success": false,
"message": "Internal server error"
}Supported languages
| Language | Locale code |
|---|---|
| Arabic (Lebanon) | ar-LB |
| Arabic (Qatar) | ar-QA |
| Arabic (Saudi) | ar-SA |
| Arabic (Standard) | ar-SA |
| Arabic (Syrian) | ar-SY |
| Czech (Standard) | cs-CZ |
| Danish (Standard) | da-DK |
| Dutch (Netherlands) | nl-NL |
| English (Generic) | en-GB |
| English (Standard) | en-AU |
| English (United States) | en-US |
| Estonian (Standard) | et-EE |
| Finnish (Standard) | fi-FI |
| French (Standard) | fr-FR |
| German (Standard) | de-DE |
| Greek (Standard) | el-GR |
| Hebrew (Standard) | he-IL |
| Hindi (Standard) | hi-IN |
| Hungarian (Standard) | hu-HU |
| Indonesian (Standard) | id-ID |
| Italian (Standard) | it-IT |
| Japanese (Standard) | ja-JP |
| Korean (Standard) | ko-KR |
| Macedonian (Standard) | mk-MK |
| Norwegian (Standard) | nb-NO |
| Polish (Standard) | pl-PL |
| Portuguese (Brazil) | pt-BR |
| Romanian (Standard) | ro-RO |
| Russian (Standard) | ru-RU |
| Spanish (Latam) | es-419 |
| Spanish (Latam — Mexico) | es-MX |
| Spanish (Standard) | es-ES |
| Swedish (Standard) | sv-SE |
| Tamil (Standard) | ta-IN |
| Thai (Standard) | th-TH |
| Turkish (Standard) | tr-TR |
Model-specific parameters
seed applies to dd-etts-1.1 only. Newer models — including the default dd-etts-3.0 — do not use it, and setting it has no effect on their output. Do not rely on it to reproduce a generation on any model other than dd-etts-1.1.Supported output formats
The REST API streams audio as raw bytes in the HTTP response body. Supported formats:| Format | Description |
|---|---|
mp3 | Compressed audio, smallest file size. Default. |
opus | High-quality compressed audio, efficient for streaming. |
mulaw | 8-bit µ-law encoding, commonly used in telephony. Defaults to 8000 Hz if no sample rate is specified. |
mp3, opus, and mulaw only. For wav or s16le output, use the Streaming Out API.Sample rates
Valid values are8000, 16000, 22050, 24000, 32000, 36000, 44100, and 48000 Hz; any other value is rejected with a 400. The internal generation runs at 48 kHz and is resampled to the requested rate. If no sample rate is specified, mulaw defaults to 8000 Hz.
Generation ID
Every successful response carries anx-generation-id header identifying the generation. Keep it — it is what you quote when reporting a problem with the audio.
REST vs WebSocket comparison
| Feature | REST API | Streaming Out API |
|---|---|---|
| Delivery | Streaming HTTP response (chunked audio bytes) | Chunked audio delivered incrementally as base64-encoded JSON messages |
| Formats | mp3, opus, mulaw | wav (default), mp3, opus, mulaw, s16le |
| Text streamed in | No | No — use Streaming In and Streaming Out |
| Default format | mp3 | wav |
| Default mulaw sample rate | 8000 Hz | 8000 Hz |
| Best for | Simple integrations, file generation | Real-time playback, low-latency applications |
Authorizations
API key for authentication. Must start with dd- prefix.
Headers
API Key
Body
Request structure for TTS generation endpoints.
Optional parameters (not shown in playground): generationId (string), targetDuration (number, seconds — mutually exclusive with tempo), tempo (number, 0–2 — mutually exclusive with targetDuration), variance (number, 0.0–1.0), temperature (number, 0.0–1.0), sampleRate (integer: 8000, 16000, 22050, 24000, 32000, 36000, 44100 or 48000), format (string: mp3/opus/mulaw — default mp3), promptBoost (boolean), superStretch (boolean), realtime (boolean), cleanAudio (boolean, default false on REST), autoGain (boolean, default true on REST), publish (boolean), accentControl (object with accentBaseLocale, accentLocale, accentRatio), performanceReferencePromptId (string), voiceReference (string, base64-encoded audio), targetGender (string: male/female — used for language-specific handling such as Hebrew diacritics; other values are ignored).
Model ID to use for generation
"dd-etts-3.0"
Text to be converted to speech
"Hello world, welcome to Deepdub."
Language locale code (e.g., en-US, fr-FR)
"en-US"
ID of the voice prompt to use for generation
"bd1b00bb-be1c-4679-8eaa-0fcbfd4ff773"
Random seed for deterministic generation. Applies to dd-etts-1.1 only — newer models do not use it, and setting it has no effect on their output.
42
Response
Audio stream in the requested format (MP3, Opus, or mulaw depending on format parameter). The response body is raw audio bytes.
