Ключ і швидкий старт
Бот і API працюють з одного балансу кредитів.
Отримати API-ключ
- Відкрий @sonapro_bot.
- Обери 🔌 API → Створити ключ.
- Додавай
sk_user_…у заголовок кожного запиту.
X-API-Key: sk_user_…Важливо: не вставляй ключ у frontend-код, публічний GitHub або переписку. Створення нового ключа в боті відразу вимикає попередній.
Перша озвучка
Процес асинхронний: створи job_id, перевіряй статус і після done забери аудіо.
API="https://api.sonapro.ai"
KEY="sk_user_…"
# 1. Створити задачу
curl -X POST "$API/v1/tts" \
-H "X-API-Key: $KEY" \
-H "Content-Type: application/json" \
-d '{"text":"Привіт, світе!","voice":"vc_xxxxxxxxxx","language":"uk","model":"sona-3.6"}'
# 2. Перевірити статус
curl "$API/v1/tts/JOB_ID" -H "X-API-Key: $KEY"
# 3. Забрати файл
curl "$API/v1/tts/JOB_ID/audio" -H "X-API-Key: $KEY" -o out.mp3Ендпоінти
Базова адреса: https://api.sonapro.ai.
| Метод | Шлях | Опис |
|---|---|---|
| POST | /v1/tts | Створити озвучку або діалог → job_id |
| GET | /v1/tts/{job_id} | Статус задачі |
| GET | /v1/tts/{job_id}/audio | Завантажити аудіо |
| GET | /v1/tts/{job_id}/link | Коротке публічне посилання |
| GET | /v1/tts/{job_id}/subtitles?format=srt|vtt|ass|json|zip | Субтитри; потрібно subtitles:true |
| GET | /v1/tts/{job_id}/dub | Дубляж: мови, голоси й ціна (кредити й PAYG) для готового результату |
| POST | /v1/tts/{job_id}/dub | Дублювати готовий результат → задача на кожну мову; оплата кредитами або PAYG |
| POST | /v1/tts/dub-options | Мови й голоси дубляжу до створення озвучки |
| GET | /v1/tts/{job_id}/fragments | Фрагменти готової озвучки: номер, текст, початок і кінець |
| POST | /v1/tts/{job_id}/fragments/{n}/quote | Ціна переозвучки фрагмента |
| POST | /v1/tts/{job_id}/fragments/{n} | Переозвучити фрагмент → новий повний файл |
| POST | /v1/tts/dialogue/parse | Діалог: розібрати сценарій або прозу на ролі й репліки |
| GET | /v1/tts/{job_id}/dialogue | Діалог: хто, що й коли говорить |
| GET | /v1/tts/{job_id}/stems | Діалог: ZIP з окремою доріжкою кожної ролі |
| GET | /v1/tts/{job_id}/stems/link | Публічне посилання на доріжки ролей |
| GET/POST | /v1/dialogue/templates | Шаблони діалогів: список або створення → dlg:N |
| GET/PATCH/DEL | /v1/dialogue/templates/{ref} | Шаблон діалогу: прочитати, змінити або видалити |
| POST | /v1/dialogue/templates/from-job/{job_id} | Шаблон із героїв готового діалогу |
| GET | /v1/voices?language=uk&collection=sona_v1 | Каталог; collection: library або sona_v1 |
| POST | /v1/voices/clone | Клонувати голос → tmpl:N |
| GET/POST | /v1/voices/templates | Список або створення шаблону |
| PATCH/DEL | /v1/voices/templates/{num} | Змінити або видалити шаблон |
| GET | /v1/emotions | Актуальний список емоцій |
| GET/POST | /v1/pronunciation | Список або збереження правила вимови |
| DEL | /v1/pronunciation/{term} | Видалити правило |
| GET | /v1/me | Акаунт, тариф і баланс |
| GET | /v1/activity?kind=voice&status=done&limit=50 | Історія задач акаунта: що вже готово, а що ще ні (озвучки, зображення, відео) |
| POST | /v1/images | Згенерувати зображення |
| POST | /v1/images/edit | Згенерувати з фото-референсом |
| GET | /v1/images/{image_id} | Статус задачі |
| GET | /v1/images/{image_id}/file | Завантажити PNG/JPEG/WebP |
| POST | /v1/videos | Створити відео Veo 3.1 — з тексту або з 1–3 фото → video_id |
| GET | /v1/videos/{video_id} | Статус відео |
| GET | /v1/videos/{video_id}/file | Завантажити MP4 |
| GET | /v1/videos?limit=20 | Історія відео акаунта |
Баланс і термін дії — GET /v1/me
Відповідь стосується лише акаунта, якому належить ключ. «Профіль» у боті показує ті самі числа. Дати — ISO 8601 в UTC.
| Поле | Кредити на озвучку й тариф |
|---|---|
credits_remaining | Скільки можна витратити зараз: усі чинні пакети разом зі стартовими кредитами. Поруч — credits_total і credits_used. |
credits_expiringcredits_expires_at | Скільки кредитів згорить найближчим терміном і коли. Це лише найближча дата: у кожного пакета свій термін. Коли в пакетах кредитів не лишилось — 0 і null. |
tariff | Поточний тариф: start, pro, business, ultra або null. |
tariff_expires_at | Коли цей тариф закінчиться. Витрачений пакет тримає тариф до кінця свого терміну, тому дата буває пізніша за credits_expires_at і є навіть тоді, коли та — null. Після неї tariff знижується до меншого чинного пакета або стає null. |
jobs_limit | Скільки озвучок акаунт може виконувати одночасно. |
sub_activesub_expires_at | Підписка Ультра і дата її кінця; для інших тарифів — false і null. |
unlimited | true — безлімітний акаунт: кредити не списуються, тож баланс не рухається, а tariff_expires_at — null. |
Пакети Nano і Veo — у product_billing. і product_billing.; null, якщо пакета немає.
| Поле | Пакет Nano / Veo |
|---|---|
daily_limitjobs_limit | Генерацій на добу (у Veo — null, без ліміту) і скільки одночасно. Кілька пакетів Nano діють разом, і тут — їхня сума. |
used_todayremaining_today | Використано й лишилось у поточній добі. |
resets_at | Коли почнеться нова доба; з кількома пакетами — найближча. Відлік іде від початку пакета, а не з півночі. |
expires_at | Кінець поточного терміну пакета; з кількома пакетами — найближчий. |
active_until | Кінець усього вже оплаченого строку без перерв. Без інших пакетів дорівнює expires_at. |
plans | Кожен пакет, що діє зараз, окремо: id, label, ліміти, використання за його власну добу, starts_at, expires_at. Пакет Nano, куплений поверх активного, діє одразу поруч із ним; пакет Veo починається після кінця поточного. |
product_billing. — раніше придбані кредити, якими можна платити за Nano. Вони вже входять у credits_remaining, тож не додавай їх удруге. payg — гаманець оплати за фактом: balance_usd доступно, reserved_usd зарезервовано під задачі, що виконуються; кошти не згорають. Поля payg немає, якщо PAYG для акаунта вимкнений.
curl https://api.sonapro.ai/v1/me -H "X-API-Key: $SONA_API_KEY"Відповідь, скорочено:
{
"credits_remaining": 400000,
"credits_expiring": 400000,
"credits_expires_at": "2026-10-27T11:37:49+00:00",
"tariff": "pro",
"tariff_expires_at": "2026-10-27T11:37:49+00:00",
"jobs_limit": 4,
"product_billing": {"products": {"nano": {"plan": {
"daily_limit": 600, "used_today": 2, "remaining_today": 598,
"resets_at": "2026-09-28T11:37:49+00:00",
"expires_at": "2026-10-27T11:37:49+00:00",
"active_until": "2026-11-26T11:37:49+00:00"}}}},
"payg": {"balance_usd": "5.000000", "reserved_usd": "0.000000"}
}Голоси й шаблони
Параметри зберігаються для кожного шаблону окремо.
Формати ID і тариф
vc_…Бібліотечний голос1 кредит / символsona_…SONA Voice v11,5 кредита / символtmpl:NОсобистий шаблон/клон1,5 кредита / символЩоб побудувати окремий список наших голосів, запитай GET /v1/voices?collection=sona_v1. У загальному каталозі кожен елемент має поле collection: sona_v1 або library. Фільтри поєднуються, наприклад ?collection=sona_v1&language=uk.
Отримати каталог голосів
Один запит повертає весь каталог обраної мови — зручно зібрати свою таблицю id + name + description.
curl "$API/v1/voices?language=uk" \
-H "X-API-Key: $KEY"
# відповідь (скорочено)
{
"count": 1,
"voices": [
{
"id": "vc_04d73ccf5c",
"name": "Weston A.",
"language": "uk",
"gender": "masculine",
"tags": ["Conversational"],
"description": "Approachable adult male voice with a professional tone for casual conversations and everyday interactions",
"is_pro": false,
"has_preview": true,
"collection": "library"
}
]
}Один голос — різні шаблони
Шаблон зберігає власні speed, volume і emotion. Тому один голос може мати «Нейтральний», «Злий» і «Спокійний» варіанти. Бот запитує ці поля під час створення; у картці шаблону їх можна змінити.
POST /v1/voices/templates
{
"engine": "sona",
"voice": "sona_xxxxxxxxxxxx",
"name": "Taras · angry",
"speed": 1.05,
"volume": 1.0,
"emotion": "angry"
}
# Змінити пресет пізніше
PATCH /v1/voices/templates/7
{"emotion":"neutral","speed":1.0}Якщо під час генерації передати параметр явно, він перекриє значення шаблону лише для цієї озвучки.
Клонування
POST /v1/voices/clone — multipart з полями clip, name, language і необов’язковими speed, volume, emotion. Зразок — від 3 до 60 секунд чистої мови без фонової музики, до 16 МБ; на Sona 3.6 довший зразок, 30–60 секунд, краще зберігає акцент.
Параметри озвучення
Поля POST /v1/tts. Зірочкою позначені обов’язкові.
| Поле | Тип / межі | Опис |
|---|---|---|
text * | string | Текст для озвучення |
voice * | vc_…, sona_…, tmpl:N | Голос або шаблон |
language | auto, uk, en, pl… | auto бере мову голосу; явний код дозволяє іншу мову |
model | sona-3.5 / sona-3.6 | Типово sona-3.6. sona-3.5 працює, лише коли її передано в запиті; старі назви sona-pro, sona-fast і sona-hd теж ідуть на sona-3.6. Модель, вибрана в боті, на API не впливає. |
normalization | auto / off / locale | Sona 3.6: читання чисел, дат, часу, валют і скорочень; напр. en-IN |
format | mp3 | Формат файлу |
bitrate | 32000–192000 | Бітрейт MP3; типово 96000 |
sample_rate | 8000–48000 | Частота дискретизації; типово 44100 |
speed | 0.6–1.5 | Швидкість SONA/клону |
volume | 0.5–2.0 | Гучність SONA/клону |
emotion | string | Одна вокальна манера на весь запит |
billing_source | credits / payg | Типово — кредити тарифу. Передай payg явно для оплати з грошового балансу. Автоматичного перемикання немає. |
auto_stress | bool, типово true | Велика голосна всередині кириличного слова → U+0301 |
subtitles | bool | SRT/VTT/ASS і JSON-таймкоди |
name | string | Назва файлу без розширення |
client_request_id | string, до 128: латиниця, цифри, . _ : - | Твій ідентифікатор запиту (або заголовок Idempotency-Key). Повтор із тим самим id і тим самим тілом повертає першу відповідь із replayed: true — без другої задачі й другого списання; той самий id з іншим тілом — 409. Діє 72 год. Так само в POST …/dub і POST …/fragments/{n}. |
Переозвучити фрагмент
Готова озвучка складається з фрагментів, приблизно по 700 символів. Один фрагмент можна озвучити ще раз — як був або з виправленим текстом (наприклад, з наголосом). Результат — нова задача з новим повним файлом, де цей фрагмент замінено; оригінал не змінюється. Ціна — ×2 до звичайної озвучки символів фрагмента.
GET /v1/tts/{job_id}/fragments — номер (index, з 1), текст, start і end кожного фрагмента. POST …/fragments/{n}/quote — ціна, ті самі поля, що й у POST /v1/tts/quote. POST …/fragments/{n} з необов’язковими text (до 3000 символів), max_credits / max_microusd, billing_source і client_request_id повертає job_id; далі це звичайна задача, із субтитрами, якщо вони були в оригіналі. Статус готової озвучки показує fragments — скільки їх. Доступно, поки зберігається результат (24 год); фрагмент дубляжу не переозвучується — переозвуч оригінал і задублюй знову.
Емоція шаблону і емоція запиту
Якщо використовуєш tmpl:N без emotion, SONA бере збережену емоцію шаблону. Якщо передати emotion:"angry" в цьому запиті, вона замінить емоцію шаблону лише для нього.
Оплата за фактом (PAYG)
Поповни баланс від $5 та оплачуй озвучку в міру використання. Sona — $8 за мільйон оплачуваних символів; клони та PRO — $12 (×1,5). 10 паралельних задач; кошти не згорають. Наприклад, $16 вистачить на 2 000 000 звичайних символів.
Відкрий /payg у Telegram: баланс, поповнення та вибір оплати озвучки в боті. У веб-кабінеті (api.sonapro.ai/cabinet) оплату обирає власний перемикач «Оплата» в налаштуваннях озвучки — вибір у боті туди не переноситься. В API працює той самий ключ: передавай billing_source:"payg" у кожному запиті. Ні вибір у боті, ні перемикач у кабінеті не змінюють типовий режим API. Зображення й відео мають власні пакети і той самий PAYG-баланс: $0.015 за зображення, $0.02 за відео; деталі у вкладках «Генерація зображень» і «Генерація відео».
GET /v1/billing/payg повертає доступні/зарезервовані USD та історію. Поповнення: POST /v1/billing/checkout з {"product":"payg","amount_usd":"16.25","method":"mono"} (або crypto). Кошти зараховуються після перевірки провайдером. Порожній гаманець повертає 402; помилка чи скасування озвучки повертає кошти на той самий баланс. Квитанція billing задачі показує суму й статус списання.
Дубляж
Готова озвучка — іншими мовами й тієї ж тривалості, що й оригінал.
Як це працює
Текст готової озвучки перекладається й озвучується іншими мовами. Кожна мова — окрема задача й окремий файл. Як саме лягає переклад, обираєш ти: «Під відео» — кожне речення починається там, де звучить в оригіналі, і доріжку можна покласти на те саме відео; «Природно» — як звичайна озвучка цією мовою (нижче, «Режими»). Дубляж доступний кожному акаунту, працює з тим самим заголовком X-API-Key і оплачується кредитами або з PAYG-балансу (оплата за фактом).
| Запит | Коли |
|---|---|
GET /v1/tts/{job_id}/dub | Пропозиція для готового результату: мови, голоси й ціна |
POST /v1/tts/{job_id}/dub | Дублювати готовий результат → задача на кожну мову |
POST /v1/tts + dub_languages | Замовити дубляж разом з озвучкою: задачі створяться самі, коли оригінал буде готовий |
POST /v1/tts/dub-options | Мови й голоси до створення озвучки |
POST /v1/audio/dub-source | Дублювати власний запис — лише аудіо (вкладка «Дубляж аудіо») |
Режими: під відео чи природно
Переклад рідко має ту саму довжину, що й оригінал: англійська чи іспанська часто на 20–25 % коротші за українську. Тому обери, що важливіше — збіг із картинкою чи природне звучання. Поле mode у POST …/dub (у POST /v1/tts з dub_languages — dub_mode); діє і для звичайної озвучки, і для діалогу. Ціна однакова.
| Режим | Як звучить | Коли обирати |
|---|---|---|
video«Під відео» типово | Довжина й паузи як в оригіналі: кожна фраза (у діалозі — кожна репліка) на своєму місці (щоб вирівняти паузи, фраза може почати до пів секунди раніше), файл тієї ж тривалості. Коротший переклад сервіс спершу трохи сповільнює дубль, а якщо цього мало — просить сказати повніше (без нових фактів); решту розподіляє по паузах — без довгої тиші посередині; у кінці лишається хіба коротка тиша. | Доріжка ляже під те саме відео: ролик, презентація, урок, де звук має збігатися з картинкою. |
natural«Природно» | Як звичайна озвучка цією мовою: кожен фрагмент звучить у звичайному темпі, паузи природні (не довші за ~0,9 с; у діалозі — паузи самого діалогу), без тиші в кінці. Тривалість може відрізнятися від оригіналу — часто коротша. | Канал, подкаст, аудіокнига, аудіо без відео — де картинка не мусить збігатися слово в слово. |
Без поля — video. Інше значення — 422. GET …/dub і POST /v1/tts/dub-options повертають modes (id, name, description) і default_mode, відповідь POST …/dub — mode, а статус задачі дубляжу — dub_mode. У режимі «Природно» нічого не переозвучується, тож списується лише базова ціна, а решта утримання повертається.
Дубляж готового результату
Спершу запитай пропозицію, потім запусти потрібні мови. max_credits (для PAYG — max_amount_microusd) — найбільше, що ти погоджуєшся заплатити. Менше за базову ціну — запит відхиляється з 409, нічого не списано; між базовою ціною й максимальною — обмежує, скільки можна доплатити за повторну озвучку; без нього утримується повна максимальна сума.
# 1. Що доступно і скільки коштує
curl https://api.sonapro.ai/v1/tts/JOB_ID/dub \
-H "X-API-Key: $SONA_API_KEY"
# 2. Запустити: по задачі на кожну мову
curl -X POST https://api.sonapro.ai/v1/tts/JOB_ID/dub \
-H "X-API-Key: $SONA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"languages":["en","ja"],"voices":{"ja":"native"},"mode":"video","max_credits":4500}'
# → {"job_id":"JOB_ID","mode":"video","billing_source":"credits","chars":4500,"chars_base":3000,"jobs":[
# {"job_id":"DUB_ID","language":"en","status":"queued","voice":"same","chars":2250}, …]}
# 3. Кожна мова — звичайна задача озвучки
curl https://api.sonapro.ai/v1/tts/DUB_ID -H "X-API-Key: $SONA_API_KEY"
curl https://api.sonapro.ai/v1/tts/DUB_ID/audio -H "X-API-Key: $SONA_API_KEY" -o dub_en.mp3У відповіді POST …/dub chars — кредити, утримані зараз, chars_base — базова ціна, а chars кожної задачі в jobs — її утримання. Коли мова готова, списується база плюс повторно озвучені символи, решта одразу повертається; chars у статусі готової задачі дубляжу — фактично списані кредити.
Відповідь GET …/dub для оригіналу на 1 000 символів голосом із каталогу, скорочено:
{
"job_id": "JOB_ID",
"source_language": "uk",
"languages": ["ar", "bg", "cs", "de", "en", "…"],
"voices": {
"en": {"auto": "native",
"native": {"id": "vc_…", "name": "…", "gender": "feminine"},
"choices": [{"id": "vc_…", "name": "…", "gender": "feminine"}, "…"],
"pro": [{"id": "sona_…", "name": "…", "pro": true, "gender": "feminine"}]}
},
"cost_per_language": 1500,
"cost_catalog_voice": 1500,
"cost_clone_voice": 2000,
"cost_per_language_max": 2250,
"cost_catalog_voice_max": 2250,
"cost_clone_voice_max": 3000,
"multiplier_catalog_voice": 1.5,
"multiplier_clone_voice": 2.0,
"billing_source": "credits",
"charge_per_language": 1500,
"charge_per_language_max": 2250,
"max_languages": 10,
"modes": [{"id": "video", "name": "Під відео", "description": "…"},
{"id": "natural", "name": "Природно", "description": "…"}],
"default_mode": "video",
"free_slots": 4,
"balance": 400000,
"payg": {
"cost_per_language_microusd": 12000,
"cost_catalog_voice_microusd": 12000,
"cost_clone_voice_microusd": 16000,
"cost_per_language_max_microusd": 18000,
"cost_catalog_voice_max_microusd": 18000,
"cost_clone_voice_max_microusd": 24000,
"balance_microusd": 5000000
}
}cost_per_language — базова ціна однієї мови голосом оригіналу; cost_catalog_voice і cost_clone_voice — якщо для мови обрати голос із каталогу або клон чи голос Sona PRO. Поля з _max — скільки утримується при запуску: база плюс 50 % на повторну озвучку. multiplier_catalog_voice і multiplier_clone_voice — ціна за символ оригіналу. billing_source — чим заплатить auto; charge_per_language і charge_per_language_max — що утримається з кредитів (0 для безлімітного акаунта). payg є лише в акаунтів із PAYG: ті самі ціни в мікродоларах і balance_microusd. У voices для кожної мови: auto — що вибере auto (same чи native), native — головний голос носія мови, choices — до 6 голосів носіїв, pro — голоси Sona PRO цієї мови. Задача дубляжу має в статусі dub_of — job_id оригіналу. Готовий результат, який можна дублювати, має dub_available: true.
Субтитри: subtitles у POST …/dub (true чи false) вмикає їх для кожної мови запиту; без поля дубляж бере вибір оригіналу — його показує subtitles у пропозиції GET …/dub, а дубляж, замовлений через POST /v1/tts, бере subtitles самої озвучки. Готова мова з субтитрами має в статусі has_subtitles: true і віддає SRT, VTT, ASS чи JSON через GET /v1/tts/{job_id}/subtitles, як звичайна озвучка. Без доплати.
Оплата за фактом (PAYG)
Дубляж можна оплатити з PAYG-балансу: $12 за мільйон символів оригіналу за кожну мову голосом із каталогу й $16 — клоном або голосом Sona PRO (звичайна ставка PAYG $8 × 1,5 і × 2), плюс доплата за повторну озвучку за тією ж ставкою. Чим платити, задає billing_source у POST …/dub: auto (типово) — PAYG, якщо оригінал оплачено з PAYG і PAYG для акаунта увімкнено, інакше кредити; credits чи payg — явно. Ліміт ціни — max_amount_microusd, за тими самими правилами, що й max_credits.
curl -X POST https://api.sonapro.ai/v1/tts/JOB_ID/dub \
-H "X-API-Key: $SONA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"languages":["en","de"],"billing_source":"payg","max_amount_microusd":36000}'
# → {"job_id":"JOB_ID","billing_source":"payg","amount_microusd":36000,"amount_usd":"0.036000",
# "base_microusd":24000,"base_usd":"0.024000",
# "jobs":[{"job_id":"DUB_ID","language":"en",…,"amount_microusd":18000}, …]}amount_microusd і amount_usd — утримано зараз, base_microusd і base_usd — базова ціна, amount_microusd у кожній задачі jobs — її утримання. Підсумкове списання показує квитанція billing у статусі готової задачі дубляжу (charged_usd). Для PAYG free_slots у пропозиції рахує слоти PAYG.
Дубляж одразу при створенні
Додай до POST /v1/tts поле dub_languages і, за потреби, dub_voices та dub_mode (video чи natural, див. «Режими»). Ціна дубляжу додається до ціни озвучки й утримується разом із нею: POST /v1/tts/quote з тим самим тілом показує базову ціну дубляжу в dub_credits, утримання з доплатою за повторну озвучку — в dub_credits_max, а charge_credits уже включає утримання. max_credits діє на весь запит: менше за ціну озвучки разом із базовою ціною дубляжу — 409, більше — обмежує доплату за повторну озвучку.
curl -X POST https://api.sonapro.ai/v1/tts \
-H "X-API-Key: $SONA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"Привіт, світе!","voice":"vc_xxxxxxxxxx","language":"uk","dub_languages":["en","de"],"dub_voices":{"de":"same"},"dub_mode":"natural"}'
# → {"job_id":"JOB_ID","status":"queued","chars":14,"language":"uk",
# "dub_credits":42,"dub_credits_max":64,"dub_languages":["en","de"],"dub_mode":"natural"}
# стан дубляжу — у статусі оригіналу
curl https://api.sonapro.ai/v1/tts/JOB_ID -H "X-API-Key: $SONA_API_KEY"
# → … "dub_jobs":[{"language":"en","state":"started","job_id":"DUB_ID"},
# {"language":"de","state":"waiting"}]waiting→started+job_idКоли оригінал готовий, сервіс сам створює задачі дубляжу, і кожна отримує свій job_id. Якщо оригінал завершився помилкою або його скасовано, усе утримане за дубляж повертається, а стан стає refunded.
З billing_source:"payg" задача оплачує з PAYG-балансу й свої dub_languages: дубляж утримується з гаманця разом із задачею й повертається, якщо задача не вдалася чи скасована. Ліміт ціни на весь запит тоді — max_microusd. Quote показує dub_amount_microusd і dub_amount_max_microusd (у доларах — dub_amount_usd і dub_amount_max_usd), а amount_microusd включає утримання дубляжу.
Голос для кожної мови
Поле voices (або dub_voices у POST /v1/tts) — словник «мова → голос». Мова без запису отримує auto.
| Значення | Що звучить |
|---|---|
auto | Типово. Голос оригіналу, якщо він говорить цією мовою; інакше — голос носія мови з каталогу тієї ж статі. Клон і голос Sona PRO лишаються собою. |
same | Голос оригіналу — з його акцентом |
native | Найпопулярніший голос носія мови з каталогу, тієї ж статі, якщо вона відома |
vc_…, sona_…, tmpl:N | Конкретний голос, збережений шаблон або власний клон |
Щоб показати вибір ще до створення озвучки, надішли голос, мову й модель у POST /v1/tts/dub-options. Відповідь містить languages, voices у тому самому форматі й max_languages. Ціни тут немає, бо вона залежить від тексту: її дає POST /v1/tts/quote.
curl -X POST https://api.sonapro.ai/v1/tts/dub-options \
-H "X-API-Key: $SONA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"voice":"vc_xxxxxxxxxx","language":"uk","model":"sona-3.6"}'Ціна й ліміти
- Ціна — за кожен символ оригіналу, за кожну мову: голосом із каталогу — 1,5 кредита (як озвучка клоном чи голосом Sona PRO), клоном або голосом Sona PRO — 2 кредити. З PAYG — $12 і $16 за мільйон символів оригіналу. Переклад входить у ціну.
- Повторна озвучка — доплата по факту: фрагменти, які довелося озвучити ще раз, щоб вони влізли в час, оплачуються зверху за тією ж ставкою (символи кожного повторного дубля × множник). При запуску утримується базова ціна плюс 50 % від неї (поля
*_max); коли дубляж готовий, списується база плюс повторно озвучені символи, а решта одразу повертається. Більше за утримане не списується — повторна озвучка понад нього безкоштовна. Якщо дубляж мови не вдався, повертається все утримане за неї. - Приклад — оригінал на 1 000 символів, одна мова: голосом із каталогу 1 500 кредитів (до 2 250 з повторною озвучкою) або $0.012 (до $0.018); клоном чи голосом Sona PRO — 2 000 (до 3 000) або $0.016 (до $0.024).
- Мови залежать від моделі оригіналу: 42 мови
sona-3.5, аsona-3.6додає одію (or) та урду (ur). Мова оригіналу до списку не входить. - До 10 мов за запит. Кожна мова — окрема задача й займає один слот одночасних задач тарифу (
jobs_limit), а з PAYG — один із 10 слотів PAYG. Набір приймається цілком або ніяк: якщо вільних слотів не вистачає на всі мови, повертається429. Скільки вільно зараз, показуєfree_slots. - 24 години — стільки результат зберігається й доступний для дубляжу; потім
410. Дубляж дубляжу не робиться — дублюй оригінал.
Помилки
У разі відмови нічого не списується.
402 | Недостатньо кредитів (повідомлення пропонує оплатити з PAYG) або коштів PAYG |
403 | Дубляж недоступний для цього акаунта, або PAYG для акаунта вимкнено |
404 | Задачу не знайдено |
409 | Озвучка ще не завершена, це вже дубляж, цю озвучку не можна дублювати, або max_credits / max_amount_microusd нижче за базову ціну |
410 | Результат уже видалено за строком зберігання |
422 | Мова недоступна або збігається з мовою оригіналу, забагато мов, невідомий голос, mode не video і не natural |
429 | Замало вільних слотів на всі мови |
503 | Дубляж тимчасово недоступний або тривають технічні роботи |
Дубляж свого запису
Свій аудіозапис чи голосове теж можна задублювати іншими мовами — у боті чи через API. Покрокова інструкція, ціна й ліміти — на вкладці «Дубляж аудіо».
Дубляж аудіо
Свій запис — та сама доріжка іншими мовами: сервіс розпізнає текст, перекладає його й озвучує в такт оригіналу.
Як це працює
- Що надсилати — аудіофайл (mp3, m4a, ogg, wav, flac…) або голосове повідомлення: один голос у записі, до 2 год. Відео не приймаємо — лише звук.
- Що робить сервіс — безкоштовно розпізнає мову, текст і час кожного слова й визначає стать мовця. Текст можна виправити до дубляжу: імена, терміни, недочуте.
- Що виходить — mp3 кожною обраною мовою. «🎬 Під відео» — кожна фраза на своєму місці й та сама тривалість, що в оригіналу: доріжку можна накласти на те саме відео. «🎙 Природно» — як звичайна озвучка цією мовою. Фонова музика й шуми не переносяться: у результаті звучить лише новий голос.
У боті — крок за кроком
- Відкрий @sonapro_bot і надішли аудіофайл або голосове — до 20 МБ (більше Telegram ботам не віддає).
- Бот покаже картку запису з тривалістю й ціною — натисни «🌐 Дубляж цього аудіо».
- Зачекай на розпізнавання — приблизно хвилина на кожні 10 хвилин запису. Бот надішле розпізнаний текст.
- Якщо треба — «✏️ Виправити текст»: скопіюй текст, виправ і надішли наступним повідомленням (у боті — до 3 500 символів; довший текст виправляється через API).
- «🌐 Обрати мови» — познач потрібні мови й натисни «Далі › голоси». Для кожної мови — «Авто» (носій мови тієї ж статі, що й мовець), інший голос носія мови (🔊 — прослухати), голос Sona PRO 💎 або свій збережений голос ⭐.
- Обери режим «🎬 Під відео» чи «🎙 Природно», за потреби — «Субтитри», і натисни «▶️ Запустити» — на кнопці вже видно ціну. Готовий файл кожною мовою прийде в чат.
Через API, ціна й ліміти
- Через API — надішли файл, дочекайся
status: done, за потреби виправ текст і запускай дубляж звичайнимPOST …/dub.
| Запит | Що робить |
|---|---|
POST /v1/audio/dub-source | Multipart: file, необов'язково language (uk, en, pt-BR… або auto) і name. Відповідь 202: job_id, status, duration |
GET /v1/tts/{job_id} | Статус запису: source: "upload", language, gender (стать мовця або null), transcript_chars, dub_available; поки сервіс завантажений — waiting і retry_at |
GET /v1/tts/{job_id}/transcript | Розпізнаний текст і його речення з часом (sentences) |
PUT /v1/tts/{job_id}/transcript | Виправити текст до дубляжу: незмінені слова зберігають свій час у записі |
GET / POST /v1/tts/{job_id}/dub | Пропозиція й запуск, як для будь-якої озвучки. Голосу Sona в записі немає, тож same не буває; auto — найпопулярніший голос носія мови тієї ж статі, що й мовець |
# 1. Надіслати запис (розпізнавання безкоштовне)
curl -X POST https://api.sonapro.ai/v1/audio/dub-source \
-H "X-API-Key: $SONA_API_KEY" \
-F file=@talk.mp3 -F language=uk
# → 202 {"job_id":"JOB_ID","status":"queued","duration":512.4}
# 2. Дочекатися "status": "done"
curl https://api.sonapro.ai/v1/tts/JOB_ID -H "X-API-Key: $SONA_API_KEY"
# 3. Текст із часом речень — і виправлення, якщо треба
curl https://api.sonapro.ai/v1/tts/JOB_ID/transcript -H "X-API-Key: $SONA_API_KEY"
curl -X PUT https://api.sonapro.ai/v1/tts/JOB_ID/transcript \
-H "X-API-Key: $SONA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"Привіт усім. Сьогодні поговоримо про погоду."}'
# 4. Дубляж — як для будь-якої озвучки
curl -X POST https://api.sonapro.ai/v1/tts/JOB_ID/dub \
-H "X-API-Key: $SONA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"languages":["en","de"],"mode":"video"}'- Ціна — розпізнавання й виправлення тексту безкоштовні. Дубляж запису — за кожен символ розпізнаного тексту, за кожну мову, удвічі дорожче за озвучку: голосом із каталогу — 2 кредити, клоном або голосом Sona PRO — 3. З PAYG — $16 і $24 за мільйон символів. Повторна озвучка — доплата по факту за тією ж ставкою, при запуску утримується база плюс 50 %, як у будь-якого дубляжу.
- Приклад — запис на 1 000 символів тексту, одна мова: голосом із каталогу 2 000 кредитів (до 3 000) або $0.016 (до $0.024); клоном чи голосом Sona PRO — 3 000 (до 4 500) або $0.024 (до $0.036).
- Ліміти — файл до 95 МБ, запис до 2 год, до 6 год записів на добу на акаунт, один запис розпізнається за раз. «Під відео» дає файл тієї ж тривалості, що й запис. Сам файл видаляється, щойно запис розпізнано; текст і mp3 зберігаються 24 години.
411 | Запит без заголовка Content-Length — надсилай файл звичайним запитом |
413 | Файл більший за 95 МБ |
422 | Запис задовгий (понад 2 год), це не аудіо або це відео, невідома мова запису, виправлений текст відрізняється від розпізнаного більш ніж на 30 % за довжиною, або same для дубляжу запису |
429 | Попередній запис ще розпізнається, вичерпано 6 год записів на добу або вільні слоти тарифу |
Діалоги
Кілька голосів в одній озвучці: кожна роль говорить своїм голосом — з паузами, накладаннями й перебиваннями.
Як це працює
Діалог — це ролі й репліки в порядку звучання. Кожна репліка озвучується голосом своєї ролі, і всі вони складаються в один файл. Тишу на початку й у кінці кожної репліки ми обрізаємо, тож пауза між репліками звучить рівно такою, як задано. Гучність ролей вирівнюється: тиха роль не тоне поруч із гучною, а шепіт лишається шепотом. Репліки можуть накладатися, звучати одночасно або перебивати попередню — обірвана репліка плавно затихає там, де її перебили, а накладання не перевантажує звук. Субтитри називають мовця, а кожну роль можна забрати окремою доріжкою.
| Запит | Що робить |
|---|---|
POST /v1/tts + speakers, segments | Озвучити діалог → job_id; ціну заздалегідь показує POST /v1/tts/quote з тим самим тілом |
POST /v1/tts/dialogue/parse | Розібрати сценарій або звичайну прозу на ролі й репліки — безкоштовно |
GET /v1/tts/{job_id}/dialogue | Готовий діалог: хто, що й коли говорить |
GET /v1/tts/{job_id}/stems | ZIP з окремою доріжкою кожної ролі |
GET /v1/dialogue/templates | Шаблони діалогів dlg:N: герої та їхні голоси |
POST /v1/tts/{job_id}/dub + role_voices | Дубляж діалогу іншими мовами |
Діалоги вмикаються для акаунта окремо: GET /v1/me повертає "dialogue": true, коли ними можна користуватися. Поки ні, запити діалогу відповідають 403.
У боті
- Надішли сценарій текстом або файлом .txt / .docx — кожна репліка з нового рядка:
Ім'я: текст. Бот упізнає діалог і відкриє екран ролей «🎭 Діалог: N ролей · M реплік». - На екрані ролей — кнопка для кожної ролі «Ім'я — Голос». Перша роль отримує поточний голос, інші — запропоновані, щоб ролі не звучали однаково. Натисни роль і обери їй голос: збережені, клони, недавні, пошук за назвою, ID або каталог.
- Далі › з'являється, коли голос є в кожної ролі: картка покаже ролі, голоси, символи й ціну, а Озвучити запустить діалог. Озвучити одним голосом повертає до звичайної озвучки того самого тексту, Як писати діалог показує формат і команди.
- 🎭 Розібрати на ролі — кнопка під звичайним текстом без імен: оповідь розбирається на оповідача й персонажів, а слова реплік беруться з твого тексту дослівно.
- 🎭 Шаблони діалогів — збережені склади героїв із голосами. Шаблон, герої якого збігаються з іменами сценарію, підставляється сам: роль позначена «з шаблону» або «як минулого разу»; 🎭 Шаблон… обирає інший шаблон або жодного.
- Якщо в сценарії помилка, бот покаже «Рядок N: …» і не прочитає ні імена, ні команди вголос.
Під готовим діалогом:
| 🎚 Доріжки ролей | ZIP з окремою доріжкою кожної ролі; якщо він більший за 50 МБ — посилання на нього |
| ✂️ Переозвучити фрагмент | Репліки списком «Ім'я: текст»: будь-яку можна озвучити ще раз — як була або з виправленим текстом |
| 🌐 Створити дубляж | Діалог іншими мовами: обираєш лише мови, голос кожної ролі для кожної мови добирається сам |
| 💾 Зберегти як шаблон | Герої цього діалогу з їхніми голосами, швидкістю й емоцією стають новим шаблоном |
Формат сценарію
Так сценарій пишеться і в боті, і в POST /v1/tts/dialogue/parse.
- Репліка — з нового рядка:
Ім'я: текстабо[Ім'я]: текст. Рядок без імені продовжує попередню репліку. - Ремарка в дужках після імені не озвучується:
Андрій (пошепки): …— це роль «Андрій». - Текст до першого імені читає роль «Оповідач».
- Команди — у фігурних дужках будь-де в репліці; вони не озвучуються й не оплачуються. Пауза стосується кінця своєї репліки, решта — її початку й відлічується від попередньої репліки. Числа — секунди (можна з комою), з
msчимс— мілісекунди.
| Команда | Російською · англійською | Що робить |
|---|---|---|
{пауза: 1.5} | {пауза: 1.5}{pause: 1.5} | Пауза після цієї репліки, до 30 с |
{накладання: 0.7} | {наложение: 0.7}{overlap: 0.7} | Почати за 0.7 с до кінця попередньої репліки |
{перебити: 0.7} | {перебить: 0.7}{interrupt: 0.7} | Те саме — і обірвати попередню |
{почати через: 2} | {начать через: 2}{start after: 2} | Почати через 2 с після початку попередньої |
{перебити через: 2} | {перебить через: 2}{interrupt after: 2} | Те саме — і обірвати попередню |
{почати після: "фраза"} | {начать после: "фраза"}{after words: "phrase"} | Почати, щойно в попередній репліці прозвучить фраза; вона має траплятися там рівно один раз |
{перебити після: "фраза"} | {перебить после: "фраза"}{interrupt after words: "phrase"} | Те саме — і обірвати попередню |
{одночасно} | {одновременно}{simultaneous} | Разом із попередньою реплікою |
Автор: Лісова галявина. Над озером стелиться вечірній туман.
Василь: Андрію, ти чуєш? Хтось співає над водою. {пауза: 1}
Андрій (пошепки): Чую. Кажуть, це Мавка, вона заманює рибалок у саму глибину.
Мавка: {перебити після: "заманює рибалок"} Неправда!
Я просто люблю співати, коли сходить місяць.
Василь: {накладання: 0.4} Ой... Вона нас почула.
Автор: Хлопці переглянулися й мовчки рушили додому.Чотири ролі, сім рядків — шість реплік: після Василевого питання секунда тиші, Мавка перебиває Андрія на словах «заманює рибалок», рядок без імені продовжує її репліку, а Василь починає ще до того, як вона договорить.
API: озвучити діалог
Той самий POST /v1/tts, але замість text і voice — ролі (speakers) і репліки (segments). Решта полів — model, language, format, subtitles, billing_source, max_credits, name — працюють як у звичайній озвучці; speed, volume і emotion запиту діють на ролі без власних. Далі це звичайна задача: статус, /audio, субтитри.
curl -X POST https://api.sonapro.ai/v1/tts \
-H "X-API-Key: $SONA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"sona-3.6","subtitles":true,"dialogue_pause_seconds":0.35,
"speakers":[
{"id":"author","name":"Автор","voice":"vc_xxxxxxxxxx"},
{"id":"vasyl","name":"Василь","voice":"tmpl:3","speed":1.05},
{"id":"mavka","name":"Мавка","voice":"sona_xxxxxxxxxxxx","volume":0.9,"emotion":"calm"}],
"segments":[
{"speaker_id":"author","text":"Над озером стелиться туман.","pause_after_seconds":1},
{"speaker_id":"vasyl","text":"Чуєш? Хтось співає над водою. Це, мабуть, Мавка."},
{"speaker_id":"mavka","text":"Так, це я!","start_mode":"after_words",
"start_after_words":"над водою","interrupt_previous":true},
{"speaker_id":"vasyl","text":"Вона нас почула.","start_mode":"overlap","start_offset_seconds":0.3}]}'
# → {"job_id":"JOB_ID","status":"queued","chars":202,"language":"uk",
# "dialogue":{"speakers":3,"segments":4}}
# із шаблоном dlg:3: голоси героїв беруться з нього за іменами, speakers не потрібні
curl -X POST https://api.sonapro.ai/v1/tts \
-H "X-API-Key: $SONA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"template":"dlg:3","segments":[{"speaker_id":"Василь","text":"Ти чуєш?"},{"speaker_id":"Мавка","text":"Чую."}]}'| Поле | Опис |
|---|---|
speakers | 2–20 ролей (таблиця нижче). З template — необов'язкові: вони лише перекривають героїв шаблону або додають нових |
segments * | До 2000 реплік у порядку звучання (таблиця нижче) |
dialogue_pause_seconds | Пауза між репліками, які не задають власної, 0–30 с; типово 0.35 |
template | dlg:N — шаблон діалогу: кожна роль отримує голос героя з тим самим іменем |
text | Не потрібен. Якщо передати — має дорівнювати текстам реплік через порожній рядок |
| speakers[] | Опис |
|---|---|
id * | Унікальний у запиті, до 80 символів; на нього посилаються репліки |
name | Ім'я в субтитрах, доріжках і шаблонах; типово — id |
voice * | vc_…, sona_… або tmpl:N |
speed | 0.6–1.5 (або 60–150 %) |
volume | 0.5–2.0 (або 50–200 %): точне підсилення ролі в міксі після вирівнювання гучності |
emotion | Емоція ролі |
language | Мова ролі — у діалозі ролі можуть говорити різними мовами. Типово — мова запиту; auto бере мову голосу ролі, а якщо вона невідома, визначає її з реплік ролі |
Пріоритет: поле ролі → поле запиту → пресет збереженого голосу tmpl:N. Наголоси, правила вимови й теги в тексті працюють у кожній репліці так само, як у звичайній озвучці.
| segments[] | Опис |
|---|---|
speaker_id * | id ролі |
text * | Текст репліки |
pause_after_seconds | Пауза після репліки, 0–30 с; замість dialogue_pause_seconds |
start_mode | Коли починається репліка — таблиця нижче; типово after |
start_offset_seconds | Для overlap і after_seconds, 0–60 с |
start_after_words | Для after_words: фраза до 200 символів, що трапляється в попередній репліці рівно один раз |
interrupt_previous | true — обірвати попередню репліку там, де починається ця (з будь-яким start_mode, крім after) |
interrupt_overlap_seconds | Скільки обидва голоси звучать разом перед обривом, 0–0.5 с; типово 0.05 |
| start_mode | Коли починається репліка |
|---|---|
after | Типово: коли всі попередні репліки стихли, плюс пауза |
simultaneous | Разом із попередньою |
overlap | За start_offset_seconds до кінця попередньої |
after_seconds | Через start_offset_seconds після початку попередньої |
after_words | Щойно в попередній репліці прозвучить start_after_words |
Правило початку відлічується від попередньої репліки й замінює паузу перед нею. Перша репліка завжди after, а одна роль сама на себе не накладається. Відповідь POST /v1/tts додає dialogue — скільки ролей і реплік; quote — dialogue з ролями (id, name, voice, chars), кількістю реплік і credit_multiplier.
API: результат
Статус діалогу містить dialogue — ролі (id, name) і кількість реплік. У готового додаються dialogue_url, stems_url і fragments — кількість реплік, які можна переозвучити.
# 1. Статус
curl https://api.sonapro.ai/v1/tts/JOB_ID -H "X-API-Key: $SONA_API_KEY"
# → … "dialogue":{"speakers":[{"id":"author","name":"Автор"}, …],"segments":4},
# "dialogue_url":"/v1/tts/JOB_ID/dialogue","stems_url":"/v1/tts/JOB_ID/stems","fragments":4
# 2. Хто, що й коли
curl https://api.sonapro.ai/v1/tts/JOB_ID/dialogue -H "X-API-Key: $SONA_API_KEY"
# 3. Доріжки ролей: ZIP або публічне посилання на нього
curl https://api.sonapro.ai/v1/tts/JOB_ID/stems -H "X-API-Key: $SONA_API_KEY" -o stems.zip
curl https://api.sonapro.ai/v1/tts/JOB_ID/stems/link -H "X-API-Key: $SONA_API_KEY"
# → {"url":"https://api.sonapro.ai/ds/…","expires":1791460800}
# 4. Озвучити третю репліку ще раз, з виправленим текстом
curl -X POST https://api.sonapro.ai/v1/tts/JOB_ID/fragments/3 \
-H "X-API-Key: $SONA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"Так, це я! І я все чую."}'Відповідь GET …/dialogue, скорочено:
{
"job_id": "JOB_ID",
"duration": 7.41,
"speakers": [{"id": "author", "name": "Автор", "voice": "vc_xxxxxxxxxx"}, "…"],
"segments": [
{"index": 2, "speaker_id": "vasyl", "speaker_name": "Василь",
"text": "Чуєш? Хтось співає над водою. Це, мабуть, Мавка.",
"start": 3.12, "end": 5.06, "interrupted": true},
{"index": 3, "speaker_id": "mavka", "speaker_name": "Мавка",
"text": "Так, це я!", "start": 5.01, "end": 6.2, "interrupted": false},
"…"
]
}- Доріжки ролей —
GET …/stemsвіддає ZIP: окрема доріжка кожної ролі тієї ж довжини, що й увесь діалог, плюсtimeline.json.GET …/stems/link— публічне посилання без ключа (urlіexpires), зручне для великих файлів. - Субтитри (
subtitles:true) називають мовця: SRT — «Ім'я: …», одночасна мова — один блок «- А: … / - Б: …», VTT —<v Ім'я>, ASS — поле Name. - Репліки як фрагменти —
GET /v1/tts/{job_id}/fragmentsповертає репліки зspeaker_idіspeaker_name.POST …/fragments/{n}з необов'язковим виправленимtextстворює нову задачу — увесь діалог, де цю репліку озвучено ще раз; оригінал не змінюється. Ціну заздалегідь показуєPOST …/fragments/{n}/quote.
API: розбір сценарію
POST /v1/tts/dialogue/parse перетворює текст на ролі й репліки у форматі POST /v1/tts і пропонує кожній ролі голос. Безкоштовно: до 30 запитів на хвилину. Звичайний текст без імен відповідає {"is_dialogue": false}, а з "auto": true розбирається на оповідача й персонажів — до 20 000 символів, до 6 запитів на хвилину; слова реплік беруться з оригіналу дослівно.
# сценарій; voice — поточний голос, його отримає перша роль
curl -X POST https://api.sonapro.ai/v1/tts/dialogue/parse \
-H "X-API-Key: $SONA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"Василь: Ти чуєш? {пауза: 1}\nМавка: Чую!","voice":"vc_xxxxxxxxxx"}'
# звичайна оповідь → оповідач і персонажі, без шаблону
curl -X POST https://api.sonapro.ai/v1/tts/dialogue/parse \
-H "X-API-Key: $SONA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"Василь озирнувся й гукнув: «Хто тут?» Із туману тихо відповіла Мавка: «Я».","auto":true,"template":"none"}'Відповідь на перший запит, скорочено:
{
"is_dialogue": true,
"auto": false,
"speakers": [
{"id": "Василь", "name": "Василь", "lines": 1, "chars": 8,
"suggested_voice": {"id": "vc_xxxxxxxxxx", "name": "…", "gender": "masculine"},
"voice_source": "current", "template_voice": null, "remembered_voice": null},
{"id": "Мавка", "name": "Мавка", "lines": 1, "chars": 4,
"suggested_voice": {"id": "vc_…", "name": "…", "gender": "feminine"},
"voice_source": "suggested", "template_voice": null, "remembered_voice": null}
],
"segments": [
{"speaker_id": "Василь", "text": "Ти чуєш?", "pause_after": 1.0, "start_mode": "after", "…": "…"},
{"speaker_id": "Мавка", "text": "Чую!", "pause_after": null, "start_mode": "after", "…": "…"}
],
"characters": 12,
"credit_multiplier": 2.0,
"language": "uk",
"template": null
}- Поля запиту:
text(обов'язкове),auto,voice— поточний голос (vc_…,sona_…,tmpl:N; невідомий просто ігнорується),template,language,model. suggested_voice— голос, з якого роль починає, у порядку: герой шаблону → голос, яким цей герой звучав у твоєму останньому діалозі →voiceзапиту (лише перша роль) → голос із каталогу, якого не має жодна інша роль. Звідки він — кажеvoice_source:template,memory,current,suggestedабоnull. Голос із шаблону чи пам'яті приходить зі своїмиspeedіemotion; самі вони — уtemplate_voiceіremembered_voice.template:"dlg:N"— цей шаблон,"none"— без шаблону; без поля застосовується твій шаблон, герої якого покривають найбільше ролей сценарію (щонайменше дві або всі). Відповідь тоді маєtemplate—id,name,matchedіmissing(ролі, яким шаблон не дав голосу), інакшеnull.segmentsможна одразу надіслати вPOST /v1/tts, додавши голос кожній ролі. Поля в них звуться коротко —pause_after,start_offset,interrupt,interrupt_overlap;POST /v1/ttsприймає обидва написання.- Сценарій, який не можна озвучити (помилка в команді, забагато ролей чи реплік, задовгий), отримує
422з причиною «Рядок N: …» ще тут.
Шаблони діалогів
Шаблон — твій збережений склад: герої так, як їх названо в сценаріях, і голос кожного (vc_…, sona_… або tmpl:N), за бажанням — speed, volume, emotion і language. Посилання — dlg:N: номер у межах акаунта, після видалення не повторюється. До 50 шаблонів, у кожному 1–20 героїв, назва — до 60 символів.
| Запит | Що робить |
|---|---|
GET /v1/dialogue/templates | Список: templates, змінені останніми — першими, і max |
POST /v1/dialogue/templates | Створити → 201; герої списком roles або рядками text |
GET /v1/dialogue/templates/{ref} | Один шаблон; ref — dlg:N або N |
PATCH /v1/dialogue/templates/{ref} | Змінити name, roles або text — герої замінюються повністю |
DELETE /v1/dialogue/templates/{ref} | Видалити → {"deleted": "dlg:3"} |
POST /v1/dialogue/templates/from-job/{job_id} | Шаблон із героїв готового діалогу → 201; працює й після того, як аудіо видалено |
# створити зі списку героїв: один герой на рядок
curl -X POST https://api.sonapro.ai/v1/dialogue/templates \
-H "X-API-Key: $SONA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Лісова пісня","text":"Автор vc_xxxxxxxxxx\nВасиль tmpl:3 1.1\nАндрій: vc_yyyyyyyyyy calm\nМавка = sona_xxxxxxxxxxxx 0.9 sad"}'
# → 201 {"id":"dlg:3","num":3,"name":"Лісова пісня","roles":[
# {"name":"Автор","voice":"vc_xxxxxxxxxx","voice_name":"…","speed":null,…}, …],…}
# або з героїв готового діалогу
curl -X POST https://api.sonapro.ai/v1/dialogue/templates/from-job/JOB_ID \
-H "X-API-Key: $SONA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Лісова пісня"}'
# перейменувати
curl -X PATCH https://api.sonapro.ai/v1/dialogue/templates/dlg:3 \
-H "X-API-Key: $SONA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Мавка й рибалки"}'- Рядки героїв —
Ім'я ID [швидкість] [емоція]: між іменем і голосом пробіл,:,-,—чи=; швидкість — 0.6–1.5 або 60–150 %. Рядок, який не вдалося прочитати, —422«Рядок N: …». - Збіг за іменами — без урахування регістру й зайвих пробілів, «ё» = «е», усі апострофи однакові.
POST /v1/ttsз"template": "dlg:3"дає кожній ролі голос героя з тим самим іменем, а в субтитрах лишається написання зі сценарію;speakersз тим самимidперекривають героя або додають нового. Роль, якої немає ні там, ні там, —422з її іменем. Розбір сценарію підставляє відповідний шаблон сам. - Пам'ять героїв — і без шаблону сервіс пам'ятає останній голос кожного героя за іменем (до 500 на акаунт): його записує кожен прийнятий діалог, і наступний розбір пропонує його знову (
voice_source: "memory"). - Якщо збережений голос
tmpl:Nвидалено, герої з ним лишаються без голосу ("voice": null): розбір показує їх уmissing, і їм треба дати новий.
Дубляж діалогу
Готовий діалог дублюється так само, як звичайна озвучка, — GET і POST /v1/tts/{job_id}/dub, — але голос задається для кожної ролі окремо. Кожна репліка перекладається з урахуванням попередніх і того, хто їх говорить, озвучується голосом своєї ролі й стає туди, де звучала в оригіналі; обірвана репліка обривається в ту саму мить. Файл кожної мови — тієї ж довжини, що й оригінал, і теж є діалогом: репліки, доріжки ролей, субтитри, переозвучка репліки. Дублювати дубляж ще раз не можна.
# 1. Мови, голоси ролей і ціна
curl https://api.sonapro.ai/v1/tts/JOB_ID/dub -H "X-API-Key: $SONA_API_KEY"
# → … "dialogue":true,"roles":[{"id":"vasyl","name":"Василь","voice":"tmpl:3"}, …],
# "role_voices":{"en":{"vasyl":{"auto":{"id":"tmpl:3","name":"…"},"choices":[…]}, …}, …}
# 2. Запустити: голос задано лише Мавці англійською, решта — auto
curl -X POST https://api.sonapro.ai/v1/tts/JOB_ID/dub \
-H "X-API-Key: $SONA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"languages":["en","pl"],"role_voices":{"en":{"mavka":"vc_xxxxxxxxxx","author":"native"}}}'role_voices— «мова → роль → голос»:auto,same,native,vc_…,sona_…абоtmpl:N; роль без запису отримуєauto. Полеvoicesдля діалогу не діє —422.auto: клон і голос Sona PRO лишаються собою, голос, що говорить цією мовою, — теж; інакше роль отримує голос носія мови тієї ж статі, і дві ролі не отримують один голос.- Пропозиція
GET …/dubдля діалогу додаєdialogue: true,rolesіrole_voices— для кожної мови й ролі, що вибереauto, і до 6 голосів носіїв уchoices. mode— як у вкладці «Дубляж»:video(типово) — кожна репліка починається там, де в оригіналі (щоб вирівняти паузи — до пів секунди раніше), файл тієї ж тривалості, під те саме відео;natural— репліки йдуть одна за одною з природними паузами (накладання й перебивання зберігаються), тривалість може відрізнятися.- Ціна не залежить від голосів (нижче, «Ціна й ліміти»); мови, до 10 мов за запит, слоти, утримання й
max_credits— як у вкладці «Дубляж». Замовити дубляж разом зі створенням діалогу (dub_languages) не можна — лише з готового результату.
Ціна й ліміти
- Діалог — 2 кредити за символ реплік, якими б голосами вони не звучали; імена, команди, налаштування й паузи не оплачуються. З PAYG (
billing_source:"payg") — $16 за мільйон символів реплік. Наприклад, 1 000 символів реплік — 2 000 кредитів або $0.016. - Одна репліка ще раз — ×2 до її символів: 2 кредити за символ, з PAYG — $16 за мільйон.
- Дубляж діалогу — 2 кредити за символ реплік оригіналу за кожну мову, з PAYG — $16 за мільйон на мову. Репліки, які довелося озвучити ще раз, щоб вони влізли в час, доплачуються за тією ж ставкою: при запуску утримується база плюс до 50 %, а невикористане одразу повертається.
- Ролі — від 2 до 20,
idі ім'я — до 80 символів. Репліки — до 2000, разом до 200 000 символів. - Паузи — до 30 с, зсуви (
start_offset_secondsі числа в командах) — до 60 с. Увесь діалог разом із паузами — до 5 годин; довший отримує422ще до списання. - Одна задача — діалог займає один слот одночасних задач, скільки б ролей у ньому не було.
- 24 години — стільки зберігаються файл, доріжки ролей і репліки для переозвучки й дубляжу; потім
410. Шаблон із готового діалогу можна зберегти й пізніше.
Помилки
У разі відмови нічого не списується.
400 | Тіло запиту не вдалося прочитати — наприклад, воно не в UTF-8 |
402 | Недостатньо кредитів або коштів PAYG |
403 | Діалоги ще не увімкнено для цього акаунта (GET /v1/me → "dialogue": false), або PAYG для акаунта вимкнено |
404 | Задачу чи шаблон не знайдено, задача — не діалог, або немає репліки з таким номером |
409 | Діалог ще не готовий, ціна вища за max_credits / max_microusd, уже збережено 50 шаблонів, або це вже дубляж |
410 | Файли діалогу вже видалено за строком зберігання |
422 | Помилка в ролях, репліках чи сценарії — з місцем: «Роль …», «Репліка N: …», «Рядок N: …»; невідомий голос, недоступна мова ролі, задовгий діалог, героя немає в шаблоні; у запиті діалогу є voice, accent чи dub_languages; автоматичному розбору не можна довіряти |
429 | Забагато запитів (розбір — 30 на хвилину, з auto — 6) або зайняті всі слоти одночасних задач |
503 | Діалоги чи автоматичний розбір тимчасово недоступні або тривають технічні роботи |
Наголоси, вимова й емоції
Клон передає тембр, а читає текст модель. Тому наголос і вимова налаштовуються через текст.
Три рівні роботи з наголосом
| Рівень | Приклад | Коли застосовувати |
|---|---|---|
| 1. Знак U+0301 | за́мок / замо́к | Перша підказка для неоднозначного слова |
| 2. Велика голосна | зАмок / замОк | Лише зручний запис: SONA перетворить його на той самий U+0301 |
| 3. Фонетична заміна | Тарас → та-РАС | Тільки якщо модель проігнорувала обидві підказки і заміну перевірено на слух |
U+0301 і велика літера — не два різні методи. Велика голосна всередині кириличного слова лише конвертується в U+0301. Якщо модель ігнорує знак, вона може ігнорувати обидва варіанти.
Персональний словник SONA: як він працює з кирилицею
Це не готовий орфоепічний словник усієї мови й не автоматичний пошук наголосів. Це список власних винятків акаунта: перед озвученням SONA знаходить term у тексті й буквально підставляє replacement. Ідентифікатор словника в POST /v1/tts передавати не потрібно — збережені правила застосовуються автоматично.
| Властивість | Поведінка SONA |
|---|---|
| Кирилиця | Підтримується і в term, і в replacement. Фонетичну підказку можна записати звичайними українськими/російськими літерами. |
| Регістр | Типово case_sensitive: false: Тарас знаходить Тарас, тарас і ТАРАС. З case_sensitive: true правило US не змінює us, а LaTeX не змінює latex. Ключ малими літерами також приймає початкову велику: cat → cat / Cat, але не CAT. Діє в Sona 3.5 і 3.6. |
| Межі | Збіг лише за цілим словом або цілою фразою. Правило Тарас не змінює Тараса чи Тарасові. |
| Відмінки | Кожну потрібну словоформу зберігай окремо: Тараса → та-РА-са, Тарасові → та-РА-со-ві. Це приклади формату — кожну заміну перевір на слух. |
| Область дії | Правила належать акаунту, а не одному голосу: вони діють у боті та API для всіх його голосів і шаблонів. |
| Порядок | Довші фрази застосовуються раніше за коротші слова. Ліміт — 50 правил; term до 60, replacement до 160 символів. |
Для слова зі словника пиши в сценарії звичайне написання. Не додавай одночасно U+0301 або велику голосну: словник застосовується після нормалізації наголосу, тому змінене написання вже не дорівнюватиме збереженому term. Після підміни саме фінальний текст іде в озвучення, субтитри та підрахунок символів.
Приклад правила з урахуванням регістру для POST /v1/pronunciation: {"term":"US","replacement":"United States","case_sensitive":true}. Старі правила зберігають попередню поведінку. Правила з перетином написань повертають 422: спочатку зміни або видали попереднє правило. Для оновлення чи видалення конкретного варіанта передавай точний term зі списку правил.
# додати або оновити одне правило
curl -X POST https://api.sonapro.ai/v1/pronunciation \
-H "X-API-Key: $SONA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"term":"Тарас","replacement":"та-РАС"}'
# окремі правила для відмінюваних форм
curl -X POST https://api.sonapro.ai/v1/pronunciation \
-H "X-API-Key: $SONA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"term":"Тараса","replacement":"та-РА-са"}'
# переглянути всі правила акаунта
curl https://api.sonapro.ai/v1/pronunciation \
-H "X-API-Key: $SONA_API_KEY"
# видалити правило; кирилицю в URL треба percent-encode
curl -X DELETE https://api.sonapro.ai/v1/pronunciation/%D0%A2%D0%B0%D1%80%D0%B0%D1%81 \
-H "X-API-Key: $SONA_API_KEY"Коли використовувати: для імен, брендів, абревіатур і термінів, які стабільно читаються неправильно. Якщо проблема лише в наголосі й U+0301 спрацьовує, словник не потрібен. Фонетична підміна — sounds-like підказка, а не гарантія, тому тестуй короткою озвучкою на потрібній мові.
Перевірене правило: Тарас
Для українського голосу Taras модель читала ТАрас і ігнорувала знак наголосу. Прослухана заміна та-РАС дала правильне ТарАс.
curl -X POST https://api.sonapro.ai/v1/pronunciation \
-H "X-API-Key: $SONA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"term":"Тарас","replacement":"та-РАС"}'Правило діє лише на ціле слово, незалежно від регістру, і автоматично застосовується до всіх озвучок цього API-акаунта. Не розбивай весь текст на склади і не вигадуй IPA: кожну фонетичну заміну спочатку треба прослухати.
Промпт для Claude / ChatGPT
Встав промпт перед сценарієм. AI проаналізує весь текст, а не лише слово «Тарас», і поверне готовий варіант для SONA.
Ти — редактор тексту для озвучення SONA.
Проаналізуй увесь текст у контексті та підготуй його до природної машинної озвучки.
Правила:
1. Не змінюй зміст, стиль, факти та мову.
2. Збережи природну пунктуацію і абзаци — вони керують паузами.
3. Знайди слова, які TTS може прочитати неправильно. Особливо перевір:
- імена та прізвища;
- географічні назви;
- бренди, назви продуктів і компаній;
- абревіатури;
- іншомовні вставки й запозичення;
- рідкісні терміни та омографи.
4. Якщо неоднозначний лише наголос, постав U+0301 після наголошеної голосної:
за́мок / замо́к, му́ка / мука́.
5. Якщо знака наголосу може бути недостатньо і правильна вимова тобі достовірно
відома, перепиши ЛИШЕ проблемне слово фонетично:
- розділи його на зручні для читання частини дефісами;
- наголошений склад напиши ВЕЛИКИМИ літерами;
- збережи відмінкове закінчення конкретної форми слова.
6. Не обмежуйся словом «Тарас». Самостійно знаходь інші проблемні слова за
контекстом, але не вигадуй вимову, якщо не впевнений.
7. Орієнтири формату:
- Тарас → та-РАС
- OpenAI → оупен-ей-АЙ
- ChatGPT → чат-джі-пі-ТІ
- Renault → ре-НО
8. Не розбивай звичайні слова на склади, не вставляй IPA і не переписуй увесь текст
фонетично. Уже наявні теги <emotion value="..."/> збережи без змін.
9. Поверни лише готовий текст для озвучення без пояснень, списків і коментарів.
Мій текст:
"""
[ВСТАВ ТЕКСТ]
"""Теги в тексті
Поля speed, volume і emotion задають одну манеру на всю озвучку. Ті самі три контролі можна поставити прямо в текст — і додати паузу, вимову по літерах та смішок. Теги працюють на sona-3.5 і sona-3.6; [laughter] розрахований на sona-3.6, типову модель; з "model":"sona-3.5" на нього не розраховуй.
<speed ratio="0.8"/> | 0.6–1.5 | від цього місця й далі |
<volume ratio="0.5"/> | 0.5–2.0 | від цього місця й далі |
<emotion value="sad"/> | список нижче | від цього місця й далі |
<break time="700ms"/> | ms або s, до 10 с | одна пауза тут |
<spell>Bob</spell> | — | вимовити по літерах |
[laughter] | — | один смішок тут |
<volume ratio="0.6"/><speed ratio="0.8"/>Тут подаю тихіше й повільніше.<break time="1s"/>
<volume ratio="1"/><speed ratio="1"/>А тут уже як завжди.
<emotion value="excited"/> Не повіриш, що я дізнався! [laughter]
<emotion value="sad"/> Але потім усе пішло не так…Великі літери, кому замість точки й забутий слеш ми виправляємо самі (<SPEED RATIO="0,8"> → <speed ratio="0.8"/>), а поламаний тег повертає 422 з поясненням — щоб він не «не спрацював» тихо. Текст у кутових дужках, що не є тегом, озвучується як цитата: <<Стій!>> стає «Стій!», 5 < 10 > 3 — 5 ‹ 10 › 3 (без цього рушій мовчки пропускав усе в дужках). HTML-теги на кшталт <b> не звучать. Довгий текст ми ріжемо на частини й самі перевідкриваємо активні speed/volume/emotion у кожній наступній, тому їхня дія не обривається посеред озвучки.
emotion поки в стані beta й найкраще звучить англійською — на інших мовах різниця може бути не чутна; speed і volume — підказка, а не точний множник. <break> розриває генерацію в цьому місці, тому кілька пауз поспіль звучать неприродно. Символи тегів входять у chars, а в субтитри не потрапляють: там лишається тільки те, що звучить.
Повний список · 58 емоцій
neutral, happy, excited, enthusiastic, elated, euphoric, triumphant, amazed, surprised, flirtatious, curious, content, peaceful, serene, calm, grateful, affectionate, trust, sympathetic, anticipation, mysterious, angry, mad, outraged, frustrated, agitated, threatened, disgusted, contempt, envious, sarcastic, ironic, sad, dejected, melancholic, disappointed, hurt, guilty, bored, tired, rejected, nostalgic, wistful, apologetic, hesitant, insecure, confused, resigned, anxious, panicked, alarmed, scared, proud, confident, distant, skeptical, contemplative, determined
Генерація зображень
Генерація з тексту та з фото-референсом.
POST /v1/images | JSON: prompt, model, size → image_id. Prefer: respond-async повертає 202 одразу. |
POST /v1/images/edit | multipart із повторюваним полем images: Nano Banana 2.1 / Pro і GPT Image 2.5 — до 10 файлів |
GET /v1/images/{image_id} | Статус задачі. Якщо error: пояснення в detail і error_code — content_refused (модель відхилила сам запит, refusal_reason як у відео, retryable:false — змініть промпт) або generation_failed (retryable:true); оплата повертається сама |
GET /v1/images/{image_id}/file | Завантажити файл |
GET /v1/images?limit=20 | Історія акаунта |
Приклад
# пакет Nano або раніше придбані кредити: billing_source можна не вказувати (auto)
curl -X POST https://api.sonapro.ai/v1/images \
-H "X-API-Key: $SONA_API_KEY" \
-H "Content-Type: application/json" \
-H "Prefer: respond-async" \
-d '{"prompt":"Cinematic portrait in soft blue light","model":"nano-banana-2","size":"1024x1024"}'
# PAYG-баланс ($0.015): billing_source:"payg" обов’язковий, без нього auto поверне 402
curl -X POST https://api.sonapro.ai/v1/images \
-H "X-API-Key: $SONA_API_KEY" \
-H "Content-Type: application/json" \
-H "Prefer: respond-async" \
-d '{"prompt":"Cinematic portrait in soft blue light","model":"nano-banana-2","size":"1024x1024","billing_source":"payg","max_amount_microusd":15000}'
# edit із кількома референсами (повторюй -F images=@... до ліміту моделі; для PAYG додай -F billing_source=payg)
curl -X POST https://api.sonapro.ai/v1/images/edit \
-H "X-API-Key: $SONA_API_KEY" -H "Prefer: respond-async" \
-F 'prompt=Збережи людей і обʼєднай композицію' \
-F 'model=nano-banana-pro' \
-F 'images=@reference-1.jpg' -F 'images=@reference-2.png'
# GPT Image 2.5 через PAYG ($0.03); із раніше придбаними кредитами billing_source можна не вказувати
curl -X POST https://api.sonapro.ai/v1/images \
-H "X-API-Key: $SONA_API_KEY" \
-H "Content-Type: application/json" \
-H "Prefer: respond-async" \
-d '{"prompt":"Cinematic portrait in soft blue light","model":"gpt-image-2.5","size":"2048x1152","billing_source":"payg","max_amount_microusd":30000}'
# опитуй GET /v1/images/IMAGE_ID до status=done, потім завантаж download_urlРозміри (size)
size | Формат | Nano Banana 2.1 / Pro | GPT Image 2.5 |
|---|---|---|---|
1024x1024 | 1:1, квадрат | 1024×1024 | ≈1254×1254 |
2048x1152 | 16:9, широкий | 2048×1152 | ≈1672×941 |
1152x2048 | 9:16, вертикальний | 1152×2048 | ≈941×1672 |
1536x1152 | 4:3, альбомний | 1536×1152 | ≈1448×1086 |
1152x1536 | 3:4, портретний | 1152×1536 | ≈1086×1448 |
За замовчуванням — 1024x1024; інші значення повертають 422. Nano Banana віддає файл рівно запитаного розміру. Для GPT Image 2.5 size обирає лише пропорцію: файл приходить у власній роздільності моделі (~1,5 Мп), без апскейлу. Той самий size приймає POST /v1/images/edit.
Моделі
| Модель | model | Референси | Оплата |
|---|---|---|---|
| Nano Banana 2.1 | nano-banana-2 | до 10 | пакет Nano, PAYG або раніше придбані кредити |
| Nano Banana Pro | nano-banana-pro | до 10 | те саме, що й Nano Banana 2.1: спільний денний ліміт пакета |
| GPT Image 2.5 | gpt-image-2.5 | до 10 | PAYG — $0.03 або раніше придбані кредити (за тарифом покупки) |
Не хардкодь список: GET /v1/me повертає в image.model_options лише моделі, доступні саме цьому акаунту, разом із ціною (billing_options). Поле model обов’язкове — моделі за замовчуванням немає.
Як оплачується зображення
- Пакет Nano на 30 днів: Старт $27 — 600 зображень на день, 5 одночасно; Про $45 — 1 200 на день, 7 одночасно; Ультра $90 — 3 500 на день, 14 одночасно. Nano Banana 2.1 і Pro рахуються в один денний ліміт; невикористаний ліміт не переноситься.
- PAYG — $0.015 за генерацію з грошового балансу. Лише явно: передай
billing_source:"payg"(у multipart — полеbilling_source=payg). Щоб зафіксувати ціну, додайmax_amount_microusd. - Раніше придбані кредити — 1 000 за Nano Banana 2.1 або Pro.
- GPT Image 2.5 — PAYG, $0.03 за зображення (
billing_source:"payg"), або кредити, придбані до переходу на пакети, — за тарифом покупки (Start 2 500 · Pro 3 333 · Business 6 000 · Ultra 9 000),autoбере їх першими. Пакети й кредити, куплені після переходу, її не оплачують: без старих кредитівautoповертає402.sizeзадає тільки пропорцію — файл приходить у власній роздільності моделі (~1,5 Мп, напр. 1672×941 для 16:9). Старі IDgpt-image-2іsona-imageприймаються.
Типове billing_source:"auto" бере пакет, а без пакета — раніше придбані кредити. Гроші з PAYG воно не витрачає ніколи: якщо ні пакета, ні кредитів немає, прийде 402. Якщо генерація не вдалася, оплата повертається автоматично. Зображення віддаються в оригіналі 1080 так, як їх генерує модель, без апскейлу. quality=2k вимкнено, воно повертає 422.
Генерація відео
Veo 3.1 · 720p · з тексту й з референсами — 8 с, від першого кадру — зараз 6 с · один ендпоінт для тексту й фото.
POST /v1/videos | Створити відео → 202 + video_id. JSON — відео з тексту; multipart/form-data — відео з 1–3 фото |
GET /v1/videos/{video_id} | Статус: queued → processing → done або error |
GET /v1/videos/{video_id}/file | Завантажити MP4 (H.264 + AAC) |
GET /v1/videos?limit=20 | Історія відео акаунта |
Параметри
| Поле | За замовч. | Опис |
|---|---|---|
prompt * | — | Що відбувається в кадрі, до 4000 символів |
model | veo-3.1 | Єдина модель відео |
aspect_ratio | 16:9 | 16:9 (горизонтальне) або 9:16 (вертикальне) |
images | — | Лише multipart, повторюване поле, PNG/JPEG/WEBP до 10 МБ. 1 фото — перший кадр; 2 — перший і останній кадри; 3 — референси (персонаж, предмет, стиль). Більше трьох — 422 |
image_mode | за кількістю | Роль фото замість правила кількості: frames — 1–2 фото як перший / перший і останній кадр; references — 1–3 фото як референси. frames із трьома фото — 422 |
resolution | 720p | 720p або 1080p. 1080p — лише з billing_source:"payg", $0.03; якщо 1080p зараз недоступне — 503, нічого не списується. Статус повертає resolution готового файла: коли збільшення до 1080p не вдалося, приходить 720p і списується $0.02 |
billing_source | auto | auto, plan або payg — як і для зображень |
max_amount_microusd | — | Стеля ціни для PAYG; дорожче — 409 без списання |
Відповідь завжди асинхронна: відео рендериться від 1 до кількох хвилин, тож POST одразу повертає 202, а готовий файл забираєш за download_url зі статусу. Відео з тексту — 8 с. Тривалість відео з фото задає сервіс рендеру: від першого кадру (1–2 фото) зараз 6 с, з трьома референсами — 8 с. Тому до завершення duration_s для нього дорівнює null. У готовому відео duration_s — справжня тривалість файлу.
Приклад
# 1. Відео з тексту
curl -X POST https://api.sonapro.ai/v1/videos \
-H "X-API-Key: $SONA_API_KEY" -H "Content-Type: application/json" \
-d '{"prompt":"Паперовий кораблик пливе ставком на світанку","aspect_ratio":"16:9"}'
# → 202 {"video_id":"...","status":"queued","model":"veo-3.1","status_url":"/v1/videos/..."}
# 2. Відео з фото: перший кадр — твоє зображення
curl -X POST https://api.sonapro.ai/v1/videos \
-H "X-API-Key: $SONA_API_KEY" \
-F 'prompt=Камера повільно наближається, листя ворушить вітер' \
-F 'aspect_ratio=9:16' \
-F 'images=@first-frame.jpg'
# 3. Опитуй статус до done і забери MP4
curl https://api.sonapro.ai/v1/videos/VIDEO_ID -H "X-API-Key: $SONA_API_KEY"
curl https://api.sonapro.ai/v1/videos/VIDEO_ID/file -H "X-API-Key: $SONA_API_KEY" -o clip.mp4Доступ і оплата
- Відео доступне кожному акаунту. Якщо менеджер вимкнув Veo для акаунта,
POST /v1/videosповертає403, аGET /v1/meпоказуєvideo.allowed:false. - Пакет Veo на 30 днів, кількість відео необмежена: Старт $45 — 2 відео одночасно; Про $95 — 6; Ультра $140 — 10. Пакет підключає менеджер.
- PAYG — $0.02 за відео з грошового балансу, лише явно: передай
billing_source:"payg". Щоб зафіксувати ціну, додайmax_amount_microusd(20000). Відео 1080p (resolution:"1080p") — $0.03 (30000), лише через PAYG.
GET /v1/me → video: allowed, models, aspect_ratios, duration_s, max_references, resolutions (доступні зараз) і billing_options — ціна для цього акаунта. Якщо рендер не вдався, статус повертає error із поясненням у detail, і оплата повертається сама. Поле error_code: content_refused — модель відхилила сам запит за своїми правилами (refusal_reason: real_person, intellectual_property, minor, audio, sexual, violence, unsafe, prohibited, prompt або policy; retryable:false — змініть промпт або зображення), або generation_failed (retryable:true). Той самий запит (промпт + зображення), відхилений двічі (через звук — тричі), 24 год не приймається: POST одразу відповідає 422, нічого не списується.
Результат і помилки
Статуси задачі, файли, субтитри і HTTP-коди.
Життєвий цикл
queued→processing→doneТакож можливі error і canceled. Аудіо, зображення й відео зберігаються обмежений час; після видалення endpoint поверне 410.
Історія задач — GET /v1/activity
Останні задачі акаунта, якому належить ключ: озвучки, зображення й відео разом. Незавершені (queued, processing) ідуть першими, далі — від найновіших. Так видно, які запити вже виконано, а які ні, навіть якщо job_id загубився.
kind | voice, image або video; кілька — через кому. Без параметра — усі. |
status | queued, processing, done, error або canceled; кілька — через кому. Без параметра — усі. |
limit | Скільки задач повернути: від 1 до 100, за замовчуванням 12. |
curl "https://api.sonapro.ai/v1/activity?kind=voice&status=queued,processing,error&limit=50" -H "X-API-Key: $SONA_API_KEY"Відповідь, скорочено:
{
"jobs": [
{"id": "3f9c2a…", "kind": "voice", "name": "chapter_2", "status": "processing",
"created_at": "2026-10-09T10:27:03+00:00", "finished_at": null},
{"id": "8a41d0…", "kind": "voice", "name": "chapter_1", "status": "done",
"created_at": "2026-10-09T10:12:40+00:00", "finished_at": "2026-10-09T10:13:05+00:00"}
],
"payments": []
}id — це job_id озвучки, image_id зображення або video_id відео: статус і файл забирай звичайними запитами (/v1/tts/{job_id}/audio, /v1/images/{image_id}/file, /v1/videos/{video_id}/file). Файли зберігаються обмежений час, запис в історії лишається. Невідоме значення kind чи status повертає 422. payments — останні платежі акаунта.
Субтитри
Передай subtitles:true під час створення. Потім забери srt, vtt, ass, json або zip; ZIP містить аудіо і всі формати разом.
HTTP-коди
400 | Некоректний формат запиту |
401 | Відсутній або невірний API-ключ |
402 | Недостатньо кредитів, немає активного пакета або порожній PAYG-баланс |
403 | Модель або продукт не підключені цьому акаунту (напр. відео, поки його не увімкнув менеджер) |
404 | Ресурс не знайдено |
409 | Ціна вища за передану стелю (max_credits / max_amount_microusd) — нічого не списано |
410 | Файл уже видалено за строком зберігання |
422 | Невірне поле, ID голосу або межа параметра |
429 | Забагато запитів, зайняті всі одночасні задачі або вичерпано денний ліміт пакета |
503 | Сервіс/голос тимчасово недоступний; враховуй Retry-After |