API429 / Text to speech

Fish Audio Pro API: каталог голосов и озвучка текста

Для Fish Audio Pro используйте model=fish-s2.1-pro в POST /v1/audio/speech и обязательный идентификатор voice. Сначала выберите доступный голос через GET /v1/audio/voices, затем выполните один небольшой запрос и проверьте полученный аудиофайл.

Студийный микрофон с поп-фильтром, наушники и дикторский текст
Редакционная фотоиллюстрация к Fish Audio S2.1 Pro API: микрофон и подготовленный текст для синтеза речи.По теме: Синтез речи через API · Gemini TTS и 30 голосов · Цены ElevenLabs · Справочник API

Проверка клиентского контракта: . Точный ID: fish-s2.1-pro. Опубликованная модель: проверяйте точный ID и доступ вашего ключа.

Точный ID и проверка доступа

Fish Audio Pro в этой инструкции означает конкретную опубликованную модель fish-s2.1-pro. Маркетинговое название, версия из документации производителя и ID другого сервиса не являются взаимозаменяемыми значениями model. Скопируйте точную строку и проверьте наличие в GET /v1/models со своим ключом.

В публичном каталоге эта запись сейчас может находиться в категории text. Это не инструкция отправлять её в Chat Completions: для описанного клиентского контракта используются точный документированный ID, метод /v1/audio/speech и ставка символов TTS. Руководство не меняет глобальные категории каталога.

Начните с короткого текста, который представляет вашу задачу: например, реплики справочника или фрагмента дикторского сценария. Отдельно проверьте доступ к модели и голосу. Наличие записи без авторизации не подтверждает права конкретного ключа. Перед выполнением запроса проверьте его доступ и текущие условия оплаты.

Каталог голосов Fish: поиск и страницы

Запросите GET /v1/audio/voices с model=fish-s2.1-pro. Параметры language=ru и q=narrator помогают сузить поиск; limit=5 и offset=0 задают первую страницу. Это параметры каталога Fish: не используйте этот метод для получения фиксированных имён Gemini.

Ответ имеет object=list, model, total, offset и массив data. В каждой записи доступны id, name, languages, tags, description и другие документированные поля. Сопоставляйте язык и описание с собственной задачей, а идентификатор берите из id; название записи не заменяет значение voice.

Для следующей страницы увеличьте offset с учётом числа полученных элементов и total. Если нужны собственные голоса, предусмотрен необязательный scope=mine. Пустой результат поиска не доказывает отсутствие модели или всех русскоязычных голосов: проверьте фильтры и доступ вашего ключа, прежде чем менять конфигурацию.

Поле voice обязательно

Публичный ID голоса содержит 32 шестнадцатеричных символа. Идентификатор приватного клона имеет форму voice_ и те же 32 символа. В примере значение передаётся через API429_VOICE_ID и проверяется до сетевого запроса; случайная строка или имя Kore для Fish не подходят.

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

Не публикуйте персональные данные владельца голоса вместе с журналом запроса. Храните выбранный ID как настройку приложения и разделяйте его с API-ключом. После изменения голоса снова прослушайте характерный фрагмент: одинаковый текст может потребовать другой расстановки пауз или написания специальных терминов.

Форматы ответа и пример WAV

Клиентская документация перечисляет mp3 по умолчанию, а также wav, pcm и opus. Для длинного текста opus не поддерживается; не выбирайте его для такой задачи. В первом примере явно задан response_format=wav, чтобы расширение файла и ожидаемый контейнер не зависели от формата по умолчанию.

Проверьте HTTP-статус, получите полное тело и убедитесь, что это корректный WAV с сигнатурами RIFF и WAVE. В отличие от отдельного контракта Gemini, здесь не следует заранее приписывать ответу частоту 24 кГц или один канал. Пример читает фактические параметры из заголовка файла.

Не сохраняйте JSON-ошибку под расширением .wav и не передавайте неполное тело проигрывателю как готовый результат. Если нужен MP3, создайте отдельный запрос с документированным форматом и проверяйте его соответствующим способом. Повторное выполнение Python-файла создаёт новую платную попытку, поэтому сначала разберите предыдущую.

Символы TTS и стоимость серии

Ниже показана свежая ставка API429 за опубликованное число символов TTS. Для Fish здесь проверяется именно этот показатель, а не входные или выходные токены текстовой модели. Категория записи сама по себе не должна превращать стоимость синтеза речи в стоимость чата.

В прямом API Fish встречаются расчёты по UTF-8 байтам. Байты, символы и минуты речи — разные единицы: кириллица и латиница не дают универсального коэффициента пересчёта. Это руководство не объявляет тариф производителя тарифом API429 и не вычисляет процент экономии из несопоставимых величин.

При подготовке серии сначала оцените объём исходного текста в единицах действующего тарифа, учтите возможные повторные попытки и проверьте небольшой пример по фактическому списанию. Если каталог недоступен, устарел или содержит неоднозначную ставку, числовая цена скрывается. Перед увеличением нагрузки повторно проверьте условия.

Найти голос Fish Audio Pro

Пример чтения первой страницы каталога. Он не создаёт озвучку. Перед синтезом возьмите точный id выбранной записи и задайте API429_VOICE_ID в окружении сервера.

curl --fail-with-body --get 'https://gateway.api429.com/v1/audio/voices' \
  -H "Authorization: Bearer $API429_API_KEY" \
  --data-urlencode 'model=fish-s2.1-pro' \
  --data-urlencode 'language=ru' \
  --data-urlencode 'q=narrator' \
  --data-urlencode 'limit=5' \
  --data-urlencode 'offset=0'

Оболочка ответа: object: list, model, total, offset, data. Список элементов содержит id, name, languages, tags и description. Для собственных голосов добавьте фильтр scope=mine.

Текущие ставки API429

USD, стандартный публичный тариф. Каждая строка сохраняет свою единицу; входные токены и символы TTS нельзя складывать как одинаковые величины.

  • $0.00450000 / 1 000 символов TTS

Дата каталога: . Свежая публикация не гарантирует доступ конкретного ключа.

Пример запроса на Python: одна попытка и проверка WAV

Запускайте на сервере с Python 3.10+ и стандартной библиотекой. Установите API429_API_KEY и API429_VOICE_ID через защищённое окружение. Выполнение сначала проверяет доступ через GET /v1/models, затем отправляет один платный POST /v1/audio/speech. Автоматических повторов нет.

import io, json, os, re, struct, urllib.request, wave
from pathlib import Path

BASE = "https://gateway.api429.com/v1"
MODEL = "fish-s2.1-pro"
KEY = os.environ["API429_API_KEY"]
VOICE = os.environ["API429_VOICE_ID"]
if not re.fullmatch(r"(?:voice_)?[0-9a-fA-F]{32}", VOICE):
    raise ValueError("Invalid API429_VOICE_ID")
headers = {"Authorization": "Bearer " + KEY}

# Verify access with the same key before one paid speech request.
request = urllib.request.Request(BASE + "/models", headers=headers)
with urllib.request.urlopen(request, timeout=30) as response:
    models = json.load(response)
if not isinstance(models, dict) or not isinstance(models.get("data"), list):
    raise ValueError("Invalid models response")
if not any(isinstance(m, dict) and m.get("id") == MODEL for m in models["data"]):
    raise ValueError("Requested model is not available to this key")

payload = {"model": MODEL, "input": "Здравствуйте! Это пример текста для озвучки.", "voice": VOICE, "response_format": "wav"}
request = urllib.request.Request(
    BASE + "/audio/speech", data=json.dumps(payload).encode("utf-8"),
    headers={**headers, "Content-Type": "application/json"}, method="POST",
)
# Running this file again creates another paid attempt; no automatic retries.
with urllib.request.urlopen(request, timeout=180) as response:
    audio = response.read()
if len(audio) < 44 or audio[:4] != b"RIFF" or audio[8:12] != b"WAVE":
    raise ValueError("Expected complete WAV response")
if struct.unpack_from("<I", audio, 4)[0] + 8 != len(audio):
    raise ValueError("Incomplete RIFF body")
with wave.open(io.BytesIO(audio), "rb") as wav:
    if wav.getcomptype() != "NONE" or wav.getnframes() <= 0:
        raise ValueError("Expected non-empty PCM WAV")
    frames = wav.readframes(wav.getnframes())
    if len(frames) != wav.getnframes() * wav.getnchannels() * wav.getsampwidth():
        raise ValueError("Incomplete WAV audio data")
Path("speech.wav").write_bytes(audio)
print("Saved speech.wav")

Оплата и тест $10

  • Карта российского банка. Пополнение баланса в личном кабинете.
  • Счёт для юрлиц. Безналичная оплата с закрывающими документами.
  • USDT и TON. Пополнение криптовалютой.

Тест $10. Подпишитесь на наш Telegram-канал через бота — получите $10 на баланс для первых запросов. Получить $10 в боте

Частые вопросы

Какое значение model нужно для Fish Audio Pro?

В этом контракте используется fish-s2.1-pro. Проверьте этот точный ID через GET /v1/models с вашим ключом.

Можно не передавать voice?

Нет. Передайте публичный ID из 32 hex-символов или доступный приватный voice_<32hex>. Выберите голос через каталог Fish.

Почему в примере выбран WAV?

response_format=wav задаёт контейнер явно. Пример проверяет целостность RIFF/WAVE и читает реальные параметры, не приписывая Fish параметры PCM модели Gemini.

Можно считать цену минуты по цене символов?

Без конкретного текста и темпа речи — нет. Используйте текущую ставку символов TTS и фактическое списание; UTF-8 байты прямого API производителя являются другой единицей.

Продолжить подключение

Источники и границы проверки

Параметры API429 берутся из клиентской документации. Каталог определяет опубликованные ID и единицы тарификации. Материалы производителей дают контекст моделей и голосов, но не доказывают поддержку всех их возможностей через API429 или доступ вашего ключа.

Telegram