ElevenLabs Dialogue v3
elevenlabs-dialogue-v3Multi-speaker conversational ad script synthesis with natural interruptions, laughs and breaths
https://vidlab.ai/v1/generationsSend "model": "elevenlabs-dialogue-v3" and the fields below. The call answers 202 at once with the generation's id; poll it for the file. Billed per 1,000 characters of text, only when it succeeds.
curl -X POST https://vidlab.ai/v1/generations \
-H "Authorization: Bearer $VIDLAB_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"model": "elevenlabs-dialogue-v3",
"input": {
"text": "Fresh coffee, delivered before you wake up."
}
}'import os
import uuid
import requests
response = requests.post(
"https://vidlab.ai/v1/generations",
headers={
"Authorization": f"Bearer {os.environ['VIDLAB_API_KEY']}",
"Idempotency-Key": str(uuid.uuid4()),
},
json={
"model": "elevenlabs-dialogue-v3",
"input": {
"text": "Fresh coffee, delivered before you wake up.",
},
},
)
response.raise_for_status()
generation = response.json()["data"]
print(generation["id"], generation["status"])const response = await fetch("https://vidlab.ai/v1/generations", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.VIDLAB_API_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": crypto.randomUUID(),
},
body: JSON.stringify({
model: "elevenlabs-dialogue-v3",
input: {
text: "Fresh coffee, delivered before you wake up.",
},
}),
});
if (!response.ok) throw new Error((await response.json()).error.message);
const { data: generation } = await response.json();
console.dir(generation);package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
)
func main() {
body, _ := json.Marshal(map[string]any{
"model": "elevenlabs-dialogue-v3",
"input": map[string]any{
"text": "Fresh coffee, delivered before you wake up.",
},
})
req, _ := http.NewRequest("POST", "https://vidlab.ai/v1/generations", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("VIDLAB_API_KEY"))
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.StatusCode, string(out))
}import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.UUID;
public class Main {
public static void main(String[] args) throws Exception {
String body = """
{
"model": "elevenlabs-dialogue-v3",
"input": {
"text": "Fresh coffee, delivered before you wake up."
}
}
""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://vidlab.ai/v1/generations"))
.header("Authorization", "Bearer " + System.getenv("VIDLAB_API_KEY"))
.header("Content-Type", "application/json")
.header("Idempotency-Key", UUID.randomUUID().toString())
.POST(HttpRequest.BodyPublishers.ofString(body))
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode() + " " + response.body());
}
}<?php
$body = [
'model' => 'elevenlabs-dialogue-v3',
'input' => [
'text' => 'Fresh coffee, delivered before you wake up.',
],
];
$ch = curl_init('https://vidlab.ai/v1/generations');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('VIDLAB_API_KEY'),
'Content-Type: application/json',
'Idempotency-Key: ' . bin2hex(random_bytes(16)),
],
CURLOPT_POSTFIELDS => json_encode($body),
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;using System.Net.Http.Headers;
using System.Text;
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", Environment.GetEnvironmentVariable("VIDLAB_API_KEY"));
client.DefaultRequestHeaders.Add("Idempotency-Key", Guid.NewGuid().ToString());
var body = """
{
"model": "elevenlabs-dialogue-v3",
"input": {
"text": "Fresh coffee, delivered before you wake up."
}
}
""";
var response = await client.PostAsync("https://vidlab.ai/v1/generations",
new StringContent(body, Encoding.UTF8, "application/json"));
Console.WriteLine($"{(int)response.StatusCode} {await response.Content.ReadAsStringAsync()}");{
"model": "elevenlabs-dialogue-v3",
"input": {
"text": "Fresh coffee, delivered before you wake up."
}
}{
"data": {
"id": "gen_4Fq9xT2mLr7Kd1sV8bN3pZ0c",
"object": "generation",
"status": "queued",
"model": "elevenlabs-dialogue-v3",
"variant": "*",
"units": 1,
"price_usd": 0.09,
"outputs": [],
"created_at": "2026-11-01T18:04:11.000Z",
"status_url": "/v1/generations/gen_4Fq9xT2mLr7Kd1sV8bN3pZ0c",
"result_url": "/v1/jobs/gen_4Fq9xT2mLr7Kd1sV8bN3pZ0c/result"
}
}{
"data": {
"id": "gen_4Fq9xT2mLr7Kd1sV8bN3pZ0c",
"object": "generation",
"status": "succeeded",
"model": "elevenlabs-dialogue-v3",
"variant": "*",
"units": 1,
"price_usd": 0.09,
"outputs": [
{
"url": "https://vidlab.ai/v1/generations/gen_4Fq9xT2mLr7Kd1sV8bN3pZ0c/content",
"mime": "audio/mpeg"
}
],
"created_at": "2026-11-01T18:04:11.000Z",
"finished_at": "2026-11-01T18:06:02.000Z"
}
}{
"error": {
"message": "`text` is required.",
"type": "invalid_request_error",
"code": "invalid_input"
}
}{
"error": {
"message": "The API key is missing, invalid, revoked, or not authorized. Send it as Authorization: Bearer <key>.",
"type": "authentication_error",
"code": "unauthorized"
}
}{
"error": {
"message": "The API wallet does not have room for this generation. Add credit to the API wallet, or wait for running generations to finish.",
"type": "rate_limit_error",
"code": "api_wallet_exhausted"
}
}{
"error": {
"message": "This model is busy right now. Try again shortly.",
"type": "service_unavailable_error",
"code": "model_unavailable"
}
}Headers
| Header | Type | Required | Value |
|---|---|---|---|
Authorization | string | required | Bearer vidlab_sk_..., your API key from the dashboard. |
Content-Type | string | required | application/json |
Idempotency-Key | string | optional | 8 to 100 letters, digits or _ : . - (a UUID is fine). A retry with the same key never starts or charges twice. |
No key yet? Make one under API keys. Keep it on your server, never in a browser or an app.
Body
| Field | Type | Required | Default | Allowed |
|---|---|---|---|---|
model | string | required | None | Must be elevenlabs-dialogue-v3 |
input | object | required | None | The fields below. |
max_cost_usd | number | optional | None | Dollars The most you will pay. Over it, the call answers 422 and nothing is held. Submit a generation |
max_wait_s | number | optional | None | Seconds The longest you will wait. |
Input
The fields of input for text to speech. A field the model does not take is refused, never ignored. Files are https links or base64 data URLs; upload a file from your machine first.
| Field | Type | Required | Default | Allowed |
|---|---|---|---|---|
text | string | required | None | Up to 20,000 characters Text to speak, for voice models. |
voice | string | optional | None | A voice id or name A voice id or name, for voice models. |
Pricing
Billed per 1,000 characters of text. A failed generation is free. The example costs $0.09 (*, 1 1,000 characters). Check any request for free with POST /v1/generations/quote.
| Option | Price | Billed |
|---|---|---|
* Any options | $0.09 | per 1,000 characters of text |
Response
202 with the generation (status: "queued"), its price, and where to poll it. The fields are on Generation object.
Get the result
https://vidlab.ai/v1/generations/{id}Poll every few seconds until status is succeeded or failed. outputs[].url is the file, on our storage; download it with your key from GET /v1/generations/{id}/content. See Get the result.
curl https://vidlab.ai/v1/generations/gen_4Fq9xT2mLr7Kd1sV8bN3pZ0c \
-H "Authorization: Bearer $VIDLAB_API_KEY"import os
import requests
response = requests.get(
"https://vidlab.ai/v1/generations/gen_4Fq9xT2mLr7Kd1sV8bN3pZ0c",
headers={"Authorization": f"Bearer {os.environ['VIDLAB_API_KEY']}"},
)
print(response.json()["data"]["status"])const response = await fetch("https://vidlab.ai/v1/generations/gen_4Fq9xT2mLr7Kd1sV8bN3pZ0c", {
headers: { Authorization: `Bearer ${process.env.VIDLAB_API_KEY}` },
});
const { data } = await response.json();
console.log(data.status, data.outputs);Errors
Every error is { "error": { "message", "type", "code" } } and nothing is held. All codes are on Errors.
| Status | Code | When |
|---|---|---|
| 400 | invalid_input | A field this model does not take, a value that is not allowed, or a required field left out. The message names it. |
| 401 | unauthorized | The key is missing, unknown or revoked. |
| 422 | max_cost_exceeded | No route can run the call for max_cost_usd or less. Nothing is held. |
| 429 | api_wallet_exhausted | The balance has no room for this price. Add credit. |
| 429 | request_per_minute | This key started too many generations this minute. Wait for Retry-After. |
| 503 | model_unavailable | The model is busy right now. Retry after Retry-After. |