Синтез речи, транскрипция и анализ аудио через единый REST API. Ключ – в заголовке, результат – бинарный аудиофайл или JSON.
Открыть Swagger (OpenAPI)rtt_… в кабинете.X-Api-Key каждого запроса.https://ttsapi.ru.curl -X POST https://ttsapi.ru/v1/synthesize \
-H "Content-Type: application/json" \
-H "X-Api-Key: rtt_…" \
-d '{"text":"Привет, мир!","voice":"preset_anna","format":"mp3"}' \
--output hello.mp3
Все эндпоинты /v1/* (кроме каталога голосов) требуют API-ключ в заголовке X-Api-Key.
X-Api-Key: rtt_…
Также поддерживаются Authorization: Bearer rtt_… и X-RapidAPI-Key для интеграции через RapidAPI.
Ключи создаются и управляются в кабинете (`/account`). После создания ключ показывается один раз – скопируйте его сразу. Каждому ключу можно задать имя, срок действия, области доступа и собственные месячные лимиты.
Scope ограничивает, какие эндпоинты доступны конкретному ключу. По умолчанию ключ создаётся без ограничений (все области); тарифные ограничения продолжают действовать отдельно.
| Scope | Описание |
|---|---|
synthesis | /v1/synthesize, /v1/synthesize/stream, /v1/batch/synthesize |
transcription | /v1/transcribe, /v1/transcribe/sync, /v1/transcribe/{jobId}, /v1/transcribe/{jobId}/subtitles, /v1/transcribe/{jobId}/translate, /v1/audio/clean, /v1/recordings, /v1/recordings/from-link, /v1/recordings/{id}/* (speakers, transcript, export, share), /v1/eval, /v1/qa/*, /v1/meetings/protocol, /v1/search, /v1/ask |
analysis | /v1/analyze, /v1/analyze/sync, /v1/analyze/{jobId}, /v1/detect-language, /v1/redact, /v1/analyze/topics, /v1/analyze/summarize, /v1/moderate, /v1/batch/analyze |
voices | /v1/voices/clone, /v1/voices/clone/{id} |
voiceid | /v1/voice-id, /v1/voice-id/enroll, /v1/voice-id/verify, /v1/voice-id/identify, /v1/voice-id/profiles |
effects | /v1/audio/effects, /v1/video/effects (включая опрос и скачивание результата) |
Пустой набор областей означает «без ограничений» – так ведут себя ключи, созданные до появления scopes. При отсутствии требуемой области API возвращает `403`.
Ключу можно задать срок действия и три месячных лимита сверх квоты тарифа: символы синтеза, секунды транскрипции и запросы анализа. Истёкший или отозванный ключ перестаёт аутентифицироваться (`401`). При превышении поключевого лимита возвращается `403 quota_exceeded`.
Расход символов, секунд транскрипции и запросов анализа учитывается отдельно по каждому ключу и отображается в кабинете и админке – удобно выдавать отдельным интеграциям собственные квоты.
Создание, переименование и отзыв – в кабинете (`/account/keys`). Количество одновременно активных ключей ограничено тарифом (Free – 2, Basic – 5, Pro – 10, Business – 20). Администратор управляет ключами клиентов в админке.
POST /v1/synthesize принимает JSON и возвращает бинарный аудиофайл (mp3, wav или ogg).
| Поле | Тип | Описание |
|---|---|---|
text | string | Текст для озвучивания (до 5000 символов) |
voice | string | ID голоса, например preset_anna |
format | string | mp3 (по умолчанию), wav, ogg |
sample_rate | int | Частота дискретизации, например 24000 |
speed | float | Скорость речи (по умолчанию 1.0) |
language | string | Язык синтеза (по умолчанию – язык голоса): ru, en, zh, ja, ko, de, es, fr, it Если не указан, берётся язык голоса. |
put_accent | bool | Принимается для обратной совместимости и не влияет на синтез |
put_yo | bool | Восстановление буквы ё: принимается для обратной совместимости и не влияет на синтез |
normalize | bool | Числа прописью: принимается для обратной совместимости и не влияет на синтез — движок и так верно читает цифры |
lexicon | object | Словарь произношения: ключ – как написано в тексте, значение – как произносить. Подстановка по целому слову, без учёта регистра, до 200 записей. Пример: {"ООО": "общество с ограниченной ответственностью"} |
effects | string | Опциональная цепочка аудиоэффектов – JSON-строка с массивом дескрипторов. Требует план Pro или Business. |
Лексикон меняет только то, что слышит модель: квота считается по исходному тексту. Для SSML-запросов (ssml=true) он игнорируется.
Параметры put_accent, put_yo и normalize принимаются для обратной совместимости. Движок не потребляет ударения, сам верно читает цифры и не даёт навязать букву ё, поэтому на звук они не влияют. Для правильного произношения конкретных слов используйте lexicon.
Эффекты применяются к синтезированному аудио и кодируются в выбранный формат. Не поддерживается для потокового синтеза (/v1/synthesize/stream).
curl -X POST https://ttsapi.ru/v1/synthesize \
-H "Content-Type: application/json" \
-H "X-Api-Key: rtt_…" \
-d '{"text":"Добрый день!","voice":"preset_anna","format":"mp3"}' \
--output speech.mp3
# Аудиоэффекты (Pro/Business): реверберация + питч
curl -X POST https://ttsapi.ru/v1/synthesize \
-H "Content-Type: application/json" \
-H "X-Api-Key: rtt_…" \
-d '{"text":"Добрый день!","voice":"preset_anna","format":"mp3","effects":"[{\"type\":\"reverb\",\"room_size\":0.5},{\"type\":\"pitch\",\"semitones\":2}]"}' \
--output speech_fx.mp3
import httpx
response = httpx.post(
"https://ttsapi.ru/v1/synthesize",
headers={"X-Api-Key": "rtt_…"},
json={
"text": "Добрый день!",
"voice": "preset_anna",
"format": "mp3",
},
timeout=60.0,
)
response.raise_for_status()
with open("speech.mp3", "wb") as f:
f.write(response.content)
const response = await fetch("https://ttsapi.ru/v1/synthesize", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Api-Key": "rtt_…",
},
body: JSON.stringify({ text: "Добрый день!", voice: "preset_anna", format: "mp3" }),
});
if (!response.ok) throw new Error(await response.text());
const blob = await response.blob();
// Браузер: URL.createObjectURL(blob) → воспроизведение в теге audio
// Node.js: fs.writeFileSync("speech.mp3", Buffer.from(await blob.arrayBuffer()))
using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Post, "https://ttsapi.ru/v1/synthesize");
request.Headers.Add("X-Api-Key", "rtt_…");
request.Content = new StringContent(
"""{"text":"Добрый день!","voice":"preset_anna","format":"mp3"}""",
System.Text.Encoding.UTF8, "application/json");
using var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
await File.WriteAllBytesAsync("speech.mp3", await response.Content.ReadAsByteArrayAsync());
POST /v1/synthesize/stream отдаёт аудио чанками по мере генерации – воспроизведение начинается до окончания синтеза длинного текста. Доступно на тарифах Pro и Business; Free и Basic получают 403 streaming_forbidden.
Тело запроса совпадает с POST /v1/synthesize. Ответ – поток audio/mpeg без заголовка Content-Length: каждый чанк пишется в тело сразу после синтеза.
curl -X POST https://ttsapi.ru/v1/synthesize/stream \
-H "Content-Type: application/json" \
-H "X-Api-Key: rtt_…" \
-d '{"text":"Первое предложение. Второе предложение. Третье предложение.","voice":"preset_anna","format":"mp3"}' \
--no-buffer \
--output speech_stream.mp3
import httpx
with httpx.stream(
"POST",
"https://ttsapi.ru/v1/synthesize/stream",
headers={"X-Api-Key": "rtt_…"},
json={"text": "Первое предложение. Второе предложение.", "voice": "preset_anna", "format": "mp3"},
timeout=60.0,
) as response:
response.raise_for_status()
with open("speech_stream.mp3", "wb") as f:
for chunk in response.iter_bytes():
f.write(chunk)
MP3 стримится по предложениям (кадры MP3 конкатенируются корректно); WAV/OGG кодируются целиком и режутся на чанки, чтобы поток оставался валидным контейнером.
POST /v1/synthesize/async ставит длинный текст (аудиокнига / длинная статья) в очередь как фоновую задачу. Текст разбивается на абзацы, каждый синтезируется отдельно, затем склеивается в один WAV с точным таймкод-манифестом.
Опрашивайте `GET /v1/synthesize/async/{job_id}` для манифеста и скачивайте аудио через `GET /v1/synthesize/async/{job_id}/audio`. Передайте `webhookUrl`, чтобы получить уведомление о завершении.
Синтез длинных текстов возвращает WAV (PCM), чтобы таймкоды абзацев оставались сэмпл-точными.
| Поле | Тип | Описание |
|---|---|---|
text | string | Текст для озвучивания (до 5000 символов) |
voice | string | ID голоса, например preset_anna |
format | string | wav (по умолчанию), |
sample_rate | int | Частота дискретизации, например 24000 |
speed | float | Скорость речи (по умолчанию 1.0) |
language | string | Язык синтеза (по умолчанию – язык голоса): |
curl -X POST "https://ttsapi.ru/v1/synthesize/async" \
-H "Content-Type: application/json" \
-H "X-Api-Key: rtt_…" \
-d '{"text":"Глава первая. Абзац один.\n\nАбзац два.","voice":"preset_anna","format":"wav"}'
# → 202 { "job_id": "…", "status": "queued", "estimated_seconds": 12 }
# Результат
curl "https://ttsapi.ru/v1/synthesize/async/{job_id}" \
-H "X-Api-Key: rtt_…"
# → 200 { "job_id": "…", "status": "completed", "result": { "segments": [ … ], "duration_milliseconds": 18420, … } }
curl "https://ttsapi.ru/v1/synthesize/async/{job_id}/audio" \
-H "X-Api-Key: rtt_…" \
--output audiobook.wav
from voicekit import VoiceKitClient
client = VoiceKitClient(api_key="rtt_…")
job = client.synthesize_async("Глава первая…", voice="preset_anna", format="wav")
result = client.get_synthesis_job(job["job_id"])
while result["status"] not in ("completed", "failed"):
result = client.get_synthesis_job(job["job_id"])
audio = client.download_synthesis_audio(job["job_id"])
open("audiobook.wav", "wb").write(audio)
POST /v1/audio/effects применяет цепочку аудиоэффектов к загруженному файлу как фоновую задачу. Поддерживаются: reverb, compressor, eq, distortion, chorus, pitch, timestretch.
Опрашивайте `GET /v1/audio/effects/{job_id}` и скачивайте результат через `GET /v1/audio/effects/{job_id}/audio`. Передайте `webhookUrl`, чтобы получить уведомление.
| Поле | Тип | Описание |
|---|---|---|
audio | file | Аудиофайл (wav, mp3, ogg, flac до 25 МБ / 15 мин) (wav, mp3, ogg, flac) |
effects | string | JSON-строка: массив дескрипторов эффектов |
output_format | string | wav (по умолчанию), mp3, ogg |
curl -X POST https://ttsapi.ru/v1/audio/effects \
-H "X-Api-Key: rtt_…" \
-F "audio=@voice.mp3" \
-F 'effects=[{"type":"reverb","room_size":0.5},{"type":"pitch","semitones":2}]' \
-F "output_format=mp3"
# → 202 { "job_id": "…", "status": "queued" }
curl https://ttsapi.ru/v1/audio/effects/{job_id} -H "X-Api-Key: rtt_…"
# → 200 { "status": "completed", "result": { "format": "mp3", "duration_milliseconds": … } }
curl https://ttsapi.ru/v1/audio/effects/{job_id}/audio -H "X-Api-Key: rtt_…" --output result.mp3
POST /v1/video/effects применяет эффекты к видео (mode=mux) или к его аудио-дорожке (mode=audio) как фоновую задачу. В mux можно передать отдельный аудиофайл, который заменит аудио-дорожку.
Опрашивайте `GET /v1/video/effects/{job_id}` и скачивайте результат через `GET /v1/video/effects/{job_id}/file`.
| Поле | Тип | Описание |
|---|---|---|
video | file | Видеофайл (mp4, webm, …) |
audio | file | Опциональный аудиофайл для mode=mux |
effects | string | JSON-строка: массив дескрипторов эффектов |
mode | string | mux (по умолчанию), audio |
output_format | string | mp4, webm (mux) / wav, mp3, ogg (audio) |
curl -X POST https://ttsapi.ru/v1/video/effects \
-H "X-Api-Key: rtt_…" \
-F "video=@clip.mp4" \
-F 'effects=[{"type":"compressor","threshold_db":-18,"ratio":3}]' \
-F "mode=mux" \
-F "output_format=mp4"
# → 202 { "job_id": "…", "status": "queued" }
curl https://ttsapi.ru/v1/video/effects/{job_id}/file -H "X-Api-Key: rtt_…" --output result.mp4
POST /v1/audio/clean убирает фоновый шум и нормализует громкость загруженного файла как фоновую задачу. Без `options` применяется пресет «в один клик» (denoise + normalize).
Опрашивайте `GET /v1/audio/clean/{job_id}` и скачивайте результат через `GET /v1/audio/clean/{job_id}/audio`. Передайте `webhookUrl`, чтобы получить уведомление.
| Поле | Тип | Описание |
|---|---|---|
audio | file | Аудиофайл (wav, mp3, ogg, flac до 25 МБ / 15 мин) (wav, mp3, ogg, flac) |
options | string | JSON-строка с опциями: `denoise` (strength, stationary), `normalize` (target_db), `high_pass`, `low_pass`. Необязательно. |
output_format | string | wav (по умолчанию), mp3, ogg |
webhookUrl | string | URL для уведомления о готовности (query-параметр) |
curl -X POST https://ttsapi.ru/v1/audio/clean \
-H "X-Api-Key: rtt_…" \
-F "audio=@recording.mp3" \
-F 'options={"denoise":{"strength":0.8,"stationary":true},"normalize":{"target_db":-1.0}}' \
-F "output_format=wav"
# → 202 { "job_id": "…", "status": "queued" }
curl https://ttsapi.ru/v1/audio/clean/{job_id} -H "X-Api-Key: rtt_…"
# → 200 { "status": "completed", "result": { "format": "wav", "duration_milliseconds": … } }
curl https://ttsapi.ru/v1/audio/clean/{job_id}/audio -H "X-Api-Key: rtt_…" --output cleaned.wav
Очистку можно включить и как препроцессор: флаг `clean=true` в `/v1/transcribe`, `/v1/transcribe/sync`, `/v1/analyze`, `/v1/analyze/sync` и `/v1/voices/clone`.
GET /v1/voices возвращает список голосов без авторизации; GET /v1/voices/{id} – один голос.
Всего 29 preset-голосов (по умолчанию – Анна, `preset_anna`); доступны, например: preset_anna, preset_maksim, preset_pavel, preset_m01, preset_w01 …
curl https://ttsapi.ru/v1/voices
POST /v1/voices/clone создаёт клонированный голос из 1–3 образцов речи одного диктора. Возвращает `id`, который используется как `voice` вместе с `model=premium`.
Один образец: wav/mp3/ogg/flac/m4a/aac до 10 МБ, чистый голос без шума и музыки, плюс его транскрипт (prompt_text). Клонирование доступно на Basic (до 5 голосов), Pro (до 50) и Business (до 500). Премиум-пресеты доступны на Pro и Business.
Передайте `clean=true`, чтобы автоматически очистить (denoise + normalize) каждый образец перед клонированием. Тарифы Basic, Pro и Business.
curl -X POST https://ttsapi.ru/v1/voices/clone \
-H "X-Api-Key: rtt_…" \
-F "name=my_voice" \
-F "samples=@voice_1.wav" \
-F "samples=@voice_2.wav" \
-F "samples=@voice_3.wav"
# → 201 { "id": "clone_…", "name": "my_voice", "language": "ru",
# "sample_count": 3, "created_at": "…" }
# GET /v1/voices/clone
# GET /v1/voices/clone/{id}
# DELETE /v1/voices/clone/{id} # → 204
Используйте клонированный голос в POST /v1/synthesize и POST /v1/synthesize/stream:
curl -X POST https://ttsapi.ru/v1/synthesize \
-H "Content-Type: application/json" \
-H "X-Api-Key: rtt_…" \
-d '{"text":"Привет!","voice":"clone_…","model":"premium","format":"mp3"}'
Асинхронный POST /v1/transcribe принимает multipart/form-data и сразу возвращает job_id. Результат забирается опросом GET /v1/transcribe/{job_id}.
| Поле | Тип | Описание |
|---|---|---|
audio | file | Аудиофайл (wav, mp3, ogg, flac до 25 МБ / 15 мин) |
language | string | Код языка ISO 639-1 (например ru, en, de). Необязательный – если не указан, определяется автоматически. |
diarization | bool | Разделение спикеров (требует тариф с диаризацией) |
keyterms | string | Список терминов через запятую для точного распознавания (keyterm prompting) |
webhookUrl | string | URL для уведомления о готовности |
clean | bool | Сначала убрать шум и нормализовать громкость (`clean=true`). Тарифы Pro и Business. |
Поддерживаются коды языков (ISO 639-1): ru, en, de, es, fr, uk, kk, uz, zh и другие – всего модель Whisper поддерживает ~99 языков.
# Запуск задачи
curl -X POST https://ttsapi.ru/v1/transcribe \
-H "X-Api-Key: rtt_…" \
-F "audio=@meeting.mp3" \
-F "language=ru" \
-F "diarization=true"
# → 202 { "job_id": "…", "status": "queued" }
# Результат
curl https://ttsapi.ru/v1/transcribe/{job_id} \
-H "X-Api-Key: rtt_…"
Для коротких файлов (до 3 минут) есть синхронный вариант – POST /v1/transcribe/sync, возвращающий результат сразу.
Можно передать поле `keyterms` – список терминов через запятую: модель будет распознавать их точнее (keyterm prompting). Ответ `segments` теперь содержит по-словные таймкоды `words` (`word`, `start`, `end`, `confidence`).
GET /v1/transcribe/{job_id}/subtitles выгружает готовую транскрипцию как субтитры WebVTT или SubRip.
Параметр `format` – `vtt` (по умолчанию) или `srt`.
Если задача ещё не завершена, вернётся `409 subtitles_unavailable`.
Субтитры поддерживают target_language (перевод на лету) и hot_marks=true — пометки [fast]/[unclear] там, где спикер говорит слишком быстро или неразборчиво.
# VTT or SRT
curl -OJ "https://ttsapi.ru/v1/transcribe/{job_id}/subtitles?format=srt" \
-H "X-Api-Key: rtt_…"
# translated subtitles with hot marks
curl -OJ "https://ttsapi.ru/v1/transcribe/{job_id}/subtitles?format=vtt&target_language=en&hot_marks=true" \
-H "X-Api-Key: rtt_…"
POST /v1/transcribe/{job_id}/translate переводит готовый транскрипт по сегментам (таймкоды и спикеры сохраняются).
curl -X POST https://ttsapi.ru/v1/transcribe/{job_id}/translate \
-H "X-Api-Key: rtt_…" \
-H "Content-Type: application/json" \
-d '{"target_language": "en"}'
# → { "source_language": "ru", "target_language": "en", "transcript": "…",
# "segments": [ { "start": 0.0, "end": 2.1, "text": "…",
# "speaker": "SPEAKER_00", "confidence": 0.95 } ],
# "llm_model": "gpt-4o-mini" }
GET /v1/recordings список, скачивание, экспорт и публикация сохранённых записей клиента.
POST /v1/recordings/from-link начинает диаризованную транскрипцию по публичной ссылке на аудиофайл — сервер сам скачает файл и сохранит запись с источником link.
GET /v1/recordings/{id} возвращает метаданные одной записи; GET /v1/recordings/{id}/transcript возвращает полный транскрипт записи; DELETE /v1/recordings/{id} удаляет запись и её аудио.
PATCH /v1/recordings/{id} обновляет теги и папку записи (поле отсутствует — не меняется, null — очистить); GET /v1/recordings/tags отдают уникальные теги и папки клиента для автодополнения. GET /v1/recordings/folders
Ссылка открывает публичный плеер с синхронной подсветкой транскрипта; expires_in_seconds (по умолчанию 7 дней, максимум 30) и опциональный password.
# list recordings (filter/pagination + tags/folders)
curl "https://ttsapi.ru/v1/recordings?source=upload&tag=sales&folder=Q3&limit=20" -H "X-Api-Key: rtt_…"
# запуск транскрипции по публичной ссылке на аудио
curl -X POST https://ttsapi.ru/v1/recordings/from-link \
-H "X-Api-Key: rtt_…" -H "Content-Type: application/json" \
-d '{"url": "https://example.com/call.mp3", "language": "ru"}'
# → 202 { "job_id": "…", "status": "queued" }
# метаданные, транскрипт и удаление записи
curl https://ttsapi.ru/v1/recordings/{id} -H "X-Api-Key: rtt_…"
curl https://ttsapi.ru/v1/recordings/{id}/transcript -H "X-Api-Key: rtt_…"
curl -X DELETE https://ttsapi.ru/v1/recordings/{id} -H "X-Api-Key: rtt_…"
# tags & folder (PATCH semantics: null clears, absent = untouched)
curl -X PATCH https://ttsapi.ru/v1/recordings/{id} \
-H "X-Api-Key: rtt_…" -H "Content-Type: application/json" \
-d '{"tags": ["sales", "warm"], "folder": "Q3"}'
# → { "id": "…", "folder": "Q3", "tags": ["sales", "warm"] }
# distinct tags / folders (autocomplete)
curl https://ttsapi.ru/v1/recordings/tags -H "X-Api-Key: rtt_…"
curl https://ttsapi.ru/v1/recordings/folders -H "X-Api-Key: rtt_…"
# download the stored audio
curl -OJ https://ttsapi.ru/v1/recordings/{id}/audio -H "X-Api-Key: rtt_…"
# export the transcript (txt | md | srt | vtt | docx | pdf)
curl -OJ "https://ttsapi.ru/v1/recordings/{id}/export?format=pdf" -H "X-Api-Key: rtt_…"
# create a public share link (TTL + optional password)
curl -X POST https://ttsapi.ru/v1/recordings/{id}/share \
-H "X-Api-Key: rtt_…" -H "Content-Type: application/json" \
-d '{"expires_in_seconds": 86400, "password": "secret"}'
# → { "share_id": "…", "url": "https://ttsapi.ru/share/…",
# "password_required": true, "expires_at_utc": "…" }
# list / revoke shares
curl https://ttsapi.ru/v1/recordings/{id}/share -H "X-Api-Key: rtt_…"
curl -X DELETE https://ttsapi.ru/v1/recordings/{id}/share/{token} -H "X-Api-Key: rtt_…"
# the share URL opens a player with synced transcript highlighting:
# https://ttsapi.ru/share/{token}
POST /v1/eval распознаёт загруженное аудио и возвращает WER (word error rate) относительно эталонного текста.
Прогоняйте один эталон через разные голоса и настройки синтеза и сравнивайте по цифре. Тарифы Pro/Business; списываются секунды транскрипции.
# WER: how closely the speech matches the reference text
curl -X POST https://ttsapi.ru/v1/eval \
-H "X-Api-Key: rtt_…" \
-F "audio=@synthesis.wav" \
-F "reference=Здравствуйте, это сервис синтеза речи." \
-F "normalize=true"
# → { "wer": 0.15, "accuracy": 0.85, "hits": 10,
# "substitutions": 1, "insertions": 0, "deletions": 1,
# "reference_words": 12, "hypothesis_words": 13,
# "normalized_reference": "здравствуйте это сервис синтеза речи",
# "transcript": "Здравствуйте, это сервис синтеза речи.",
# "language": "ru", "duration_seconds": 2.6 }
WS /v1/transcribe/stream выполняет потоковую транскрипцию по WebSocket (тарифы Pro/Business). Отправляйте сырые PCM16-кадры (little-endian, mono, 16 кГц) бинарными сообщениями; сервер отвечает JSON-событиями: `session`, `vad`, `partial` и `final`.
Тарифы Free и Basic получают `403 streaming_forbidden`.
Аутентификация: ключ в query-строке `?api_key=…` или заголовке `X-Api-Key` (браузеры не задают заголовки при WS-хендшейке).
Клиент → сервер: бинарные PCM16-кадры (little-endian, mono, 16 кГц) и текстовый кадр `{"type":"stop"}` для финализации.
Сервер → клиент – JSON-события:
| Тип | Событие | Описание |
|---|---|---|
session | started / ended | Жизненный цикл сессии (+`session_id`, `audio_seconds`). |
vad | speech_started / speech_ended | Детекция речи: начало и конец фразы. |
partial | – | Промежуточный транскрипт во время речи. |
final | – | Финальный транскрипт завершённой фразы. |
error | – | Ошибка сессии (`quota_exceeded`, `stream_failed`). |
Параметры запроса: `language`, `keyterms` (через запятую), `interim=true|false`.
Квота списывается по переданному аудио (1 сек = 32 000 байт PCM16).
const ws = new WebSocket("wss://ttsapi.ru/v1/transcribe/stream?api_key=rtt_…&language=ru");
ws.binaryType = "arraybuffer";
ws.onmessage = (event) => console.log(JSON.parse(event.data));
ws.send(pcm16Bytes);
ws.send(JSON.stringify({ type: "stop" }));
import asyncio, json, websockets
async def main():
async with websockets.connect(
"wss://ttsapi.ru/v1/transcribe/stream?api_key=rtt_…"
) as ws:
await ws.send(open("speech.raw", "rb").read())
await ws.send(json.dumps({"type": "stop"}))
async for message in ws:
print(json.loads(message))
asyncio.run(main())
POST /v1/vad находит сегменты речи (Silero VAD) в загруженном аудио и возвращает их границы. WebSocket-вариант в реальном времени шлёт события `speech_started` / `speech_ended` – база для голосовых агентов.
curl -X POST https://ttsapi.ru/v1/vad \
-H "X-Api-Key: rtt_…" \
-F "audio=@meeting.mp3"
# → { "segments": [{"start": 0.1, "end": 2.4}, {"start": 3.0, "end": 5.2}],
# "speech_ratio": 0.68, "duration_seconds": 5.2, "processing_time_ms": 12 }
WS /v1/vad/stream– стриминговый turn detection: только VAD-события, без распознавания.
const ws = new WebSocket("wss://ttsapi.ru/v1/vad/stream?api_key=rtt_…");
ws.binaryType = "arraybuffer";
ws.onmessage = (event) => console.log(JSON.parse(event.data));
// ← {"type":"vad","event":"speech_started","start":1.20}
// ← {"type":"vad","event":"speech_ended","start":1.20,"end":4.85}
Приведение аудио к PCM16: `ffmpeg -i in.mp3 -ar 16000 -ac 1 -f s16le out.raw`.
Асинхронный POST /v1/analyze ставит задачу анализа в очередь и сразу возвращает job_id; результат забирается опросом GET /v1/analyze/{jobId}.
Для коротких файлов (до 3 минут) есть синхронный вариант — POST /v1/analyze/sync, возвращающий результат сразу.
Параметр language – код языка ISO 639-1 (например ru, en); если не указан, язык определяется автоматически. Поддерживаются коды языков (ISO 639-1).
Поле `keyterms` (через запятую) повышает точность распознавания доменных терминов.
Сначала убрать шум и нормализовать громкость (`clean=true`). Тарифы Pro и Business.
# # Запуск задачи
curl -X POST https://ttsapi.ru/v1/analyze \
-H "X-Api-Key: rtt_…" \
-F "audio=@call.mp3" \
-F "language=ru"
# → 202 { "job_id": "…", "status": "queued" }
# # Результат
curl https://ttsapi.ru/v1/analyze/{job_id} \
-H "X-Api-Key: rtt_…"
# Синхронный анализ
curl -X POST https://ttsapi.ru/v1/analyze/sync \
-H "X-Api-Key: rtt_…" \
-F "audio=@call.mp3" \
-F "emotions=true" \
-F "keywords=true"
# → { "transcript": "…", "segments": […], "keywords": […] }
POST /v1/analyze/topics классифицирует текст по темам без загрузки аудио: возвращает список тем с релевантностью (0..1).
curl -X POST https://ttsapi.ru/v1/analyze/topics \
-H "X-Api-Key: rtt_…" \
-H "Content-Type: application/json" \
-d '{"text": "Запустили стартап и вывели продукт на рынок."}'
# → { "topics": [{"topic": "business", "score": 0.09}] }
POST /v1/analyze/summarize делает экстрактивное резюме текста без загрузки аудио. Параметр `max_sentences` (1..10, по умолчанию 3) задаёт число предложений.
curl -X POST https://ttsapi.ru/v1/analyze/summarize \
-H "X-Api-Key: rtt_…" \
-H "Content-Type: application/json" \
-d '{"text": "Первое предложение. Второе. Третье. Четвёртое.", "max_sentences": 2}'
# → { "summary": "…", "sentences": […] }
POST /v1/detect-language определяет язык текста без загрузки аудио: возвращает код языка ISO 639-1 и уверенность (0..1).
Полезен перед выбором голоса или принудительным указанием языка транскрипции.
curl -X POST https://ttsapi.ru/v1/detect-language \
-H "X-Api-Key: rtt_…" \
-H "Content-Type: application/json" \
-d '{"text": "Привет! Как дела?"}'
# → { "language": "ru", "confidence": 0.99 }
POST /v1/redact заменяет персональные данные в тексте на метки типа и возвращает маскированный текст со списком найденных сущностей и их позициями. Загрузка аудио не требуется.
Маскируются имена, организации, локации, даты и суммы (NER), а также телефоны, email и номера карт (регулярные выражения).
curl -X POST https://ttsapi.ru/v1/redact \
-H "X-Api-Key: rtt_…" \
-H "Content-Type: application/json" \
-d '{"text": "Иван позвонил на +7 900 123-45-67 из Москвы."}'
# → { "redacted_text": "[PER] позвонил на [PHONE] из [LOC].", "entities": […], "count": 3 }
POST /v1/moderate проверяет текст на ненормативную лексику, оскорбления и язык вражды без загрузки аудио: возвращает флаг, общий балл (0..1) и найденные термины с категориями.
Категории: profanity, insult, hate. Лёгкий лексиконный классификатор – быстрый первый фильтр, а не полноценная модель токсичности.
curl -X POST https://ttsapi.ru/v1/moderate \
-H "X-Api-Key: rtt_…" \
-H "Content-Type: application/json" \
-d '{"text": "Это оскорбительное сообщение.", "language": "ru"}'
# → { "flagged": true, "score": 0.5, "categories": ["insult"], "matches": […] }
POST /v1/qa/evaluate оценивает запись по чек-листу обязательных и запрещённых шагов и возвращает вердикт по каждому пункту с доказательством и взвешенный балл 0..100.
Пункты чек-листа имеют id, kind (required или forbidden), описание и необязательный weight. Требуются библиотека записей и языковая модель – тарифы Pro/Business.
curl -X POST https://ttsapi.ru/v1/qa/evaluate \
-H "X-Api-Key: rtt_…" \
-H "Content-Type: application/json" \
-d '{
"recording_id": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
"checklist": [
{ "id": "greeting", "kind": "required", "description": "Поздороваться и представиться" },
{ "id": "price", "kind": "required", "description": "Назвать цену", "weight": 2 },
{ "id": "profanity", "kind": "forbidden", "description": "Не использовать мат" }
]
}'
# → { "recording_id": "…", "score": 83.3, "passed": 2, "failed": 1,
# "items": [ { "id": "greeting", "verdict": "passed", "reason": "…",
# "quote": "Здравствуйте", "start": 0.0, "end": 2.1, "weight": 1 }, … ] }
GET /v1/qa/analytics GET /v1/qa/evaluations GET /v1/qa/evaluations/export
— сводная аналитика по сохранённым оценкам: тренд балла по дням, топ нарушений, скор по операторам и последние оценки.
Экспорт отдаёт CSV (одна строка на звонок, импорт в Битрикс24/amoCRM/1С) или JSON. При оценке можно указать webhook_url — при нарушении на него придёт событие qa.violation.
curl -X GET "https://ttsapi.ru/v1/qa/analytics?days=30" \
-H "X-Api-Key: rtt_…"
# → { "total_evaluations": 120, "average_score": 84.6, "violations": 17,
# "trend": [ { "date": "2026-09-18", "average_score": 81.2, "count": 14 } ],
# "top_violations": [ … ], "by_operator": [ … ], "recent": [ … ] }
# Экспорт для CRM (CSV или JSON):
curl -X GET "https://ttsapi.ru/v1/qa/evaluations/export?format=csv&days=30" \
-H "X-Api-Key: rtt_…" -o qa.csv
POST /v1/meetings/protocol генерирует структурированный протокол встречи – TL;DR, решения, задачи, риски, открытые вопросы и следующие шаги – по транскрипту записи.
Можно выбрать шаблон (standup, demo, interview, retro, one_on_one). Требуются библиотека записей и языковая модель – тарифы Pro/Business.
curl -X POST https://ttsapi.ru/v1/meetings/protocol \
-H "X-Api-Key: rtt_…" \
-H "Content-Type: application/json" \
-d '{
"recording_id": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
"template": "standup"
}'
# → { "recording_id": "…", "template": "standup", "tldr": "…",
# "decisions": [ { "decision": "…", "quote": "…", "start": 0.0, "end": 2.1 } ],
# "tasks": [ { "task": "…", "owner": "Иван", "deadline": "2026-09-27", "quote": "…" } ],
# "risks": [ … ], "open_questions": [ … ], "next_steps": [ … ],
# "markdown": "…", "llm_model": "gpt-4o-mini" }
POST /v1/search находит фрагменты транскриптов, семантически близкие к запросу, по всем вашим записям.
POST /v1/ask отвечает на вопрос по вашим записям (RAG) с дословными цитатами и таймкодами.
Поиск и Q&A индексируют ваши записи автоматически. Требуются библиотека записей, эмбеддинги и языковая модель – тарифы Pro/Business.
# search
curl -X POST https://ttsapi.ru/v1/search \
-H "X-Api-Key: rtt_…" \
-H "Content-Type: application/json" \
-d '{"query": "почему клиент отказался от Pro?", "limit": 5}'
# → { "query": "…", "hits": [ { "recording_id": "…", "text": "…",
# "speaker": "SPEAKER_00", "start": 12.0, "end": 15.5, "score": 0.92 }, … ] }
# ask (RAG)
curl -X POST https://ttsapi.ru/v1/ask \
-H "X-Api-Key: rtt_…" \
-H "Content-Type: application/json" \
-d '{"query": "почему клиент отказался от Pro?"}'
# → { "answer": "…", "citations": [ { "recording_id": "…", "quote": "…",
# "start": 12.0, "end": 15.5 } ], "llm_model": "gpt-4o-mini" }
GET /v1/recordings/{id}/speakers возвращает спикеров записи с ролями, статистикой, таймлайном и метриками разговора (перебивания, тишина, темп речи).
PATCH /v1/recordings/{id}/speakers/{speakerId} переименовывает спикера или назначает роль (operator/client/participant).
Роли operator/client вычисляются автоматически (в разговоре двоих оператор — тот, кто заговорил первым). Переопределение сохраняется в записи.
# speakers, timeline and conversation metrics
curl https://ttsapi.ru/v1/recordings/a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4/speakers \
-H "X-Api-Key: rtt_…"
# → { "recording_id": "…",
# "speakers": [ { "id": "SPEAKER_00", "label": "SPEAKER_00",
# "display_name": "Иван", "role": "operator", "auto_role": "operator",
# "duration_seconds": 123.4, "speech_share": 0.62, "segment_count": 34,
# "word_count": 180, "words_per_minute": 121.3,
# "first_utterance_at": 1.2, "last_utterance_at": 210.5 }, … ],
# "timeline": [ { "start": 0.0, "end": 3.2, "speaker_id": "SPEAKER_00" }, … ],
# "metrics": { "interruptions": 4, "silence_count": 9,
# "total_silence_seconds": 11.2, "longest_silence_seconds": 4.1 } }
# rename a speaker / assign a role (either field is optional; null clears)
curl -X PATCH https://ttsapi.ru/v1/recordings/a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4/speakers/SPEAKER_00 \
-H "X-Api-Key: rtt_…" \
-H "Content-Type: application/json" \
-d '{"display_name": "Иван", "role": "operator"}'
# → { "id": "SPEAKER_00", "label": "SPEAKER_00", "display_name": "Иван",
# "role": "operator", "auto_role": "operator", … }
POST /v1/voice-id анализирует голосовую запись (wav/mp3/ogg/flac до 25 МБ / 3 мин) и возвращает «паспорт голоса»: язык, пол, возрастную группу, эмоциональный фон, отпечаток голоса (эмбеддинг) и вероятность синтеза (AI vs человек).
Вероятность синтеза – бета-показатель и появляется только если настроен анти-спуфинг детектор; иначе поле равно null, а `fake_detection_available` – false. Требуется тариф Pro или Business.
curl -X POST https://ttsapi.ru/v1/voice-id \
-H "X-Api-Key: rtt_…" \
-F "audio=@recording.wav"
# → { "language": "ru", "gender": "female", "age_group": "adult",
# "emotional_background": "neutral",
# "ai_probability": 0.03, "speaker_embedding": [ … ] }
| Поле | Описание |
|---|---|
language | распознанный язык и уверенность (faster-whisper) |
gender | пол по основной частоте (F0): `male` / `female` / `unknown` |
age_group | грубая возрастная группа: `child` / `adult` / `unknown` |
emotional_background | эмоциональный фон и распределение эмоций |
speaker_embedding | отпечаток голоса (ECAPA-TDNN, 192 числа); `null`, если модель недоступна |
ai_probability | вероятность, что голос синтезирован (0..1); `null`, если детектор не настроен |
fake_detection_available | `false`, если анти-спуфинг модель не загружена |
nearest_voices | ближайшие известные голоса (в MVP пусто – фаза 1.5) |
Зачислите эталонную запись как профиль голоса (`voice_…`), затем проверяйте новый фрагмент 1:1 или ищите ближайший профиль 1:N. `verified` = true, когда косинусное сходство выше порога (по умолчанию 0.70).
# enroll a reference clip
curl -X POST https://ttsapi.ru/v1/voice-id/enroll \
-H "X-Api-Key: rtt_…" \
-F "audio=@speaker.wav" -F "name=Alice"
# → { "profile_id": "voice_…" }
# verify 1:1
curl -X POST https://ttsapi.ru/v1/voice-id/verify \
-H "X-Api-Key: rtt_…" \
-F "audio=@check.wav" -F "profile_id=voice_…"
# → { "profile_id": "voice_…", "similarity": 0.81, "verified": true, "threshold": 0.7 }
# identify 1:N (across your profiles)
curl -X POST https://ttsapi.ru/v1/voice-id/identify \
-H "X-Api-Key: rtt_…" \
-F "audio=@check.wav"
# → { "best_match": { "voice_id": "voice_…", "similarity": 0.81 }, "matches": […], "threshold": 0.7 }
curl https://ttsapi.ru/v1/voice-id/profiles -H "X-Api-Key: rtt_…"
curl -X DELETE https://ttsapi.ru/v1/voice-id/profiles/{profile_id} -H "X-Api-Key: rtt_…"
`enroll` зачисляет фрагмент как профиль (voiceprint). Лимит профилей: Pro – 10, Business – 100.
`verify` (1:1) – «тот же человек?»: `verified=true`, когда косинусное сходство не ниже порога `VoiceId:SimilarityThreshold` (по умолчанию 0.70).
`identify` (1:N) – ищет ближайший профиль среди ваших профилей; можно сузить параметром `profile_ids`.
Клонированные голоса зачисляются в профили автоматически – проверяйте по ним, передавая id клона как `profile_id`.
Каждый вызов `enroll` / `verify` / `identify` списывает одну проверку из квоты Voice ID (Pro – 100, Business – 1 000).
Отпечаток извлекает ECAPA-TDNN (speechbrain, CPU); анти-спуфинг детектор опционален и включается на воркере переменной `VI_VOICEID_FAKE_MODEL`. Недоступная модель не роняет запрос – соответствующее поле становится `null`/`unknown`.
POST /v1/batch/synthesize и POST /v1/batch/analyze запускают пакетную обработку: до 20 задач синтеза или до 10 задач анализа (аудио inline base64). Возвращают `202` с `batch_id`.
Результат забирается опросом: GET /v1/batch/{batch_id}.
# Пакетный синтез
curl -X POST https://ttsapi.ru/v1/batch/synthesize \
-H "Content-Type: application/json" \
-H "X-Api-Key: rtt_…" \
-d '{"items":[{"text":"Первый текст","voice":"preset_anna"},{"text":"Второй текст","voice":"preset_m01"}]}'
# → 202 { "batch_id": "…", "status": "queued", "item_count": 2 }
# Пакетный анализ
curl -X POST https://ttsapi.ru/v1/batch/analyze \
-H "Content-Type: application/json" \
-H "X-Api-Key: rtt_…" \
-d '{"items":[{"audio":"BASE64…","language":"ru"}]}'
# Результат
curl https://ttsapi.ru/v1/batch/{batch_id} \
-H "X-Api-Key: rtt_…"
GET /v1/usage показывает остаток квоты по текущему тарифу: символы синтеза, минуты транскрипции и запросы анализа.
curl https://ttsapi.ru/v1/usage \
-H "X-Api-Key: rtt_…"
GET /v1/billing/balance возвращает баланс, тариф и последние транзакции ключа.
POST /v1/billing/topup создаёт пополнение баланса картой и возвращает ссылку на оплату.
# balance, plan and recent transactions
curl https://ttsapi.ru/v1/billing/balance \
-H "X-Api-Key: rtt_…"
# card top-up (returns a payment URL)
curl -X POST https://ttsapi.ru/v1/billing/topup \
-H "X-Api-Key: rtt_…" -H "Content-Type: application/json" \
-d '{"amount_rub": 1000}'
# → { "transaction_id": "…", "payment_url": "…", "amount_rub": 1000, "status": "…" }
К каждому API-ключу применяется ограничение частоты запросов (token bucket): стабильная скорость плюс кратковременный пиковый запас. Лимит считается на клиента – все ключи аккаунта делят его – и зависит от тарифа:
| Тариф | Запросов/сек | Пиковый запас |
|---|---|---|
| Free | 5 | 10 |
| Basic | 15 | 30 |
| Pro | 30 | 60 |
| Business | 60 | 120 |
Запросы без ключа лимитируются по IP: 10 запросов/сек, запас 20. При нехватке токенов запрос отклоняется сразу – очереди ожидания нет.
При превышении возвращается `429` с кодом `rate_limit_exceeded` и заголовком `Retry-After` – повторите запрос позже с экспоненциальной задержкой.
Ошибки возвращаются в формате RFC 7807 (Problem Details) с дополнительным полем code.
| Код | HTTP | Описание |
|---|---|---|
text_too_long | 413 | Текст превышает лимит |
text_invalid_characters | 400 | Текст содержит символы, которые не поддерживает выбранный голос |
quota_exceeded | 429 | Лимит тарифа исчерпан |
rate_limit_exceeded | 429 | Превышена частота запросов (RPS-лимит), повторите позже |
streaming_forbidden | 403 | Стриминг недоступен на текущем тарифе |
audio_invalid | 400 | Некорректный аудиофайл |
audio_too_large | 413 | Аудиофайл превышает допустимый размер |
job_not_found | 404 | Задача не найдена |
engine_unavailable | 503 | Инференс временно недоступен |
premium_voice_forbidden | 403 | Premium-движок недоступен на текущем тарифе |
clone_forbidden | 403 | Клонирование недоступно на текущем тарифе |
diarization_forbidden | 403 | Диаризация недоступна на текущем тарифе |
subtitles_unavailable | 409 | Субтитры недоступны: задача ещё не завершена |
evaluation_forbidden | 403 | Оценка качества речи недоступна на текущем тарифе |
evaluation_unavailable | 503 | Оценка качества речи временно недоступна |
evaluation_invalid | 400 | Некорректный запрос оценки (пустой или слишком длинный эталон) |
recording_export_invalid | 400 | Некорректный формат экспорта или нет транскрипта |
recording_audio_unavailable | 404 | Аудио записи больше недоступно (истёк срок хранения) |
recording_tags_invalid | 400 | Некорректные теги (не строка, слишком длинный тег или больше 20 тегов) |
recording_folder_invalid | 400 | Некорректное имя папки (слишком длинное) |
share_not_found | 404 | Ссылка не найдена или отозвана |
share_expired | 410 | Срок действия ссылки истёк |
share_password_required | 403 | Для доступа требуется пароль |
share_password_invalid | 403 | Неверный пароль ссылки |
share_invalid | 400 | Некорректный запрос ссылки (TTL или пароль) |
audio_too_long | 413 | Аудио превышает допустимую длительность |
long_recording_forbidden | 403 | Длинная транскрипция недоступна на текущем тарифе |
call_qa_forbidden | 403 | Call QA недоступен на текущем тарифе |
call_qa_unavailable | 503 | Call QA временно недоступен |
call_qa_invalid | 400 | Некорректный запрос QA |
qa_export_invalid | 400 | Неверный формат экспорта QA — допустимо csv или json. |
meeting_intelligence_forbidden | 403 | Meeting Intelligence недоступен на текущем тарифе |
meeting_intelligence_unavailable | 503 | Meeting Intelligence временно недоступен |
meeting_intelligence_invalid | 400 | Некорректный запрос протокола встречи |
search_forbidden | 403 | Семантический поиск недоступен на текущем тарифе |
search_unavailable | 503 | Семантический поиск временно недоступен |
search_invalid | 400 | Некорректный поисковый запрос |
ask_forbidden | 403 | Q&A по записям недоступен на текущем тарифе |
ask_unavailable | 503 | Q&A по записям временно недоступен |
ask_invalid | 400 | Некорректный вопрос |
speaker_not_found | 404 | Спикер не найден в записи |
speaker_role_invalid | 400 | Некорректная роль спикера (operator, client, participant, unknown) |
translation_forbidden | 403 | Перевод недоступен на текущем тарифе |
translation_unavailable | 503 | Перевод временно недоступен |
translation_invalid | 400 | Некорректный запрос перевода (язык или job) |
cleaning_invalid | 400 | Некорректные параметры очистки аудио |
cleaning_forbidden | 403 | Очистка аудио недоступна на текущем тарифе |
cleaning_unavailable | 503 | Очистка аудио временно недоступна |
effects_invalid | 400 | Некорректные параметры эффектов |
lexicon_invalid | 400 | Некорректный словарь произношения (lexicon) |
effects_forbidden | 403 | Аудиоэффекты недоступны на текущем тарифе |
effects_unavailable | 503 | Аудиоэффекты временно недоступны |
video_invalid | 400 | Некорректный видеофайл |
video_too_large | 413 | Видеофайл превышает допустимый размер |
video_effects_invalid | 400 | Некорректные параметры видеоэффектов |
video_effects_forbidden | 403 | Видеоэффекты недоступны на текущем тарифе |
video_effects_unavailable | 503 | Видеоэффекты временно недоступны |
voice_id_invalid | 400 | Некорректный запрос Voice ID |
voice_id_forbidden | 403 | Voice ID недоступен на текущем тарифе |
voice_id_unavailable | 503 | Voice ID временно недоступен |
voice_profile_not_found | 404 | Профиль голоса не найден |
voice_profile_limit_exceeded | 403 | Превышен лимит профилей голоса |
diarization_unavailable | 503 | Диаризация временно недоступна |
clone_samples_invalid | 400 | Некорректные образцы для клонирования |
clone_not_found | 404 | Клонированный голос не найден |
clone_limit_exceeded | 403 | Превышен лимит клонированных голосов |
recording_not_found | 404 | Запись не найдена |
recording_forbidden | 403 | Библиотека записей недоступна на текущем тарифе |
recording_limit_exceeded | 403 | Превышен лимит количества записей |
link_invalid | 400 | Некорректная ссылка на аудиофайл |
link_unavailable | 503 | Не удалось скачать аудио по ссылке |
Официальная Python-обёртка: синтез, стриминг, транскрипция, анализ, текст-интеллект, записи, QA, meeting intelligence и batch.
pip install voicekit-client
PyPI → pypi.org/project/voicekit-client · GitHub → github.com/lomshakov/voicekit-python
from voicekit import VoiceKitClient
client = VoiceKitClient(api_key="rtt_…")
audio = client.synthesize("Привет! Это синтез русской речи.", voice="preset_anna", format="mp3")
open("speech.mp3", "wb").write(audio)
for chunk in client.synthesize_stream("Первое предложение. Второе."):
pass
job = client.transcribe("audio.wav", keyterms=["диагноз"])
result = client.get_transcription_job(job["job_id"])
while result["status"] not in ("completed", "failed"):
result = client.get_transcription_job(job["job_id"])
transcript = client.transcribe_sync("audio.wav")
analysis = client.analyze_sync("audio.wav")
lang = client.detect_language("Как дела?")
topics = client.topics("Нейросети и алгоритмы")
summary = client.summarize("Длинный текст.", max_sentences=3)
redacted = client.redact("Иван позвонил на +7 900 123-45-67 из Москвы.")
# Записи, QA и meeting intelligence (Pro/Business)
job = client.recording_from_link("https://example.com/call.mp3", language="ru")
speakers = client.recording_speakers("rec_…")
client.update_speaker("rec_…", "SPEAKER_00", display_name="Иван", role="operator")
client.update_recording("rec_…", tags=["sales", "warm"], folder="Q3")
pdf = client.export_recording("rec_…", format="pdf")
open("call.pdf", "wb").write(pdf)
protocol = client.meeting_protocol("rec_…", template="standup")
wer = client.evaluate("audio.wav", reference="Здравствуйте, это сервис синтеза речи.")
translated = client.translate_transcript(job["job_id"], "en")
batch = client.batch_synthesize([{"text": "Первый текст", "voice": "preset_anna"}])
status = client.get_batch(batch["batch_id"])
Параметры: `api_key` (обязателен), `base_url` (по умолчанию `https://ttsapi.ru`), `timeout` (120.0 с). Ошибки – `VoiceKitError` с полями `.status`, `.code`, `.message`.
Официальная TypeScript/JavaScript-обёртка: синтез, стриминг, транскрипция, анализ, текст-интеллект, записи, QA, meeting intelligence и batch.
npm install voicekit-client
npm → npmjs.com/package/voicekit-client · GitHub → github.com/lomshakov/voicekit-js
import { VoiceKitClient } from "voicekit-client";
import { writeFile } from "node:fs/promises";
const client = new VoiceKitClient({ apiKey: "rtt_…" });
const audio = await client.synthesize("Привет! Это синтез русской речи.", {
voice: "preset_anna",
format: "mp3",
});
await writeFile("speech.mp3", audio);
for await (const chunk of client.synthesizeStream("Первое предложение. Второе.")) {
// …
}
const job = await client.transcribe("audio.wav", { keyterms: ["диагноз"] });
let result = await client.getTranscriptionJob(job.job_id);
while (!["completed", "failed"].includes(result.status)) {
await new Promise((r) => setTimeout(r, 1000));
result = await client.getTranscriptionJob(job.job_id);
}
const transcript = await client.transcribeSync("audio.wav");
const analysis = await client.analyzeSync("audio.wav");
const lang = await client.detectLanguage("Как дела?");
const topics = await client.topics("Нейросети и алгоритмы");
const summary = await client.summarize("Длинный текст.", undefined, 3);
const redacted = await client.redact("Иван позвонил на +7 900 123-45-67 из Москвы.");
// Recordings, QA and meeting intelligence (Pro/Business)
const linkJob = await client.recordingFromLink("https://example.com/call.mp3", "ru");
const speakers = await client.recordingSpeakers("rec_…");
await client.updateSpeaker("rec_…", "SPEAKER_00", { displayName: "Иван", role: "operator" });
await client.updateRecording("rec_…", { tags: ["sales", "warm"], folder: "Q3" });
const pdf = await client.exportRecording("rec_…", "pdf");
const protocol = await client.meetingProtocol("rec_…", "standup");
const wer = await client.evaluate("audio.wav", "Здравствуйте, это сервис синтеза речи.");
const translated = await client.translateTranscript(linkJob.job_id, "en");
const batch = await client.batchSynthesize([{ text: "Первый текст", voice: "preset_anna" }]);
const status = await client.getBatch(batch.batch_id);
Параметры: `apiKey` (обязателен), `baseUrl` (по умолчанию `https://ttsapi.ru`), `timeoutMs` (120000). Ошибки – `VoiceKitError` с полями `.status`, `.code`, `.message`.
WebSocket-эндпоинты (стриминговая транскрипция, VAD) подключаются напрямую WS-клиентом – см. разделы выше.
Официальная C#/.NET-обёртка: синтез, стриминг, транскрипция, анализ, текст-интеллект, записи, QA, meeting intelligence и batch. Без внешних зависимостей – только BCL.
dotnet add package VoiceKit.Client
NuGet → nuget.org/packages/VoiceKit.Client · GitHub → github.com/lomshakov/voicekit-dotnet
using VoiceKit;
using var client = new VoiceKitClient("rtt_…");
byte[] audio = await client.SynthesizeAsync("Привет! Это синтез русской речи.", voice: "preset_anna", format: "mp3");
await File.WriteAllBytesAsync("speech.mp3", audio);
await foreach (var chunk in client.SynthesizeStreamAsync("Первое предложение. Второе."))
{
// …
}
var job = await client.TranscribeAsync("audio.wav", keyterms: new[] { "диагноз" });
var result = await client.GetTranscriptionJobAsync(job!["job_id"]!.GetValue<string>());
while (result!["status"]!.GetValue<string>() is not ("completed" or "failed"))
{
await Task.Delay(1000);
result = await client.GetTranscriptionJobAsync(job!["job_id"]!.GetValue<string>());
}
var transcript = await client.TranscribeSyncAsync("audio.wav");
var analysis = await client.AnalyzeSyncAsync("audio.wav");
var lang = await client.DetectLanguageAsync("Как дела?");
var topics = await client.TopicsAsync("Нейросети и алгоритмы");
var summary = await client.SummarizeAsync("Длинный текст.", maxSentences: 3);
var redacted = await client.RedactAsync("Иван позвонил на +7 900 123-45-67 из Москвы.");
// Записи, QA и meeting intelligence (Pro/Business)
var linkJob = await client.StartRecordingFromLinkAsync("https://example.com/call.mp3", language: "ru");
var speakers = await client.GetRecordingSpeakersAsync("rec_…");
await client.UpdateRecordingSpeakerAsync("rec_…", "SPEAKER_00", displayName: "Иван", role: "operator");
await client.UpdateRecordingAsync("rec_…", tags: new[] { "sales", "warm" }, setTags: true, folder: "Q3", setFolder: true);
byte[] pdf = await client.ExportRecordingAsync("rec_…", "pdf");
var protocol = await client.MeetingProtocolAsync("rec_…", template: "standup");
var wer = await client.EvaluateAsync("audio.wav", reference: "Здравствуйте, это сервис синтеза речи.");
var translated = await client.TranslateTranscriptAsync(linkJob!["job_id"]!.GetValue<string>(), "en");
var batch = await client.BatchSynthesizeAsync(new object[] { new { text = "Первый текст", voice = "preset_anna" } });
var status = await client.GetBatchAsync(batch!["batch_id"]!.GetValue<string>());
Параметры: `apiKey` (обязателен), `baseUrl` (по умолчанию `https://ttsapi.ru`), `timeout` (120 с). Ошибки – `VoiceKitError` с полями `.Status`, `.Code`, `.Message`. JSON-ответы возвращаются как `System.Text.Json.Nodes.JsonNode`.
WebSocket-эндпоинты (стриминговая транскрипция, VAD) подключаются напрямую WS-клиентом – см. разделы выше.
Официальная Go-обёртка: синтез, стриминг, транскрипция, анализ, текст-интеллект, записи, QA, meeting intelligence и batch. Только стандартная библиотека плюс WebSocket-клиент, Go 1.22+.
go get github.com/lomshakov/voicekit-go
pkg.go.dev → github.com/lomshakov/voicekit-go · GitHub → github.com/lomshakov/voicekit-go
client, err := voicekit.NewClient("rtt_…")
ctx := context.Background()
audio, err := client.Synthesize(ctx, "Привет! Это синтез русской речи.", &voicekit.SynthesizeOptions{
Voice: "preset_anna",
Format: "mp3",
})
os.WriteFile("speech.mp3", audio, 0o644)
rc, err := client.SynthesizeStream(ctx, "Первое предложение. Второе.", nil)
defer rc.Close()
job, err := client.Transcribe(ctx, voicekit.Bytes(audio), &voicekit.TranscribeOptions{Keyterms: []string{"диагноз"}})
result, err := client.GetTranscriptionJob(ctx, job.Str("job_id"))
// опрашивайте, пока result.Str("status") не станет completed или failed
transcript, err := client.TranscribeSync(ctx, voicekit.Bytes(audio), nil)
analysis, err := client.AnalyzeSync(ctx, voicekit.Bytes(audio), nil)
lang, err := client.DetectLanguage(ctx, "Как дела?")
topics, err := client.Topics(ctx, "Нейросети и алгоритмы", "")
summary, err := client.Summarize(ctx, "Длинный текст.", &voicekit.SummarizeOptions{MaxSentences: 3})
redacted, err := client.Redact(ctx, "Иван позвонил на +7 900 123-45-67 из Москвы.", "")
// Записи, QA и meeting intelligence (Pro/Business)
linkJob, err := client.RecordingFromLink(ctx, "https://example.com/call.mp3", "ru")
speakers, err := client.RecordingSpeakers(ctx, "rec_…")
client.UpdateSpeaker(ctx, "rec_…", "SPEAKER_00", "Иван", "operator")
folder := "Q3"
client.UpdateRecording(ctx, "rec_…", voicekit.UpdateRecordingOptions{Tags: []string{"sales", "warm"}, Folder: &folder})
pdf, err := client.ExportRecording(ctx, "rec_…", "pdf")
protocol, err := client.MeetingProtocol(ctx, "rec_…", "standup")
wer, err := client.Evaluate(ctx, voicekit.Bytes(audio), "Здравствуйте, это сервис синтеза речи.", nil)
translated, err := client.TranslateTranscript(ctx, linkJob.Str("job_id"), "en")
batch, err := client.BatchSynthesize(ctx, []map[string]any{{"text": "Первый текст", "voice": "preset_anna"}})
status, err := client.GetBatch(ctx, batch.Str("batch_id"))
Параметры: `voicekit.NewClient(apiKey, opts…)` – ключ обязателен; `voicekit.WithBaseURL` (по умолчанию `https://ttsapi.ru`), `voicekit.WithTimeout` (120 с). Ошибки – `*voicekit.APIError` с полями `.Status`, `.Code`, `.Message`; проверяйте через `errors.Is(err, voicekit.ErrForbidden)` или `voicekit.ErrorCode(err)`. JSON-ответы возвращаются как `voicekit.Object` с аксессорами `.Str()`, `.Int()`, `.Bool()`, `.List()`.
WebSocket-эндпоинты (стриминговая транскрипция, VAD) подключаются напрямую WS-клиентом – см. разделы выше.
Официальный PHP-клиент: синтез, стриминг, транскрипция, анализ, текст-интеллект, записи, QA, meeting intelligence и batch. Без зависимостей: PHP 8.1+, cURL или потоки, WebSocket-сессии через сокеты.
composer require lomshakov/voicekit-client
Packagist → lomshakov/voicekit-client · GitHub → github.com/lomshakov/voicekit-php
use VoiceKit\VoiceKitClient;
$client = new VoiceKitClient("rtt_…");
$audio = $client->synthesize("Привет! Это синтез русской речи.", voice: "preset_anna", format: "mp3");
file_put_contents("speech.mp3", $audio);
$out = fopen("long.mp3", "wb");
foreach ($client->synthesizeStream($longText, voice: "preset_anna") as $chunk) {
fwrite($out, $chunk); // чанки приходят по мере генерации
}
fclose($out);
$job = $client->transcribe("audio.wav", language: "ru", keyterms: ["диагноз"]);
$result = $client->getTranscriptionJob($job->str("job_id"));
// опрашивайте, пока $result->str("status") не станет completed или failed
$transcript = $client->transcribeSync("audio.wav");
$analysis = $client->analyzeSync("audio.wav");
$lang = $client->detectLanguage("Как дела?");
$topics = $client->topics("Нейросети и алгоритмы");
$summary = $client->summarize("Длинный текст.", maxSentences: 3);
$redacted = $client->redact("Иван позвонил на +7 900 123-45-67 из Москвы.");
// Записи, QA и meeting intelligence (Pro/Business)
$linkJob = $client->recordingFromLink("https://example.com/call.mp3", "ru");
$speakers = $client->recordingSpeakers("rec_…");
$client->updateSpeaker("rec_…", "SPEAKER_00", displayName: "Иван", role: "operator");
$client->updateRecording("rec_…", tags: ["sales", "warm"], folder: "Q3");
$pdf = $client->exportRecording("rec_…", "pdf");
$protocol = $client->meetingProtocol("rec_…", "standup");
$wer = $client->evaluate("audio.wav", "Здравствуйте, это сервис синтеза речи.");
$translated = $client->translateTranscript($linkJob->str("job_id"), "en");
$batch = $client->batchSynthesize([["text" => "Первый текст", "voice" => "preset_anna"]]);
$status = $client->getBatch($batch->str("batch_id"));
Параметры: `new VoiceKitClient(apiKey)` – ключ обязателен, дальше именованные аргументы `baseUrl` (по умолчанию `https://ttsapi.ru`), `timeout` (120 с), `transport`, `headers`. Ошибки – `VoiceKitError` с методами `.statusCode()`, `.errorCode()`, `.isForbidden()`, `.isCode('quota_exceeded')`. JSON-ответы возвращаются как `VoiceKit\Result` с аксессорами `.str()`, `.int()`, `.float()`, `.bool()`, `.list()`; работает и доступ как к массиву: `$result['status']`.
WebSocket-эндпоинты (стриминговая транскрипция, VAD) подключаются напрямую WS-клиентом – см. разделы выше.
Официальный Java-клиент: синтез, стриминг, транскрипция, анализ, текст-интеллект, записи, QA, meeting intelligence и batch. Без runtime-зависимостей: JDK 17+, HTTP на java.net.http, WebSocket-сессии встроенным клиентом.
<dependency>
<groupId>io.github.lomshakov</groupId>
<artifactId>voicekit-client</artifactId>
<version>0.4.0</version>
</dependency>
// Gradle
implementation("io.github.lomshakov:voicekit-client:0.4.0")
Maven Central → io.github.lomshakov:voicekit-client · GitHub → github.com/lomshakov/voicekit-java
import io.github.lomshakov.voicekit.*;
VoiceKitClient client = new VoiceKitClient("rtt_…");
byte[] audio = client.synthesize("Привет! Это синтез русской речи.", new SynthesizeOptions()
.voice("preset_anna")
.format("mp3"));
Files.write(Path.of("speech.mp3"), audio);
try (InputStream stream = client.synthesizeStream("Первое предложение. Второе.", null)) {
Files.copy(stream, Path.of("long.mp3"), StandardCopyOption.REPLACE_EXISTING);
}
Result job = client.transcribe(FilePart.ofPath("speech.mp3"), new TranscribeOptions()
.language("ru")
.keyterms(List.of("диагноз")));
Result transcript = client.transcriptionJob(job.getString("job_id"));
// опрашивайте, пока transcript.getString("status") не станет completed или failed
Result inline = client.transcribeSync(FilePart.ofPath("speech.mp3"));
Result analysis = client.analyzeSync(FilePart.ofPath("speech.mp3"));
String lang = client.detectLanguage("Как дела?").getString("language");
Result topics = client.topics("Нейросети и алгоритмы");
Result summary = client.summarize("Длинный текст.", new SummarizeOptions().maxSentences(3));
Result redacted = client.redact("Иван позвонил на +7 900 123-45-67 из Москвы.", "ru");
// Записи, QA и meeting intelligence (Pro/Business)
Result linkJob = client.recordingFromLink("https://example.com/call.mp3", "ru");
Result speakers = client.recordingSpeakers("rec_…");
client.updateSpeaker("rec_…", "SPEAKER_00", "Иван", "operator");
client.updateRecording("rec_…", List.of("sales", "warm"), "Q3");
byte[] pdf = client.exportRecording("rec_…", "pdf");
Result protocol = client.meetingProtocol("rec_…", "standup");
Result wer = client.evaluate(FilePart.ofPath("speech.mp3"), "Здравствуйте, это сервис синтеза речи.", null);
Result translated = client.translateTranscript(linkJob.getString("job_id"), "en");
Result batch = client.batchSynthesize(List.of(Map.of("text", "Первый текст", "voice", "preset_anna")));
Result status = client.batch(batch.getString("batch_id"));
Параметры: `new VoiceKitClient(apiKey)` – ключ обязателен, дальше `baseUrl` (по умолчанию `https://ttsapi.ru`), `timeout` (120 с), `transport`, `headers`. Ошибки – `VoiceKitException` с методами `.statusCode()`, `.errorCode()`, `.isForbidden()`, `.isCode('quota_exceeded')`. JSON-ответы возвращаются как `Result` с аксессорами `.getString()`, `.getInt()`, `.getDouble()`, `.getBoolean()`, `.getList()`.
WebSocket-эндпоинты (стриминговая транскрипция, VAD) подключаются напрямую WS-клиентом – см. разделы выше.