Аудио
Синтез речи
POST /api/v1/audio/speech — превращение текста в аудиопоток
POST
/
api
/
v1
/
audio
/
speech
Синтез речи
curl --request POST \
--url https://speshu.ai/api/v1/audio/speech \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "<string>",
"input": "<unknown>",
"voice": "<string>",
"speed": 123,
"instructions": "<string>",
"input_references": "<array>"
}
'import requests
url = "https://speshu.ai/api/v1/audio/speech"
payload = {
"model": "<string>",
"input": "<unknown>",
"voice": "<string>",
"speed": 123,
"instructions": "<string>",
"input_references": "<array>"
}
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({
model: '<string>',
input: '<unknown>',
voice: '<string>',
speed: 123,
instructions: '<string>',
input_references: '<array>'
})
};
fetch('https://speshu.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://speshu.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([
'model' => '<string>',
'input' => '<unknown>',
'voice' => '<string>',
'speed' => 123,
'instructions' => '<string>',
'input_references' => '<array>'
]),
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://speshu.ai/api/v1/audio/speech"
payload := strings.NewReader("{\n \"model\": \"<string>\",\n \"input\": \"<unknown>\",\n \"voice\": \"<string>\",\n \"speed\": 123,\n \"instructions\": \"<string>\",\n \"input_references\": \"<array>\"\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://speshu.ai/api/v1/audio/speech")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"<string>\",\n \"input\": \"<unknown>\",\n \"voice\": \"<string>\",\n \"speed\": 123,\n \"instructions\": \"<string>\",\n \"input_references\": \"<array>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://speshu.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 \"model\": \"<string>\",\n \"input\": \"<unknown>\",\n \"voice\": \"<string>\",\n \"speed\": 123,\n \"instructions\": \"<string>\",\n \"input_references\": \"<array>\"\n}"
response = http.request(request)
puts response.read_body"<string>"{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"param": "<string>",
"code": "invalid_request"
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"param": "<string>",
"code": "invalid_request"
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"param": "<string>",
"code": "invalid_request"
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"param": "<string>",
"code": "invalid_request"
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"param": "<string>",
"code": "invalid_request"
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"param": "<string>",
"code": "invalid_request"
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"param": "<string>",
"code": "invalid_request"
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"param": "<string>",
"code": "invalid_request"
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"param": "<string>",
"code": "invalid_request"
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"param": "<string>",
"code": "invalid_request"
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"param": "<string>",
"code": "invalid_request"
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"param": "<string>",
"code": "invalid_request"
}
}Эндпоинт превращает текст в речь и возвращает готовый аудиопоток. Работает с моделями из каталога
Ошибки приходят в конверте OpenAI — объект
GET /api/v1/models, у которых в capabilities есть значение "speech".
Минимальный запрос
Сначала получите идентификатор модели из каталога, отфильтровав его поcapabilities:
cURL
MODEL=$(curl -s https://speshu.ai/api/v1/models \
| jq -r '.data[] | select(.capabilities | index("speech")) | .id' \
| head -n 1)
curl https://speshu.ai/api/v1/audio/speech \
-H "Authorization: Bearer $SPESHU_API_KEY" \
-H "Content-Type: application/json" \
-d "{
\"model\": \"$MODEL\",
\"input\": \"Привет! Это синтез речи.\",
\"voice\": \"alloy\",
\"response_format\": \"mp3\"
}" --output speech.mp3
Идентификатор модели берите из
GET /api/v1/models и подставляйте как есть. Состав моделей меняется, поэтому в рабочем коде не зашивайте его литералом. Если передать идентификатор обычной текстовой модели или неизвестное значение, придёт 404 с кодом model_not_found.Поля запроса
| Поле | Тип | Описание |
|---|---|---|
model | string | Идентификатор модели из каталога с capabilities, содержащим "speech". Обязательно |
input | string или array | Текст для озвучки: строка или массив реплик. Обязательно |
voice | string | Голос озвучки. Необязательно — если модель не выбирает голос, провайдер возьмёт голос по умолчанию |
response_format | string | Формат ответа: pcm или mp3. Необязательно |
speed | number | Скорость речи. Необязательно |
instructions | string | Указание модели, как читать текст: темп, тон, акценты. Необязательно |
input_references | array | Референсы голоса для моделей, которые умеют клонировать голос по образцу. Необязательно |
Ответ
Ответ — бинарный аудиопоток, а не JSON. Тело ответа пишите в файл или передавайте дальше в плеер напрямую; разбирать его как JSON не нужно. Поляusage в ответе нет.
Формат потока определяется полем response_format запроса: pcm — сырые сэмплы без заголовков, mp3 — готовый аудиофайл.
Не проверяйте ответ через
response.json() или аналогичный парсер — он упадёт на бинарных данных. Признак ошибки не в теле: при неудаче API вместо аудиопотока отвечает JSON с конвертом ошибки и соответствующим кодом состояния HTTP.Стоимость
Списание идёт за символы входного текста; для моделей с токенной тарификацией — по оценке входных токенов. Поляusage в ответе нет — списанную сумму проверяйте после вызова через GET /api/v1/balance.
Проверки перед вызовом
Часть ошибок возвращается до обращения к модели:| Ситуация | Ответ |
|---|---|
| Нет ключа или ключ недействителен | 401 invalid_api_key |
| Модель не из списка моделей синтеза речи | 404 model_not_found |
| Не хватает денег | 402 insufficient_quota |
Нет model или input, неверный response_format | 400 invalid_request |
error с полями message, type, param и code. Полная таблица кодов — на странице Ошибки.
Что дальше
Распознавание речи
Текст из аудиозаписи
Каталог моделей
Фильтр по capabilities и цены моделей
Баланс
Остаток кошелька по валютам
Ошибки
Полная таблица кодов
Авторизации
API-ключ в формате sk-.... Альтернативно — заголовок X-Api-Key: sk-... (совместимо с Anthropic SDK).
Тело
application/json
Идентификатор модели из GET /api/v1/models: у неё в capabilities есть значение "speech". Передаётся как есть.
Текст для озвучки: строка или массив реплик.
Голос озвучки.
Формат ответа: pcm — сырые сэмплы, mp3 — готовый файл.
Доступные опции:
pcm, mp3 Скорость речи. Необязательно.
Указание, как читать текст: темп, тон, акценты. Необязательно.
Референсы голоса для моделей с клонированием голоса. Необязательно.
Ответ
Бинарный аудиопоток формата response_format; тело не является JSON.
The response is of type file.
⌘I
Синтез речи
curl --request POST \
--url https://speshu.ai/api/v1/audio/speech \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "<string>",
"input": "<unknown>",
"voice": "<string>",
"speed": 123,
"instructions": "<string>",
"input_references": "<array>"
}
'import requests
url = "https://speshu.ai/api/v1/audio/speech"
payload = {
"model": "<string>",
"input": "<unknown>",
"voice": "<string>",
"speed": 123,
"instructions": "<string>",
"input_references": "<array>"
}
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({
model: '<string>',
input: '<unknown>',
voice: '<string>',
speed: 123,
instructions: '<string>',
input_references: '<array>'
})
};
fetch('https://speshu.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://speshu.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([
'model' => '<string>',
'input' => '<unknown>',
'voice' => '<string>',
'speed' => 123,
'instructions' => '<string>',
'input_references' => '<array>'
]),
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://speshu.ai/api/v1/audio/speech"
payload := strings.NewReader("{\n \"model\": \"<string>\",\n \"input\": \"<unknown>\",\n \"voice\": \"<string>\",\n \"speed\": 123,\n \"instructions\": \"<string>\",\n \"input_references\": \"<array>\"\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://speshu.ai/api/v1/audio/speech")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"<string>\",\n \"input\": \"<unknown>\",\n \"voice\": \"<string>\",\n \"speed\": 123,\n \"instructions\": \"<string>\",\n \"input_references\": \"<array>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://speshu.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 \"model\": \"<string>\",\n \"input\": \"<unknown>\",\n \"voice\": \"<string>\",\n \"speed\": 123,\n \"instructions\": \"<string>\",\n \"input_references\": \"<array>\"\n}"
response = http.request(request)
puts response.read_body"<string>"{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"param": "<string>",
"code": "invalid_request"
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"param": "<string>",
"code": "invalid_request"
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"param": "<string>",
"code": "invalid_request"
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"param": "<string>",
"code": "invalid_request"
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"param": "<string>",
"code": "invalid_request"
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"param": "<string>",
"code": "invalid_request"
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"param": "<string>",
"code": "invalid_request"
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"param": "<string>",
"code": "invalid_request"
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"param": "<string>",
"code": "invalid_request"
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"param": "<string>",
"code": "invalid_request"
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"param": "<string>",
"code": "invalid_request"
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"param": "<string>",
"code": "invalid_request"
}
}