Перейти к содержанию

Синтез речи — TTS v1

POST /api/tts/v1 преобразует текст в аудио выбранным голосом. Метод поддерживает обычный и потоковый ответ, несколько выходных форматов, встроенные и пользовательские голоса. Для ручной сборки длинной озвучки используйте TTS Studio.

HTTP-запрос

POST /api/tts/v1
Authorization: Api-Key <ключ>
Content-Type: application/x-www-form-urlencoded

Поля формы можно отправлять как application/x-www-form-urlencoded или multipart/form-data. Оба варианта используют одинаковый контракт. Требования к ключу описаны в разделе Аутентификация.

Параметры запроса

Параметр Тип Обязательный По умолчанию Описание
text string да* Текст для синтеза, до 5000 символов вместе с разметкой
ssml string да* Поддерживаемый SpeechKit-like поднабор для Higgs, до 5000 символов; это не полный стандарт SSML
voice string нет Идентификатор из GET /voices; передавайте существующий голос явно
lang string нет ru-RU Поле совместимости; фактическая поддержка языка зависит от голоса и провайдера
speed string/number нет 1.0 Скорость от 0.1 до 3.0
emotion string нет Эмоциональная подача; поддержка и значения зависят от провайдера
format string нет wav wav, lpcm, oggopus, mp3 или amr
sampleRateHertz string/number нет 48000 8000, 16000 или 48000 Гц
bit_resolution string/number нет 16 8 или 16 бит
audio_channels string нет stereo mono или stereo
pcm_format string нет LINEAR16 LINEAR16 или MULAW; используйте с wav/lpcm, MULAW возвращается в WAV-контейнере
stream string/bool нет false Потоковая отдача: true, 1, yes или false, 0, no

* Укажите ровно одно поле: text или ssml. Если передать оба поля или не передать ни одного, сервер вернёт 400.

Формат AMR

AMR-NB рассчитан на 8 кГц и один канал. Для телефонии явно передавайте sampleRateHertz=8000 и audio_channels=mono.

Всегда выбирайте голос

Поле voice оставлено необязательным для совместимости, но fallback без голоса зависит от конфигурации развёртывания. Получите список через GET /api/tts/v1/voices и передавайте выбранный name.

pcm_format=MULAW не следует сочетать с MP3, OGG Opus или AMR. Для стандартного телефонного WAV используйте format=wav, sampleRateHertz=8000, audio_channels=mono и pcm_format=MULAW.

Ответ

Сервер возвращает бинарное аудио с заголовком Content-Disposition: attachment.

format Content-Type Имя файла
wav, lpcm audio/wav synthesized.wav
mp3 audio/mpeg synthesized.mp3
oggopus audio/ogg synthesized.ogg
amr audio/amr synthesized.amr

Стоимость рассчитывается по длительности сгенерированной речи до выходной конвертации с округлением вверх до целой секунды: формат, частота и число каналов цену не меняют. Для streaming сервер сначала проверяет баланс по оценочной длительности, а после завершения фиксирует фактическую. Для обычного ответа баланс проверяется после синтеза, когда известна фактическая длительность. Актуальный тариф показывается в кабинете.

Примеры

curl -X POST "https://api.speech.example.com/api/tts/v1" \
  -H "Authorization: Api-Key $API_KEY" \
  --data-urlencode "text=Привет, мир!" \
  --data-urlencode "voice=elena-speech-expert-tts" \
  --data-urlencode "format=wav" \
  --output speech.wav
curl -X POST "https://api.speech.example.com/api/tts/v1" \
  -H "Authorization: Api-Key $API_KEY" \
  --form-string "text=Медленная речь" \
  --form-string "voice=elena-speech-expert-tts" \
  --form-string "speed=0.7" \
  --form-string "audio_channels=mono" \
  --form-string "sampleRateHertz=16000" \
  --output speech.wav
from pathlib import Path

import requests

response = requests.post(
    "https://api.speech.example.com/api/tts/v1",
    headers={"Authorization": "Api-Key <ваш-ключ>"},
    data={
        "text": "Привет, мир!",
        "voice": "elena-speech-expert-tts",
        "format": "mp3",
    },
    timeout=120,
)
response.raise_for_status()
Path("speech.mp3").write_bytes(response.content)

Потоковый ответ

stream=true начинает отдавать аудио по мере генерации. Потоковый режим доступен только для голосов с provider: "higgs"; для другого провайдера сервер вернёт 400.

curl --no-buffer -X POST "https://api.speech.example.com/api/tts/v1" \
  -H "Authorization: Api-Key $API_KEY" \
  --data-urlencode "text=Привет, это потоковый синтез." \
  --data-urlencode "voice=elena-speech-expert-tts" \
  --data-urlencode "format=oggopus" \
  --data-urlencode "stream=true" \
  --output speech.ogg

WAV, MP3, OGG Opus и AMR кодируются через ffmpeg без накопления всего результата в памяти. Длительность и окончательное списание фиксируются после завершения ответа. Для воспроизведения потока до его окончания удобнее MP3 или OGG Opus: некоторые проигрыватели ожидают завершённый WAV-контейнер.

Разметка Higgs

Голоса с provider: "higgs" понимают аудиотеги, доступные и в панели Быстрого синтеза. Теги можно передать в text напрямую.

Глобальная подача

Следующие теги задают подачу всей реплики:

Категория Теги
Эмоция <|emotion:elation|>, <|emotion:anger|>, <|emotion:determination|>, <|emotion:affection|>
Манера <|style:whispering|>
Выразительность <|prosody:expressive_low|>, <|prosody:expressive_high|>
Темп <|prosody:speed_very_slow|>, <|prosody:speed_slow|>, <|prosody:speed_fast|>, <|prosody:speed_very_fast|>
Высота <|prosody:pitch_low|>, <|prosody:pitch_high|>

При подготовке запроса сервер переносит в начало реплики по одному тегу каждого типа: emotion, style, speed, pitch и expressive. Если тег одного типа встречается несколько раз, действует последний. Поэтому pitch_high, speed_*, emotion:* и другие глобальные теги нельзя надёжно применять только к слову внутри предложения.

Для Higgs числовой параметр speed выбирает ближайшую категорию: 0.65very_slow, 0.85slow, 1.0 — обычный темп, 1.2fast, 1.4very_fast. Тег темпа внутри текста имеет приоритет. Параметр emotion принимает совместимые роли good/happy, evil/angry, strict, friendly и whisper; neutral и calm не добавляют отдельный тег.

Паузы и смысловой акцент

Паузы остаются в том месте, где были добавлены:

Тег Назначение
<|prosody:pause|> Короткая пауза
<|prosody:long_pause|> Длинная пауза

Самый стабильный способ смыслового выделения слова — короткие паузы с двух сторон:

Мы запускаем <|prosody:pause|>сегодня<|prosody:pause|>, после обеда.

Именно такую разметку добавляет кнопка Смысловой акцент в TTS Studio. Она влияет на ритм и длительность слова, а не на его высоту.

Лексическое ударение

Чтобы подсказать ударную гласную, поставьте + непосредственно перед ней:

В договоре нужно позвон+ить завтра.

Для Higgs сервер преобразует такую запись в символ ударения Unicode. Лексическое ударение и смысловой акцент решают разные задачи и могут использоваться вместе.

Звуковые события

В интерфейсе доступны следующие сочетания тега и звукоподражания:

<|sfx:laughter|>Haha
<|sfx:sigh|>Uh
<|sfx:cough|>Ahem
<|sfx:humming|>Hmm
<|sfx:sneeze|>Achoo

Используйте SFX-тег вместе с указанным звукоподражанием: оно помогает модели произнести соответствующее звуковое событие.

Разметка отключает LLM-нормализацию

Если вход содержит <|...|> или <speak>, сервер не запускает автоматическую LLM-нормализацию всей реплики. Записывайте числа, даты и сокращения в том виде, в котором они должны прозвучать. Все теги учитываются в лимите 5000 символов.

SSML для Higgs

Higgs поддерживает совместимый поднабор SSML, а не весь стандарт. Основные преобразования:

Разметка Поведение
<speak>...</speak> Внешний контейнер удаляется
<sub alias="...">...</sub> Произносится значение alias
<break time="400ms"/> Короткая пауза; от 700 мс — длинная
<break strength="strong"/> weak, medium, strong, x-strong преобразуются в паузу
</p> Длинная пауза между абзацами
<emotion value="happy">...</emotion> Глобальная эмоция; также доступны good, angry, evil, strict, friendly, whisper
<speed value="0.8"> Ближайшая поддерживаемая категория темпа
<pitch value="high"> Глобальный pitch_high; значение low задаёт pitch_low
<pause value="800ms"/> Пауза в указанном месте

Неизвестные HTML/SSML-теги удаляются. Перед production-использованием проверьте звучание на выбранном голосе.

Список голосов

GET /api/tts/v1/voices
Authorization: Api-Key <ключ>

Метод возвращает встроенные голоса текущей конфигурации и готовые пользовательские голоса владельца ключа.

[
  {
    "name": "elena-speech-expert-tts",
    "label": "Елена (SpeechExpert-TTS)",
    "provider": "higgs"
  },
  {
    "name": "user-voice-a1b2c3d4e5f60718",
    "label": "Мой голос (мой)",
    "provider": "higgs",
    "is_custom": true
  }
]
Поле Описание
name Стабильный идентификатор для параметра voice
label Отображаемое название
provider Бэкенд голоса, например higgs, speech-expert-tts, qwen-tts, f5 или elevenlabs
is_custom true только для пользовательского голоса

Состав и порядок встроенных голосов зависят от конфигурации сервера. Не зашивайте список в клиенте — загружайте его этим методом.

Пользовательские голоса

В веб-интерфейсе голос создаётся кнопкой Добавить свой голос. Подробный сценарий описан в разделе TTS Studio.

Для управления из кабинета доступны методы с аутентификацией portal-cookie:

Метод Назначение
GET /api/account/tts-voices Список собственных голосов
POST /api/account/tts-voices Создать голос из multipart-полей audio, необязательных name и lang
DELETE /api/account/tts-voices/{id} Удалить голос и его референс

При создании сервер берёт не более первых 19 секунд, приводит референс к PCM16 WAV, mono, 24 кГц и автоматически распознаёт его текст. Идентификатор для синтеза находится в поле name ответа; UUID для удаления — в поле id.

Portal-cookie и API-ключ

Методы /api/account/tts-voices предназначены для авторизованного кабинета и не принимают API-ключ вместо portal-cookie. Готовый голос после создания доступен в /api/tts/v1/voices и может использоваться с API-ключом того же пользователя.

Ограничения

Параметр Значение
Максимальная длина text или ssml 5000 символов вместе с разметкой
Диапазон speed От 0.1 до 3.0
Потоковый режим Только голоса Higgs
Загрузка референса пользовательского голоса До 200 МиБ по умолчанию
Максимальный референс пользовательского голоса Первые 19 секунд загруженной записи по умолчанию

Ошибки

Ошибки возвращаются в JSON с полем detail.

Код Когда возникает
400 Нет текста, переданы и text, и ssml, превышен лимит, неверны параметры, не удалась конвертация или голос не поддерживает streaming
401 Отсутствует или неверен API-ключ
402 Недостаточно кредитов
500 Ошибка синтеза или таймаут TTS-бэкенда

См. также