Справочник
API v1 — эндпоинты
GET/api/v1/voicesКаталог голосов: id, язык, пол, стиль, лицензия, пример
GET/api/v1/voices/{voice}/avatarАватар голоса (загруженный или сгенерированный градиент)
GET/api/v1/languagesПоддерживаемые языки: код, имя, тир, число голосов
POST/api/v1/ttsСинтез речи → WAV или MP3 (параметр format)
POST/api/v1/tts_streamПотоковый синтез (chunked PCM) для low-latency — чистый поток без пост-эффектов и без mp3
POST/api/v1/voices/createСоздать голос: name, audio_b64 (≤10 МБ base64), ref_text (=аудио слово-в-слово), consent="voice-data-consent,privacy", language? → voice id
GET/api/v1/voices/mineВаши собственные голоса (созданные клоны + купленные): voice (slug), name, language, kind, sample_url — нужен API-ключ
POST/api/v1/transcribeРасшифровка короткого фрагмента: audio_b64, language? (полное имя) → текст. Длительность учитывается в месячном лимите минут расшифровки тарифа
GET/api/v1/statusГотовность движка (real-time агенты): ready, model_ready, engine_up, latency_ms
POST/api/v1/warmupПрогрев движка перед сессией звонков (без списания символов)
GET /api/v1/voices — фильтры: q (поиск по названию/стилю), language (ru, en, de…), gender (male/female), limit (по умолч. 200, макс. 500), offset. Поле voice из ответа передавайте в POST /tts.
# GET /api/v1/voices?language=ru&gender=male&limit=200
{
"object": "list",
"total": 152,
"count": 152,
"voices": [
{
"voice": "de_at_f1",
"name": "Greta",
"language": "de-AT",
"gender": "female",
"style": "Jung",
"license": "commercial",
"badge": null, // null | "beta" | "soon" (soon = synthesis disabled)
"sample_url": "https://hancvoice.com/api/v1/voices/de_at_f1/sample", // permanent link, redirects to the current file
"avatar_url": "https://hancvoice.com/api/v1/voices/de_at_f1/avatar"
}
]
}
Аватар и языки. Аватар: 302 на изображение или SVG-градиент — годится прямо в <img>. Языки: поле tier = main (готов) | beta | soon.
# GET /api/v1/languages — supported languages (code, name, tier, voice count)
{
"object": "list",
"total": 24,
"languages": [
{
"code": "de",
"name": "German",
"native_name": "Deutsch",
"tier": "main",
"voice_count": 32
}
]
}
# GET /api/v1/voices/{voice}/avatar → 302 to image, or a generated SVG. Use directly in <img src>.
<img src="https://hancvoice.com/api/v1/voices/de_at_f1/avatar" width="64" />
Доступ
Аутентификация
Все эндпоинты требуют API-ключ: заголовок X-API-Key: <ключ> или Authorization: Bearer <ключ> (кроме GET /api/v1/voices, GET /api/v1/status, GET /api/v1/languages и GET /api/v1/voices/{voice}/avatar — открыты). Ключ создаётся в кабинете → раздел «API»; API доступен с тарифа Starter и выше (иначе 403). Синтез списывает символы с тарифа ключа — при нулевом балансе возвращается 402. Лимит частоты — по тарифу: Starter — 30 запросов/мин, Pro — 120, Business — 300, Scale — 600 (фолбэк 60); превышение → 429, заголовок Retry-After.
POST /api/v1/tts
Параметры
voiceИдентификатор голоса из GET /api/v1/voices. ⚠️ Без этого поля синтез идёт голосом по умолчанию (de_at_n1), символы при этом списываются — всегда передавайте идентификатор явно.
textтекст для озвучки; макс. длина зависит от тарифа ключа (обязательно)
languagede, en, ru, fr, es, it, pt, zh, ja, ko (а также de-DE, en-US …) и полные имена (German, English …). Плюс Auto: движок определяет язык по тексту — единственный способ синтезировать бета-язык своим голосом.
instructэмоция/стиль по-английски, напр. "calm, friendly" (опц.)
emotionэмоция студийного голоса (для голосов с записанными эмоц-референсами): joyful, excited, tender, calm, sad, serious, tense, angry, afraid, surprised (опц.; без параметра — нейтрально)
saturationнасыщение/гармоническая «подцветка» тембра (пост-обработка): {"preset":"tube"|"tape"|"air","intensity":0–1} (опц.)
speedтемп речи 0.5–2.0 (опц.) Значения вне диапазона прижимаются к ближайшей границе; в ответе тогда приходит X-Effects-Failed: speed_clamped_to_….
gain_dbгромкость −24…+24 дБ (опц.)
eqэквалайзер тембра: {"bands":[{"hz":80,"db":4}, …]} (опц.)
effectпресет звучания: radio, audiobook, podcast, phone, cinematic, megaphone, vintage, deep, bright, warm, narrator_warm, intimate, spacious, whisper, concert; характеры: robot, cartoon, chipmunk, monster, villain, echo_hall; студийные: studio_announcer, studio_natural, studio_rich. Премиум-эффекты (характеры, студийные, cinematic, concert, megaphone, vintage) — только на платных тарифах, иначе игнорируются (опц.)
seedчисло для детерминированного повтора одной и той же озвучки (опц.)
cleantrue — нейро-шумоподавление (отдельно от effect, опц.)
backgroundфон/атмосфера: rain, thunder, sea, forest, birds, wind, stream, night, street, cafe, crowd, fire (опц.)
bg_levelгромкость фона 0.05–0.8 (опц., по умолч. 0.25)
lead_silence_msтишина в начале аудио, мс (опц., для агентов; по умолч. 0)
format"wav" (по умолч.) или "mp3" (опц.)
response_formatТелефонный выход (B2B/IVR): g711_alaw_8k, g711_ulaw_8k, g722_16k, opus, pcm_s16le_24k. Ответ — поток кодека + заголовок X-Audio-Format (опц.)
containerтолько с response_format: wav (контейнер, по умолч.) или raw (сырые кадры под SIP/RTP) (опц.)
Ответ — бинарный аудиофайл: audio/wav или audio/mpeg (если format=mp3); при телефонном response_format — соответствующий контейнер кодека (см. X-Audio-Format).
POST /api/v1/tts_stream
Потоковый синтез
Принимает voice, text, language, instruct, speed, gain_db, eq, effect, background, bg_level, saturation, seed и segments (до 40 элементов: text, instruct до 200 символов, silence 0–3000 мс). Ответ: сырой PCM — 24 кГц, 16 бит, моно, little-endian (application/octet-stream, chunked); WAV-заголовка нет — частоту дискретизации задавайте сами.
# POST /api/v1/tts_stream → PCM stream (application/octet-stream, chunked)
{
"voice": "de_at_f1",
"text": "Hallo! Das ist Streaming-Synthese.",
"language": "de"
}
POST /api/v1/voices/create
Создание голоса
nameназвание голоса (обязательно)
audio_b64запись-образец в base64, ≤10 МБ (обязательно)
ref_textТранскрипт записи — слово в слово, не более 2000 символов (длиннее → 400 ref_text_too_long). Если текст расходится с аудио, голос звучит неразборчиво.
consentстрока согласия — передавайте ровно "voice-data-consent,privacy" (данные голоса, GDPR); без неё — 400 (обязательно)
languageязык образца, полное имя (Russian, English…) или ISO-код; по умолч. German (опц.)
Поле voice из ответа передавайте в POST /tts. Значение voice ниже — иллюстративный пример; реальный идентификатор приходит в ответе. Создание своего голоса доступно с платного тарифа; число своих голосов не ограничено — создание списывает 10.000 символов с баланса (хранение и использование — бесплатно).
# Response — 200 OK (voice value is an example)
{
"ok": true,
"voice": "usr_a1b2c3",
"name": "My voice",
"language": "German"
}
GET /api/v1/voices/mine
Ваши голоса
GET /api/v1/voices отдаёт только публичный каталог. Чтобы получить ВАШИ СОБСТВЕННЫЕ голоса — и созданные по API, и сгенерированные в кабинете/студии — авторизуйтесь API-ключом и вызовите этот эндпоинт. Он возвращает ваши клоны (kind="own") и купленные на Маркетплейсе голоса (kind="marketplace"). Поле voice (slug) передавайте в POST /api/v1/tts.
# GET /api/v1/voices/mine — your own voices (API key required)
curl https://hancvoice.com/api/v1/voices/mine \
-H "X-API-Key: $HANCVOICE_KEY"
# Response — 200 OK
{
"object": "list",
"count": 1,
"voices": [
{
"voice": "usr_a1b2c3",
"name": "My voice",
"language": "German",
"gender": null,
"kind": "own",
"sample_url": "https://hancvoice.com/voice-samples/usr_a1b2c3.wav",
"avatar_url": "https://hancvoice.com/generated-audio/voice-avatars/usr_a1b2c3.webp"
}
]
}
gender у собственных голосов — null (не хранится); sample_url может быть null, если образца нет. При синтезе своим голосом язык берётся из голоса и перекрывает параметр language в POST /tts.
Полный поток для копирования — создать, получить список, озвучить (замените пример ключа своим из «Аккаунт → API»):
# Full own-voice flow — create → list (mine) → synthesize.
# Example key below — replace it with your own key from Account → API.
KEY="sk-live-9f3c1a7b4e2d8c6f0a5b3e1d7c9f2a4b6d8e0c1a3f5b7d9e"
# 1) Create your voice (skip if you already have one in your account)
curl -X POST https://hancvoice.com/api/v1/voices/create \
-H "X-API-Key: $KEY" -H "Content-Type: application/json" \
-d '{"name":"My voice","ref_text":"exact transcript of the recording","audio_b64":"<24kHz sample, base64>","consent":"voice-data-consent,privacy"}'
# → {"ok":true,"voice":"usr_a1b2c3","name":"My voice","language":"German"}
# 2) List your own voices → take the "voice" (slug)
curl https://hancvoice.com/api/v1/voices/mine -H "X-API-Key: $KEY"
# 3) Synthesize with your voice
curl -X POST https://hancvoice.com/api/v1/tts \
-H "X-API-Key: $KEY" -H "Content-Type: application/json" \
-d '{"voice":"usr_a1b2c3","text":"Hallo, das ist meine eigene Stimme.","language":"de"}' --output out.wav
POST /api/v1/transcribe
Расшифровка
audio_b64аудио в base64; рассчитано на короткий фрагмент (обязательно)
languageтолько ПОЛНОЕ имя языка: Russian, English, German, French, Italian, Spanish, Portuguese, Chinese, Japanese, Korean — плюс 14 бета-языков (болгарский, чешский, греческий, украинский, польский и др.) как подсказка распознаванию, а также литерал "auto" (ISO-коды здесь НЕ принимаются, в отличие от /tts; без параметра — автоопределение) (опц.)
Списываются символы по тарифу (≈1 мин аудио = 1000 символов), учитывается месячный лимит минут расшифровки тарифа.
# Response — language = vom Engine erkannter ISO-Code (z. B. de, en, ru)
{
"text": "Transkribierter Text des Fragments.",
"language": "de"
}
GET /api/v1/status · POST /api/v1/warmup
Статус и прогрев
GET /api/v1/status (без ключа) — готовность движка для real-time. POST /api/v1/warmup (с ключом; символы НЕ списывает) прогревает движок перед серией звонков.
# GET /api/v1/status
{
"ready": true,
"model_ready": true,
"engine_up": true,
"latency_ms": 42
}
# POST /api/v1/warmup
{
"ok": true,
"warmed": true,
"warm_ms": 318
}
Ответ
Заголовки и поле code
Content-Typeaudio/wav или audio/mpeg (по параметру format); для /tts_stream — application/octet-stream
X-Effects-Failedэффекты, которые НЕ применились (на движке или срезаны тарифом), через запятую — звук вернётся без них
X-CacheHIT / MISS — был ли ответ из кэша. Важно: по API-ключу кэш-HIT тарифицируется как MISS (кэш экономит время генерации, но не символы).
Retry-Afterпри 429 — через сколько секунд повторить запрос
Поле code в теле ошибки (машиночитаемо): plan_required — нужен тариф выше; voice_limit — лимит голосов тарифа; plan_quota — исчерпан месячный лимит минут расшифровки; email_unverified — подтвердите email; voice_conflict — имя голоса уже занято (при создании голоса).
Коды ответов
Ошибки
200Успех — тело ответа содержит аудиофайл
400Битый JSON или пустой текст. Неизвестный движку язык даёт 4xx-статус движка (напр. 400) с кодом engine_bad_request — одинаково на /v1/tts и /v1/tts_stream
401Нет или неверный API-ключ (заголовок X-API-Key / Authorization)
402Недостаточно символов на балансе ключа — пополните тариф
403Функция недоступна на текущем тарифе (напр. API — со Starter, свой голос — с платного) или нет доступа к голосу
409Конфликт (voice_conflict): голос с таким именем уже есть — при создании голоса укажите другое имя
413Слишком большой файл: для своего голоса аудио >10 МБ (base64)
429Превышена частота запросов (по тарифу: Starter 30, Pro 120, Business 300, Scale 600 в минуту; для /voices/create 5/мин, /warmup 20/мин). Учитывайте заголовок Retry-After. Код: rate_limited.
500Внутренняя ошибка (например, недоступна БД на GET /v1/voices) — повторите позже.
502Движок синтеза/расшифровки не ответил (Bad Gateway) — подождите и повторите
503Движок спит/недоступен или сервис перегружен — повторите через несколько секунд
Тело ошибки — JSON { "error": "описание", "code": "машиночитаемый" }. Возможные значения code: auth_required, plan_required, rate_limited, no_credits, voice_create_credits, bad_request, empty_text, text_too_long, ref_text_too_long, name_too_long, voice_limit, voice_conflict, voice_access, plan_quota, no_audio, engine_busy, engine_unavailable, engine_error, billing_unavailable, temporarily_unavailable. При неуспехе символы не списываются — исключение: обрыв стрима клиентом (списывается доля за доставленный звук).
Все коды ошибок
Полный список машинных кодов в поле code: auth_required (401) · plan_required (403, API с тарифа Starter) · text_too_long, bad_request, name_required, ref_text_required, ref_text_too_long, name_too_long, audio_b64_required, consent_required, voice_required (400) · voice_access · voice_not_found (404) · no_credits (402) · body_too_large, audio_too_large (413) · rate_limited (429, с заголовком Retry-After) · engine_bad_request (4xx от движка) · engine_error, engine_unavailable, engine_not_configured, temporarily_unavailable, mp3_failed, telephony_failed, transcribe_failed (5xx) · client_abort (499, клиент оборвал соединение).
Тонкости
Практические детали, которые легко упустить: тело запроса — не больше 2 МБ для /v1/tts и /v1/tts_stream (иначе 413) и не больше 30 МБ base64 для /v1/transcribe · speaker — синоним voice · маркер паузы ‖ (U+2016) прямо в тексте даёт ровно 400 мс тишины · instruct молча обрезается до 500 символов, lead_silence_ms ограничен 5000 · без seed подставляется 4242, то есть по умолчанию результат воспроизводим (нужна вариативность — меняйте сид сами) · без language считается немецкий · GET /v1/languages понимает ?locale · лимит частоты считается отдельно по каждому эндпоинту; свои лимиты: /voices/create 5/мин, /warmup 20/мин, /voices/mine 60/мин, открытые GET — 120/мин на IP · POST /v1/voices/clone — псевдоним /voices/create.
Каталог
Эффекты и фоны
Параметр effect — один пресет на запрос. Бесплатные доступны всем; премиум — на платных тарифах.
Подача (free)radio — сухой эфир · audiobook — аудиокнига · narrator_warm — тёплый рассказчик · podcast — подкаст · phone — телефон · intimate — близко · spacious — простор · whisper — шёпот · deep — ниже · bright — ярче · warm — теплее
Студийные (премиум)studio_announcer — дикторский эфир · studio_natural — естественный студийный · studio_rich — насыщенный «дорогой» · cinematic — кино · concert — зал · megaphone — рупор · vintage — винтаж
Характеры (премиум)robot — робот · cartoon — мультяшный · chipmunk — бурундук · monster — монстр · villain — злодей · echo_hall — эхо-зал
Фоны (background)Природа: rain (дождь) · thunder (гроза) · sea (море) · forest (лес) · birds (птицы) · wind (ветер) · stream (ручей) · night (ночь). Город: street (улица) · cafe (кафе) · crowd (толпа). Уют: fire (камин). Громкость — bg_level 0.05–0.8
eq (тембр)8 полос: 80, 160, 300, 600, 1500, 3500, 6500, 10500 Гц, каждая −12…+12 дБ. Пример: {"bands":[{"hz":80,"db":-4},{"hz":3500,"db":3}]} — убрать гул, добавить чёткости
Квоты
Лимиты
Частота запросовпо тарифу ключа: Starter — 30/мин, Pro — 120/мин, Business — 300/мин, Scale — 600/мин. Эндпоинты с собственным жёстким лимитом, независимо от тарифа: POST /v1/voices/create — 5/мин, POST /v1/warmup — 20/мин, GET /v1/status — 60/мин на IP, GET /v1/voices — 120/мин на IP.
Длина текстамакс. символов на один POST /api/v1/tts зависит от тарифа ключа
Баланс символовсинтез списывает символы с тарифа ключа; при нулевом балансе — 402
Расшифровка≈1 мин аудио = 1000 символов; действует месячный лимит минут тарифа: Pro 100, Business 300, Scale 800 мин. На Free и Starter расшифровки НЕТ — ответ 403 (plan_required). Лимит исчерпан → 403 (plan_quota).
Размер файласоздание голоса: образец ≤10 МБ (base64), иначе 413
Пример
Полный запрос
POST /api/v1/tts
{
"voice": "cml_de",
"text": "Heute ist das Wetter wunderbar.",
"language": "de",
"instruct": "calm, friendly",
"speed": 1.0,
"effect": "podcast",
"eq": { "bands": [ { "hz": 3500, "db": 3 } ] },
"background": "rain",
"bg_level": 0.2,
"format": "mp3"
}
→ 200 OK, Content-Type: audio/mpeg (binary file)