curl --request POST \
--url https://openrouter.ai/api/v1/audio/speech \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"input": "Hello world",
"model": "mistralai/voxtral-mini-tts-2603",
"response_format": "pcm",
"speed": 1,
"voice": "en_paul_neutral"
}
'import requests
url = "https://openrouter.ai/api/v1/audio/speech"
payload = {
"input": "Hello world",
"model": "mistralai/voxtral-mini-tts-2603",
"response_format": "pcm",
"speed": 1,
"voice": "en_paul_neutral"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
input: 'Hello world',
model: 'mistralai/voxtral-mini-tts-2603',
response_format: 'pcm',
speed: 1,
voice: 'en_paul_neutral'
})
};
fetch('https://openrouter.ai/api/v1/audio/speech', 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://openrouter.ai/api/v1/audio/speech",
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([
'input' => 'Hello world',
'model' => 'mistralai/voxtral-mini-tts-2603',
'response_format' => 'pcm',
'speed' => 1,
'voice' => 'en_paul_neutral'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$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://openrouter.ai/api/v1/audio/speech"
payload := strings.NewReader("{\n \"input\": \"Hello world\",\n \"model\": \"mistralai/voxtral-mini-tts-2603\",\n \"response_format\": \"pcm\",\n \"speed\": 1,\n \"voice\": \"en_paul_neutral\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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://openrouter.ai/api/v1/audio/speech")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"input\": \"Hello world\",\n \"model\": \"mistralai/voxtral-mini-tts-2603\",\n \"response_format\": \"pcm\",\n \"speed\": 1,\n \"voice\": \"en_paul_neutral\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://openrouter.ai/api/v1/audio/speech")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"input\": \"Hello world\",\n \"model\": \"mistralai/voxtral-mini-tts-2603\",\n \"response_format\": \"pcm\",\n \"speed\": 1,\n \"voice\": \"en_paul_neutral\"\n}"
response = http.request(request)
puts response.read_body"<binary audio data>"{
"error": {
"code": 400,
"message": "Invalid request parameters"
}
}{
"error": {
"code": 401,
"message": "Missing Authentication header"
}
}{
"error": {
"code": 402,
"message": "Insufficient credits. Add more using https://openrouter.ai/credits"
}
}{
"error": {
"code": 403,
"message": "Only management keys can perform this operation"
}
}{
"error": {
"code": 404,
"message": "Resource not found"
}
}{
"error": {
"code": 413,
"message": "Request payload too large"
}
}{
"error": {
"code": 429,
"message": "Rate limit exceeded"
}
}{
"error": {
"code": 500,
"message": "Internal Server Error"
}
}{
"error": {
"code": 502,
"message": "Provider returned error"
}
}{
"error": {
"code": 503,
"message": "Service temporarily unavailable"
}
}{
"error": {
"code": 524,
"message": "Request timed out. Please try again later."
}
}{
"error": {
"code": 529,
"message": "Provider returned error"
}
}Create speech
Synthesizes audio from the input text. Returns a raw audio bytestream in the requested format (e.g. mp3, pcm, wav).
curl --request POST \
--url https://openrouter.ai/api/v1/audio/speech \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"input": "Hello world",
"model": "mistralai/voxtral-mini-tts-2603",
"response_format": "pcm",
"speed": 1,
"voice": "en_paul_neutral"
}
'import requests
url = "https://openrouter.ai/api/v1/audio/speech"
payload = {
"input": "Hello world",
"model": "mistralai/voxtral-mini-tts-2603",
"response_format": "pcm",
"speed": 1,
"voice": "en_paul_neutral"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
input: 'Hello world',
model: 'mistralai/voxtral-mini-tts-2603',
response_format: 'pcm',
speed: 1,
voice: 'en_paul_neutral'
})
};
fetch('https://openrouter.ai/api/v1/audio/speech', 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://openrouter.ai/api/v1/audio/speech",
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([
'input' => 'Hello world',
'model' => 'mistralai/voxtral-mini-tts-2603',
'response_format' => 'pcm',
'speed' => 1,
'voice' => 'en_paul_neutral'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$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://openrouter.ai/api/v1/audio/speech"
payload := strings.NewReader("{\n \"input\": \"Hello world\",\n \"model\": \"mistralai/voxtral-mini-tts-2603\",\n \"response_format\": \"pcm\",\n \"speed\": 1,\n \"voice\": \"en_paul_neutral\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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://openrouter.ai/api/v1/audio/speech")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"input\": \"Hello world\",\n \"model\": \"mistralai/voxtral-mini-tts-2603\",\n \"response_format\": \"pcm\",\n \"speed\": 1,\n \"voice\": \"en_paul_neutral\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://openrouter.ai/api/v1/audio/speech")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"input\": \"Hello world\",\n \"model\": \"mistralai/voxtral-mini-tts-2603\",\n \"response_format\": \"pcm\",\n \"speed\": 1,\n \"voice\": \"en_paul_neutral\"\n}"
response = http.request(request)
puts response.read_body"<binary audio data>"{
"error": {
"code": 400,
"message": "Invalid request parameters"
}
}{
"error": {
"code": 401,
"message": "Missing Authentication header"
}
}{
"error": {
"code": 402,
"message": "Insufficient credits. Add more using https://openrouter.ai/credits"
}
}{
"error": {
"code": 403,
"message": "Only management keys can perform this operation"
}
}{
"error": {
"code": 404,
"message": "Resource not found"
}
}{
"error": {
"code": 413,
"message": "Request payload too large"
}
}{
"error": {
"code": 429,
"message": "Rate limit exceeded"
}
}{
"error": {
"code": 500,
"message": "Internal Server Error"
}
}{
"error": {
"code": 502,
"message": "Provider returned error"
}
}{
"error": {
"code": 503,
"message": "Service temporarily unavailable"
}
}{
"error": {
"code": 524,
"message": "Request timed out. Please try again later."
}
}{
"error": {
"code": 529,
"message": "Provider returned error"
}
}Authorizations
API key as bearer token in Authorization header
Body
Text-to-speech request input
Text to synthesize
"Hello world"
TTS model identifier
"mistralai/voxtral-mini-tts-2603"
Reference content for stateless voice cloning or voice design. Audio mode: one to three input_audio parts, each optionally paired with a text part carrying its transcript (a single clip accepts its transcript before or after it; with multiple clips each transcript immediately follows its clip); only routed to endpoints that support voice cloning (and multiple references when more than one part is sent). Image mode: exactly one image_url part; only routed to endpoints that support image references. The two modes cannot be mixed. An empty array is treated as no reference.
Reference content part for stateless voice cloning or voice design
- Option 1
- Option 2
- Option 3
Show child attributes
Show child attributes
{
"input_audio": {
"data": "data:audio/wav;base64,UklGRuQXDABXQVZF..."
},
"type": "input_audio"
}
[
{
"input_audio": {
"data": "data:audio/wav;base64,UklGRuQXDABXQVZF..."
},
"type": "input_audio"
},
{
"text": "I used to rule the world.",
"type": "text"
}
]
Provider-specific passthrough configuration
Show child attributes
Show child attributes
Audio output format
mp3, pcm "pcm"
A unique identifier for grouping related requests (e.g., a conversation or agent workflow). Used for observability grouping in Broadcast and private logging; never sent to the provider. If provided in both the request body and the x-session-id header, the body value takes precedence. Maximum of 256 characters.
256"session-1234"
Playback speed multiplier. Only used by models that support it (e.g. OpenAI TTS). Ignored by other providers.
1
Metadata for observability and tracing. Known keys (trace_id, trace_name, span_name, generation_name, parent_span_id) have special handling. Additional keys are passed through as custom metadata to configured broadcast destinations.
Show child attributes
Show child attributes
{
"trace_id": "trace-abc123",
"trace_name": "my-app-trace"
}
A unique identifier representing your end-user. Forwarded to Broadcast and private logging as the end-user id; never sent to the provider.
256"user-1234"
Voice identifier (provider-specific).
1"en_paul_neutral"
Response
Audio bytes stream
Raw audio bytestream. Content-Type varies by requested format (audio/mpeg for mp3, audio/pcm for pcm — 16-bit little-endian).