Контракт сверен . Опубликовано ; обновлено . Проверены публичные источники и примеры с искусственными ответами. Успешное платное выполнение под клиентским ключом здесь не заявляется.
Выбор пути: голос и формат результата
Используйте eleven_v4, когда у вас уже есть подтверждённый допустимый voice ID для запроса ElevenLabs. Пример не подставляет выдуманный голос по умолчанию: значение API429_VOICE_ID должно быть задано отдельно. Название голоса в другом сервисе не доказывает его доступность здесь. Возможность клонирования голоса, перенос чужой библиотеки и права на конкретный голос этими примерами не устанавливаются.
Для gemini-3.1-flash-tts-preview публичный клиентский справочник показывает голоса Kore и Puck. Пример явно выбирает Kore и короткий текст. Этот ID опубликован в каталоге как preview; статус предварительной версии следует учитывать при выборе для продукта. Наличие строки в публичном каталоге не заменяет проверку GET /v1/models под вашим ключом и не является подтверждением выполненного синтеза.
Первый короткий запрос на сервере
Оба пути используют POST /v1/audio/speech, поля model и input, а также явно выбранный voice. Ключ берётся из окружения серверного процесса. Не помещайте его в клиентский код сайта и не отправляйте вместе с текстом в общие журналы. Перед синтезом примеры читают каталог ключа и останавливаются, если точная модель недоступна. Сам запрос генерации платный, поэтому запускайте только выбранный вариант.
Для ElevenLabs указан response_format=mp3. У Gemini параметр response_format намеренно опущен: справочник устанавливает WAV даже при другом запрошенном формате. Переименование WAV в speech.mp3 не выполняет преобразование. Если вашему приложению нужен другой контейнер, предусмотрите отдельное преобразование проверенного файла и собственную проверку результата, а не предположение о поведении модели.
Как проверить WAV и MP3 перед сохранением
Для ElevenLabs сначала проверьте успешный HTTP-ответ и Content-Type audio/mpeg либо audio/mp3. Пример проверяет непустое тело и сохраняет speech.mp3; затем прослушайте короткую запись и подтвердите пригодность голоса. Серверный MIME не является оценкой произношения, громкости или пауз: эти критерии проверяются отдельно на целевом языке и тексте.
Для Gemini ожидается бинарный WAV: audio/wav, RIFF/WAVE, PCM 16 бит, один канал, частота 24 000 Гц. Отдельный пример разбирает WAV и проверяет непустые звуковые кадры до сохранения speech.wav. JSON ошибки, MP3 либо пустой WAV останавливают выполнение. Не используйте для него MP3-сохранение из примера ElevenLabs. Сначала проверьте короткую фразу, затем решайте, подходит ли путь для вашего проигрывателя и процесса подготовки аудио.
Длина текста, ошибки и единицы бюджета
Эффективный максимальный объём текста и длительность выхода через этот клиентский контракт здесь не установлены. Не переносите ограничения нативного API производителя на API429 по похожему имени модели. Для длинного текста сначала отдельно согласуйте требования и подтвердите поведение на разрешённом материале. Разбиение текста, склейка файлов и контроль границ предложений являются задачами вашего приложения, а не доказанными возможностями этого запроса.
Eleven V4 может показывать свежую ставку за указанное число символов, если каталог однозначен. Gemini TTS содержит разные метрики: такой набор не сводится здесь к одной цене за тысячу символов или минуту. Отсутствие расчёта не означает нулевую стоимость. При таймауте не повторяйте синтез автоматически: сохраните параметры без ключа и выясните состояние исходной попытки. Документированный формат и офлайн-проверка кода не заменяют выполнение под вашим ключом.
Проверенные ID и текущие единицы API429
Свежая публикация каталога, доступ вашего ключа и выполненная генерация — отдельные проверки. Список ниже ограничен рассмотренными ID. Ставки не сравнивают качество моделей и не включают неподтверждённые компоненты расчёта.
| Точный ID | Статус и единицы |
|---|---|
eleven_v4 | Опубликована в свежем каталоге $0.03000000 / 1 000 символов TTS |
gemini-3.1-flash-tts-preview | Предварительная версия (preview) Смешанные единицы TTS: итоговая ставка здесь не рассчитывается. |
Дата каталога: . Числовые ставки скрываются при устаревших, неоднозначных или неподтверждённых данных; внешние цены производителей здесь не приводятся.
Первый запрос: Python и JavaScript
Выберите один пример и запускайте его на сервере. Установите API429_API_KEY через защищённое окружение; для ElevenLabs также нужен подтверждённый API429_VOICE_ID. Код сначала проверяет доступ через GET /v1/models, затем выполняет один платный запрос. Повторный запуск файла создаёт новую попытку: сначала разберите предыдущую.
Eleven V4: подтверждённый голос → MP3
Python 3 — eleven_v4
import base64
import json
import os
import urllib.request
from pathlib import Path
key = os.environ["API429_API_KEY"]
base = "https://gateway.api429.com/v1"
headers = {"Authorization": "Bearer " + key, "Content-Type": "application/json"}
model = "eleven_v4"
with urllib.request.urlopen(urllib.request.Request(base + "/models", headers=headers), timeout=30) as response:
available = {item["id"] for item in json.load(response)["data"]}
if model not in available:
raise ValueError("Model unavailable to this key")
payload = json.loads("{\"model\":\"eleven_v4\",\"input\":\"Здравствуйте. Это короткая проверка синтеза речи.\",\"voice\":\"YOUR_VOICE_ID\",\"response_format\":\"mp3\"}")
payload["voice"] = os.environ["API429_VOICE_ID"]
if not payload["voice"] or payload["voice"] == "YOUR_VOICE_ID":
raise ValueError("Set a confirmed voice ID")
request = urllib.request.Request(base + "/audio/speech",
data=json.dumps(payload).encode("utf-8"), headers=headers, method="POST")
with urllib.request.urlopen(request, timeout=180) as response:
content_type = response.headers.get("Content-Type", "").split(";")[0].strip().lower()
if content_type not in ("audio/mpeg", "audio/mp3"):
raise ValueError("Expected MP3 MIME; inspect response before saving")
audio = response.read()
if not audio:
raise ValueError("Empty audio")
Path("speech.mp3").write_bytes(audio)JavaScript для Node.js — eleven_v4
import { writeFile } from "node:fs/promises";
const key = process.env.API429_API_KEY;
if (!key) throw new Error("Set API429_API_KEY");
const base = "https://gateway.api429.com/v1";
const headers = { Authorization: "Bearer " + key, "Content-Type": "application/json" };
const model = "eleven_v4";
const available = await fetch(base + "/models", { headers, signal: AbortSignal.timeout(30000) });
if (!available.ok) throw new Error("Models HTTP " + available.status);
if (!(await available.json()).data.some(item => item.id === model)) throw new Error("Model unavailable to this key");
const payload = {"model":"eleven_v4","input":"Здравствуйте. Это короткая проверка синтеза речи.","voice":"YOUR_VOICE_ID","response_format":"mp3"};
payload.voice = process.env.API429_VOICE_ID;
if (!payload.voice || payload.voice === "YOUR_VOICE_ID") throw new Error("Set a confirmed voice ID");
const response = await fetch(base + "/audio/speech", {
method: "POST", headers, body: JSON.stringify(payload), signal: AbortSignal.timeout(180000)
});
if (!response.ok) throw new Error("Generation HTTP " + response.status);
if (!["audio/mpeg", "audio/mp3"].includes((response.headers.get("content-type") || "").split(";")[0].trim().toLowerCase())) throw new Error("Expected MP3 MIME");
const bytes = Buffer.from(await response.arrayBuffer());
if (!bytes.length) throw new Error("Empty audio");
await writeFile("speech.mp3", bytes);Gemini TTS Preview: Kore → WAV
Python 3 — gemini-3.1-flash-tts-preview
import io
import json
import os
import urllib.request
import wave
from pathlib import Path
key = os.environ["API429_API_KEY"]
base = "https://gateway.api429.com/v1"
headers = {"Authorization": "Bearer " + key, "Content-Type": "application/json"}
model = "gemini-3.1-flash-tts-preview"
try:
with urllib.request.urlopen(urllib.request.Request(base + "/models", headers=headers), timeout=30) as response:
available = {item["id"] for item in json.load(response)["data"]}
except Exception:
raise ValueError("Invalid models response; stop before generation") from None
if model not in available:
raise ValueError("Model unavailable to this key")
payload = json.loads("{\"model\":\"gemini-3.1-flash-tts-preview\",\"voice\":\"Kore\",\"input\":\"Здравствуйте. Это короткая проверка синтеза речи.\"}")
request = urllib.request.Request(base + "/audio/speech", data=json.dumps(payload).encode("utf-8"), headers=headers, method="POST")
with urllib.request.urlopen(request, timeout=180) as response:
mime = response.headers.get("Content-Type", "").split(";")[0].strip().lower()
if mime != "audio/wav":
raise ValueError("Expected WAV MIME; stop before saving")
raw = response.read()
if len(raw) < 12 or int.from_bytes(raw[4:8], "little") + 8 != len(raw) or raw[:4] != b"RIFF" or raw[8:12] != b"WAVE":
raise ValueError("Expected RIFF/WAVE")
with wave.open(io.BytesIO(raw), "rb") as audio:
if (audio.getnchannels(), audio.getsampwidth(), audio.getframerate(), audio.getcomptype()) != (1, 2, 24000, "NONE"):
raise ValueError("Expected mono PCM16 WAV at 24 kHz")
frames = audio.getnframes()
if frames < 1 or len(audio.readframes(frames)) != frames * 2:
raise ValueError("Empty or truncated PCM frames")
Path("speech.wav").write_bytes(raw)JavaScript для Node.js — gemini-3.1-flash-tts-preview
import { writeFile } from "node:fs/promises";
const key = process.env.API429_API_KEY;
if (!key) throw new Error("Set API429_API_KEY");
const base = "https://gateway.api429.com/v1";
const headers = { Authorization: "Bearer " + key, "Content-Type": "application/json" };
const model = "gemini-3.1-flash-tts-preview";
const available = await fetch(base + "/models", { headers, signal: AbortSignal.timeout(30000) });
if (!available.ok) throw new Error("Models HTTP " + available.status);
let availableModels;
try { availableModels = await available.json(); }
catch { throw new Error("Invalid models response; stop before generation"); }
if (!Array.isArray(availableModels?.data)) throw new Error("Invalid models response; stop before generation");
if (!availableModels.data.some(item => item && item.id === model)) throw new Error("Model unavailable to this key");
const response = await fetch(base + "/audio/speech", {
method: "POST", headers, body: JSON.stringify({"model":"gemini-3.1-flash-tts-preview","voice":"Kore","input":"Здравствуйте. Это короткая проверка синтеза речи."}), signal: AbortSignal.timeout(180000)
});
if (!response.ok) throw new Error("Speech HTTP " + response.status);
if ((response.headers.get("content-type") || "").split(";")[0].trim().toLowerCase() !== "audio/wav") throw new Error("Expected WAV MIME");
const raw = Buffer.from(await response.arrayBuffer());
if (raw.length < 12 || raw.toString("ascii", 0, 4) !== "RIFF" || raw.toString("ascii", 8, 12) !== "WAVE" || raw.readUInt32LE(4) + 8 !== raw.length) throw new Error("Expected complete RIFF/WAVE");
let format = false, frames = false;
for (let offset = 12; offset + 8 <= raw.length;) {
const tag = raw.toString("ascii", offset, offset + 4), size = raw.readUInt32LE(offset + 4), start = offset + 8;
if (start + size > raw.length) throw new Error("Truncated WAV chunk");
if (tag === "fmt ") {
if (format || size < 16 || raw.readUInt16LE(start) !== 1 || raw.readUInt16LE(start + 2) !== 1 || raw.readUInt32LE(start + 4) !== 24000 || raw.readUInt32LE(start + 8) !== 48000 || raw.readUInt16LE(start + 12) !== 2 || raw.readUInt16LE(start + 14) !== 16) throw new Error("Expected mono PCM16 at 24 kHz");
format = true;
}
if (tag === "data") {
if (frames || !size || size % 2) throw new Error("Invalid PCM frames");
frames = true;
}
offset = start + size + size % 2;
}
if (!format || !frames) throw new Error("Missing WAV format or frames");
await writeFile("speech.wav", raw);Дальнейший маршрут
Оплата и тест $10
- Карта российского банка. Пополнение баланса в личном кабинете.
- Счёт для юрлиц. Безналичная оплата с закрывающими документами.
- USDT и TON. Пополнение криптовалютой.
Тест $10. Подпишитесь на наш Telegram-канал через бота — получите $10 на баланс для первых запросов. Получить $10 в боте
Частые вопросы
Почему Gemini сохраняется как WAV, а не MP3?
Публичный клиентский справочник устанавливает WAV для Gemini TTS независимо от response_format: PCM 16 бит, моно, 24 кГц. Пример опускает этот параметр, проверяет MIME и контейнер, затем сохраняет .wav.
Можно ли не указывать голос ElevenLabs?
Для данного примера нужен подтверждённый voice ID в API429_VOICE_ID. Заглушка YOUR_VOICE_ID отклоняется до платного запроса. Голоса Kore и Puck из примера Gemini не переносятся автоматически в ElevenLabs.
Каков максимальный размер текста?
Проверенного эффективного максимума через API429 для этого пути здесь нет. Начинайте с короткой фразы. Числа из нативного руководства производителя не являются установленными ограничениями клиентского метода.
Почему для Gemini нет одной цены TTS?
В каталоге у точного preview ID присутствуют смешанные единицы. Их назначение нельзя свести к одной итоговой цене без дополнительного контракта расчёта. Уточняйте применимые единицы перед оценкой рабочего объёма.
Источники и границы проверки
Клиентский справочник определяет параметры и ответы; каталог — опубликованные точные ID и единицы. Сокращённая OpenAPI не содержит всех разделов полного справочника. Анонимная сверка источников от не подтверждает права ключа или запуск генерации.