Автоматически распознаёт речь в видео и добавляет стилизованные субтитры, которые можно сразу встроить в ролик. Цена зависит от разрешения и длительности: 480p - 15 ₽/мин, 720p - 15 ₽/мин, 1080p - 30 ₽/мин.
Общая документация Public API · API-ключ можно создать в настройках аккаунта
VEED Subtitles сам распознаёт речь в ролике и вшивает в картинку оформленные субтитры. На входе - ссылка на видео со звуком, на выходе - готовый MP4, где текст уже стоит в кадре по таймингам речи. Ничего расставлять вручную не нужно.
Где это пригодится:
Нейросеть понимает русский, английский, испанский, немецкий, французский, португальский и китайский. Язык можно определить автоматически или задать явно. Субтитры выводятся на языке речи, перевода нет.
Вызов создаёт асинхронную операцию: сначала вы получаете id, затем проверяете статус, пока не появится ссылка на готовое видео. Ролик на 15 секунд обрабатывается примерно минуту.
POST /api/v1/operationsAuthorization: Bearer brth_...id операции и стартовый статус queued.Режим у нейросети один: видео плюс настройки оформления. Ниже два сценария: язык определяется автоматически, и язык задан явно вместе со своим стилем, положением и разрешением 1080p.
{
"tool": "veed-subtitles",
"input": {
"video": "https://cdn.example.com/source-video-1.mp4",
"language": "auto",
"target_resolution": "720p",
"preset": "glide",
"position": "bottom",
"shadow": "mid"
}
}
tool - slug нейросети, всегда "veed-subtitles".input - параметры запуска. Поля передаются прямо внутри этого объекта, без дополнительной вложенности.Поля с вариантами в таблице помечены как обязательные, но их можно пропустить: сервер подставит значение, указанное в описании поля. Без чего запрос точно не пройдёт - это video.
| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
video | string (url) | Да | Ссылка на видео с речью. Один файл, только внешний http/https URL с расширением .mp4, .mov или .webm. В ролике должна быть звуковая дорожка. |
language | enum | Да | Язык речи в ролике. Варианты: auto - определить автоматически; ru-RU - русский; en-US - английский; es-ES - испанский; de-DE - немецкий; fr-FR - французский; pt-BR - португальский (Бразилия); zh-CN - китайский (упрощённый). auto подходит для большинства роликов; если в видео говорят на одном языке, явный выбор надёжнее. Если поле не передать, будет auto. |
target_resolution | enum | Да | Разрешение готового ролика: 480p, 720p или 1080p. Число задаёт высоту кадра, пропорции сохраняются. Влияет на цену: 1080p стоит вдвое дороже. Если поле не передать, будет 720p. |
preset | enum | Да | Стиль субтитров: шрифт, цвет, анимация. Варианты: simple - простой, plain - чистый, glass - стекло, whisper - шёпот, glide2, fusion, glide, terminal - терминал, handwritten - рукописный, beans, corpo, boo, shadeplay, casper, capri, lowkey, vinta, diego, ali, slay, kitty, hustle, karl, sprout, flex, mint, rizz, vegas. Если поле не передать, будет simple. |
position | enum | Да | Где стоят субтитры в кадре: top - сверху, center - по центру, bottom - снизу. Если поле не передать, будет bottom. |
shadow | enum | Да | Тень под текстом, чтобы его было видно на пёстром фоне: none - без тени, min - слабая, mid - средняя, max - сильная. Если поле не передать, будет mid. |
Как выглядит каждый стиль, удобно посмотреть в форме на странице нейросети /tools/veed-subtitles: значения preset в API те же.
Базовый вариант для ролика на любом из поддерживаемых языков: 720p, стиль glide, субтитры снизу.
curl -X POST https://bratuha.ru/api/v1/operations \
-H "Authorization: Bearer brth_ваш_ключ" \
-H "Content-Type: application/json" \
-d '{
"tool": "veed-subtitles",
"input": {
"video": "https://cdn.example.com/source-video-1.mp4",
"language": "auto",
"target_resolution": "720p",
"preset": "glide",
"position": "bottom",
"shadow": "mid"
}
}'
const response = await fetch('https://bratuha.ru/api/v1/operations', {
method: 'POST',
headers: {
Authorization: 'Bearer brth_ваш_ключ',
'Content-Type': 'application/json',
},
body: JSON.stringify({
tool: 'veed-subtitles',
input: {
video: 'https://cdn.example.com/source-video-1.mp4',
language: 'auto',
target_resolution: '720p',
preset: 'glide',
position: 'bottom',
shadow: 'mid',
},
}),
})
const operation = await response.json()
console.log(operation.id, operation.status, operation.cost)
import requests
response = requests.post(
'https://bratuha.ru/api/v1/operations',
headers={
'Authorization': 'Bearer brth_ваш_ключ',
'Content-Type': 'application/json',
},
json={
'tool': 'veed-subtitles',
'input': {
'video': 'https://cdn.example.com/source-video-1.mp4',
'language': 'auto',
'target_resolution': '720p',
'preset': 'glide',
'position': 'bottom',
'shadow': 'mid',
},
},
timeout=30,
)
print(response.status_code)
print(response.json())
Язык задан явно, стиль hustle, сильная тень для яркого фона. Такой вариант подходит для вертикальных роликов в соцсети.
curl -X POST https://bratuha.ru/api/v1/operations \
-H "Authorization: Bearer brth_ваш_ключ" \
-H "Content-Type: application/json" \
-d '{
"tool": "veed-subtitles",
"input": {
"video": "https://cdn.example.com/interview-en-1.mov",
"language": "en-US",
"target_resolution": "1080p",
"preset": "hustle",
"position": "center",
"shadow": "max"
}
}'
const response = await fetch('https://bratuha.ru/api/v1/operations', {
method: 'POST',
headers: {
Authorization: 'Bearer brth_ваш_ключ',
'Content-Type': 'application/json',
},
body: JSON.stringify({
tool: 'veed-subtitles',
input: {
video: 'https://cdn.example.com/interview-en-1.mov',
language: 'en-US',
target_resolution: '1080p',
preset: 'hustle',
position: 'center',
shadow: 'max',
},
}),
})
const operation = await response.json()
import requests
response = requests.post(
'https://bratuha.ru/api/v1/operations',
headers={
'Authorization': 'Bearer brth_ваш_ключ',
'Content-Type': 'application/json',
},
json={
'tool': 'veed-subtitles',
'input': {
'video': 'https://cdn.example.com/interview-en-1.mov',
'language': 'en-US',
'target_resolution': '1080p',
'preset': 'hustle',
'position': 'center',
'shadow': 'max',
},
},
timeout=30,
)
print(response.json())
Ответ на ролик длиной 15 секунд в 720p:
{
"id": "op_uuid-123",
"status": "queued",
"tool": "veed-subtitles",
"cost": 15,
"balance_after": 485,
"created_at": "2026-09-30T19:48:38.796039+00:00"
}
{
"id": "op_uuid-123",
"status": "completed",
"tool": "veed-subtitles",
"cost": 15,
"created_at": "2026-09-30T19:48:38.796039+00:00",
"completed_at": "2026-09-30T19:49:49.671004+00:00",
"result": {
"type": "video",
"urls": [
"https://storage.bratuha.ru/results/veed-subtitles/result-1.mp4"
]
},
"error_message": null
}
Пока операция выполняется, status будет queued или processing, а result - null. Если обработка не удалась, придёт status: "failed" и текст причины в error_message.
Сохраните id из ответа на создание и запрашивайте операцию по нему:
GET /api/v1/operations/{id}
curl -H "Authorization: Bearer brth_ваш_ключ" \
https://bratuha.ru/api/v1/operations/op_uuid-123
Пример ожидания результата на JavaScript / TypeScript:
async function waitForVideo(id: string): Promise<string> {
while (true) {
const res = await fetch(`https://bratuha.ru/api/v1/operations/${id}`, {
headers: { Authorization: 'Bearer brth_ваш_ключ' },
})
const op = await res.json()
if (op.status === 'completed') return op.result.urls[0]
if (op.status === 'failed') throw new Error(op.error_message)
await new Promise((r) => setTimeout(r, 5000))
}
}
Статус одной операции можно запрашивать не чаще раза в секунду, иначе придёт 429. Здесь достаточно опроса раз в 5-10 секунд.
{
"type": "video",
"urls": [
"https://storage.bratuha.ru/results/veed-subtitles/result-1.mp4"
]
}
type - "video".urls - массив ровно из одной ссылки на готовый MP4.Субтитры вшиты в картинку, отдельного файла SRT или VTT нет. Звук, длительность и частота кадров остаются как у исходника, размер кадра меняется под target_resolution: вертикальный ролик 720×1264 с 720p пришёл в размере 410×720.
Цена считается за каждую начатую минуту видео и зависит от разрешения:
| Разрешение | Цена за начатую минуту |
|---|---|
480p | 15 ₽ |
720p | 15 ₽ |
1080p | 30 ₽ |
Длительность сервер измеряет сам по файлу, передавать её не нужно. Любой неполный отрезок считается целой минутой: ролик на 15 секунд стоит как минута, а ролик на 1 минуту 1 секунду - как две.
| Длительность видео | 480p / 720p | 1080p |
|---|---|---|
| до 1 минуты | 15 ₽ | 30 ₽ |
| от 1:01 до 2:00 | 30 ₽ | 60 ₽ |
| 5 минут | 75 ₽ | 150 ₽ |
Язык, стиль, положение и тень на цену не влияют. 480p и 720p стоят одинаково, поэтому 480p имеет смысл брать только ради лёгкого файла. Сумма списывается при создании операции, поле cost в ответе показывает её точно.
POST /api/v1/operations не идемпотентен: каждый повторный запрос создаёт новую операцию и списывает деньги ещё раз. Если ответ на POST потерялся, не отправляйте тот же запрос вслепую.queued, результат забирайте через GET /api/v1/operations/{id}. Обычно ролик готов за минуту-полторы, в загруженные часы ожидание может растянуться до нескольких минут.video принимаются только внешние http/https ссылки с расширением .mp4, .mov или .webm. Ссылки на localhost и внутренние адреса отклоняются с validation_error. Файл должен открываться без авторизации и весить не больше 128 МБ.auto.target_resolution задаёт высоту кадра. У вертикальных видео итоговая ширина получается заметно меньше: при 720p ширина около 400 пикселей. Если важна чёткость вертикального ролика, выбирайте 1080p.