API: расшифровка и озвучка из кода
Оба сервиса доступны программно по адресу https://bowhard.ru/api/tools.
Отдельный ключ не нужен: сервис выдаёт подписанную cookie tools_id, по ней считаются ваши
задачи и бесплатные лимиты. Запрос принимает файл или текст, возвращает идентификатор задачи, дальше
результат забирается опросом. Примеры ниже — на curl, Python и Node.js, всё без
сторонних библиотек.
Методы
| Метод | Что делает | Тело запроса |
|---|---|---|
POST /api/tools/stt |
Расшифровка аудио и видео | multipart/form-data, поле file; до 2048 МБ (mp3, wav, ogg, m4a, mp4, mov, mkv — всё, что читает ffmpeg) |
POST /api/tools/link |
Расшифровка по ссылке | application/json: {"url": "https://disk.yandex.ru/..."}. Только публичные ссылки Яндекс.Диска и Dropbox, не больше 10 в час с одного адреса |
POST /api/tools/tts |
Озвучка текста | {"text": "...", "voice": "alena", "speed": 1.0} — от 3 до 100 000 знаков, скорость от 0,5 до 2,0 |
GET /api/tools/job/<id> |
Состояние задачи | Поля ответа: status, durationSec, chars, cost, urls |
GET /api/tools/job/<id>/file/<kind> |
Результат | kind: txt — текст, srt — субтитры, json — текст со словами и таймкодами, mp3 — озвучка |
GET /api/tools/prices |
Цены и остатки | Тарифы, свободные минуты и знаки на сегодня |
GET /api/tools/voices |
Список голосов | 15 русских голосов, у каждого — подсказка, кому подходит |
Расшифровка: загрузка файла
Cookie сохраняйте между запросами — иначе следующая задача откроется как чужая.
# 1. отправляем файл (cookie пишем в файл)
curl -c cookie.txt -b cookie.txt \
-F "file=@meeting.mp3" \
https://bowhard.ru/api/tools/stt
{"jobId":"2f1c…","status":"queued"}
# 2. опрашиваем состояние раз в пару секунд
curl -c cookie.txt -b cookie.txt \
https://bowhard.ru/api/tools/job/2f1c…
{"status":"done","durationSec":1834.4,"cost":0}
# 3. забираем результат: текст, субтитры или JSON с таймкодами слов
curl -c cookie.txt -b cookie.txt \
https://bowhard.ru/api/tools/job/2f1c…/file/srt -o meeting.srt
Озвучка: текст в mp3
curl -c cookie.txt -b cookie.txt \
-H "Content-Type: application/json" \
-d '{"text":"Здравствуйте! Это проверка озвучки.","voice":"alena","speed":1.0}' \
https://bowhard.ru/api/tools/tts
{"jobId":"8a04…","status":"queued","chars":38}
curl -c cookie.txt -b cookie.txt \
https://bowhard.ru/api/tools/job/8a04…/file/mp3 -o voice.mp3
Python — только стандартная библиотека
import http.cookiejar, json, time, urllib.request
BASE = "https://bowhard.ru/api/tools"
opener = urllib.request.build_opener(
urllib.request.HTTPCookieProcessor(http.cookiejar.CookieJar())
)
def request(path, data=None, headers=None):
req = urllib.request.Request(BASE + path, data=data, headers=headers or {})
with opener.open(req, timeout=600) as r:
body = r.read()
return json.loads(body) if body[:1] in (b"{", b"[") else body
def transcribe(path):
boundary = "----bowhard"
with open(path, "rb") as fh:
payload = fh.read()
body = (
f"--{boundary}\r\nContent-Disposition: form-data; "
f'name="file"; filename="{path.split("/")[-1]}"\r\n'
f"Content-Type: application/octet-stream\r\n\r\n"
).encode() + payload + f"\r\n--{boundary}--\r\n".encode()
job = request("/stt", body, {"Content-Type": f"multipart/form-data; boundary={boundary}"})
while True:
state = request(f"/job/{job['jobId']}")
if state["status"] in ("done", "error"):
return state
time.sleep(2)
state = transcribe("meeting.mp3")
print(state["status"], state["durationSec"])
print(request(f"/job/{state['jobId']}/file/txt").decode())
Node.js — обычный fetch
const BASE = 'https://bowhard.ru/api/tools';
let cookie = '';
async function call(path, init = {}) {
const res = await fetch(BASE + path, {
...init,
headers: { ...(init.headers || {}), cookie },
});
const set = res.headers.getSetCookie?.() || [];
if (set.length) cookie = set.map((c) => c.split(';')[0]).join('; ');
return res;
}
const form = new FormData();
form.append('file', new Blob([await fs.readFile('meeting.mp3')]), 'meeting.mp3');
const job = await (await call('/stt', { method: 'POST', body: form })).json();
let state;
do {
await new Promise((r) => setTimeout(r, 2000));
state = await (await call(`/job/${job.jobId}`)).json();
} while (!['done', 'error'].includes(state.status));
console.log(await (await call(`/job/${job.jobId}/file/txt`)).text());
n8n
Отдельного узла не нужно — хватает штатного HTTP Request. Схема для голосовых из Telegram:
триггер → узел Telegram (Get File) → HTTP Request на /api/tools/stt → узел Wait (2 секунды)
→ HTTP Request на /api/tools/job/<id> → проверка status → HTTP Request на
…/file/txt → ответ в чат. Готовые шаблоны наших сценариев лежат в открытом репозитории
github.com/VavilkinAlex/n8n-bowhard-templates.
Готовые клиенты
Если не хочется писать обёртку самому, возьмите наш клиент — он без зависимостей, работает поверх того же HTTP API и умеет всё: загрузку файла, ожидание задачи, текст, SRT и JSON с таймкодами слов, озвучку в MP3. Репозиторий открыт: github.com/VavilkinAlex/bowhard-speech.
- Python 3.9+ —
pip install https://github.com/VavilkinAlex/bowhard-speech/releases/download/v0.1.0/bowhard_speech-0.1.0-py3-none-any.whl, затемfrom bowhard_speech import Client. Есть и консольная командаbowhard-speech. - Node 18+ —
npm install https://github.com/VavilkinAlex/bowhard-speech/releases/download/v0.1.0/bowhard-speech-0.1.0.tgzлибо из реестра GitHub:npm install @vavilkinalex/bowhard-speech --registry=https://npm.pkg.github.com.
Лимиты, цены и хранение
- Расшифровка. 15 минут в сутки бесплатно, дальше 25 ₽ за час записи (минимальный платёж 15 ₽). Пакеты: 4 часа — 99 ₽, 10 часов — 249 ₽.
- Озвучка. 5 000 знаков в сутки бесплатно, дальше 3,9 ₽ за 1 000 знаков. Пакеты: 25 000 знаков — 99 ₽, 100 000 знаков — 390 ₽.
- Очередь. Два файла обрабатываются одновременно, остальные ждут — статус видно в поле
status(queued,processing,done,error). - Хранение. Файлы и результаты удаляются через 24 часа; статистика по задачам — 90 дней.
- Данные. Расшифровка и синтез идут на серверах Яндекса в России, за границу данные не уходят.
Частые вопросы
Нужен ли ключ для доступа к API?
Отдельный ключ не нужен: сервис выдаёт подписанную cookie tools_id, по ней и считается
ваш объём. Сохраняйте cookie между запросами — тогда видно историю задач и остаток бесплатных лимитов.
Сколько стоит расшифровка и озвучка через API?
Цены те же, что на сайте: расшифровка — 15 минут в сутки бесплатно, дальше 25 ₽ за час; озвучка — 5 000 знаков в сутки бесплатно, дальше 3,9 ₽ за 1 000 знаков. Пакеты выгоднее: 4 часа за 99 ₽, 10 часов за 249 ₽, 25 000 знаков за 99 ₽, 100 000 знаков за 390 ₽.
Как быстро приходит результат?
Идентификатор задачи приходит сразу, состояние опрашивается раз в пару секунд. Расшифровка идёт примерно со скоростью, близкой к реальному времени записи; озвучка 10 000 знаков занимает около минуты.
Можно ли отдать файл ссылкой?
Да, методом /link. Принимаются публичные ссылки Яндекс.Диска и Dropbox — не больше
десяти в час с одного адреса. Приватные ссылки и произвольные адреса не принимаются: сервис проверяет
адрес после всех перенаправлений.
Сколько хранятся файлы и результаты?
Файлы и результаты удаляются через 24 часа. Расшифровка идёт на серверах Яндекса в России, за границу данные не уходят.
Есть ли готовые клиенты?
API — обычный HTTP, поэтому достаточно штатных средств: urllib в Python,
fetch в Node, HTTP Request в n8n. Если нужна обёртка под вашу систему или пакетная
обработка папки, напишите на mail@bowhard.ru — соберём под задачу.
Проверить сервис без интеграции можно на страницах расшифровки и озвучки — там те же методы, но мышкой.