convr Увійти

REST · JSON · Webhooks

API для розробників

Усе, що вміє сайт, — із вашого коду: конвертація, стиснення, нарізка, розпізнавання мовлення, імпорт за посиланням. JSON через HTTPS, ключ у заголовку, вебхук після готовності.

Отримати ключ → Базова адресаhttps://convr.app/api/v1

Огляд

Базова адреса — https://convr.app/api/v1. Запити й відповіді — JSON в UTF-8, запитам із тілом потрібен заголовок Content-Type: application/json. Час — RFC 3339 в UTC, розміри — в байтах, тривалості — в секундах.

Звичайний сценарій:

  • створити завдання (POST /jobs) — з назвою й розміром файлу або з посиланням;
  • завантажити файл напряму в сховище за виданим посиланням і повідомити POST /jobs/{id}/uploaded;
  • дочекатися state: "done" — вебхуком або опитуванням GET /jobs/{id};
  • отримати посилання на результат: GET /jobs/{id}/download.

Файли не проходять через API-сервер: завантаження й скачування йдуть напряму в сховище та CDN, тож розмір файлу обмежує лише тариф.

Швидкий старт

export CONVR_KEY=cvk_…

# 1. create a job: what into what, and the file's name and size
curl -s -X POST https://convr.app/api/v1/jobs -H "Authorization: Bearer $CONVR_KEY" -H "Content-Type: application/json" \
  -d '{"converter":"mov-mp4","options":{"quality":"medium"},
       "file":{"name":"clip.mov","size":52428800}}'
# → {"batch_id":"…","job":{"id":"JOB","state":"awaiting_input",…},
#    "upload":{"put_url":"PUT_URL","headers":{"Content-Type":"video/quicktime"}}}

# 2. upload the file straight to storage (no API key here)
curl -X PUT "PUT_URL" -H "Content-Type: video/quicktime" --data-binary @clip.mov

# 3. start it
curl -s -X POST https://convr.app/api/v1/jobs/JOB/uploaded -H "Authorization: Bearer $CONVR_KEY"

# 4. poll until "state":"done", then take the result
curl -s https://convr.app/api/v1/jobs/JOB -H "Authorization: Bearer $CONVR_KEY"
curl -s https://convr.app/api/v1/jobs/JOB/download -H "Authorization: Bearer $CONVR_KEY"
# → {"url":"https://…","expires_at":"…"}

Ключ і доступ

Створіть ключ в особистому кабінеті і передавайте його в кожному запиті:

Authorization: Bearer cvk_…

  • ключ діє від імені акаунта: ті самі ліміти тарифу, та сама історія файлів;
  • працює лише на тарифах з API; якщо тариф скінчився — 403 plan_required;
  • ключ показується один раз, у нас зберігається лише його хеш; загубили — відкличте й створіть новий;
  • до 10 ключів на акаунт, відкликання діє миттєво;
  • ключем не можна керувати акаунтом: вхід, пароль, оплата, самі ключі — 403 not_for_keys.

Ніколи не вставляйте ключ у код сторінки чи мобільного застосунку: його звідти дістануть. Викликайте API зі свого сервера.

Ліміти

  • Частота: 120 запитів на хвилину на ключ (із запасом на короткі сплески). Понад — 429 rate_limited і заголовок Retry-After у секундах.
  • Тариф: розмір файлу, завдання на добу, одночасні завдання, тривалість відео, хвилини розпізнавання мовлення й термін зберігання результатів — як у вашого тарифу. Точні числа віддає GET /limits.
  • Посилання на завантаження живуть 15 хвилин, посилання на результат — 30 хвилин; нове посилання на результат можна отримати будь-коли, поки файл зберігається (expires_at завдання).
  • Опитуйте статус не частіше ніж раз на 2–3 секунди або використовуйте вебхуки.

Об’єкт завдання

Завдання — один файл, що перетворюється на один результат. Його повертають майже всі методи.

{
  "id": "01m6he8nmn6ykgpp3mzh4mek06",
  "state": "done",
  "progress": 100,
  "converter": "mov-mp4",
  "input_name": "clip.mov",
  "input_size": 52428800,
  "output_name": "clip.mp4",
  "output_size": 18874368,
  "expires_at": "2026-11-05T10:00:00Z",
  "input_ready": true
}
ТипОпис
idstringІдентифікатор завдання, 26 символів.
statestringСтан — див. таблицю нижче.
stagestringЕтап у роботі: fetching, probing, converting, uploading.
progressintПрогрес, 0–100.
converterstringКонвертер, наприклад mov-mp4.
input_namestringНазва вихідного файлу.
input_sizeintРозмір вихідного файлу, байт (у посилання — після завантаження).
output_namestringНазва результату.
output_sizeintРозмір результату, байт (коли готовий).
errorstringКод причини при failed.
expires_attimeКоли файли буде видалено.
deletedboolФайли вже видалено.
resultobjectДані аналізу чи розпізнавання (лише в scan і transcribe).
input_readyboolВихідний файл збережено, з ним можна запускати clips і transcribe.
КодHTTPОпис
awaiting_inputЧекає завантаження файлу.
queuedУ черзі.
leasedОбробляється.
done✓Готово, можна завантажити.
failed✓Не вдалося, причина в error.
canceled✓Скасовано.
expired✓Термін зберігання минув або файл так і не завантажили.

Кінцеві стани позначено ✓ — після них завдання не змінюється.

Конвертери й налаштування

Конвертер називається <з>-<в>: mov-mp4, mp4-mp3, png-webp, docx-pdf, pdf-jpg. Повний список із налаштуваннями кожного — GET /registry (сотні пар форматів відео, аудіо, зображень і документів). Обирайте конвертер за розширенням вихідного файлу.

options — об'єкт «ключ: значення». Усе необов'язкове, пропущене бере значення за замовчуванням; невідомий ключ чи значення поза списком — 400 invalid_options. Типи налаштувань у /registry:

ТипОпис
enumstringОдне з values, наприклад "1080".
intnumberЦіле від min до max.
boolbooleantrue або false.
timenumber | stringСекунди (12.5) або "хх:сс" / "гг:хх:сс".
textstringТекст до max символів.
rangesstringВідрізки "початок-кінець" у секундах через кому: "12-27,40.5-70".
assetstringid картинки з POST /assets (водяний знак).
optionsТипОпис
qualityenumВідео: high · medium · small.
target_mbenumВідео: стиснути до розміру, МБ — 8, 10, 16, 25, 50…
resolutionenumВідео: висота кадру — keep, 2160 … 360.
aspect / fitenumВідео: 9:16, 4:5, 1:1, 16:9; поля blur, обрізка crop або smart (за обличчями).
trim_start / trim_endtimeВідео й аудіо: обрізати початок і кінець.
vcodec / fpsenumВідео: h264 або h265; частота кадрів.
no_audio / volumebool / intПрибрати звук; гучність 0–300 %.
auto_subs / sub_lang / sub_stylebool / enumВідео: розпізнати мовлення й впекти субтитри; мова; стиль (tiktok, karaoke, beast, lyrics…).
title / wm_text / wm_imagetext / assetВідео: заголовок, текстовий або картинка-водяний знак.
bitrate / sample_rate / channelsenumАудіо: 128–320 кбіт/с; 44100/48000; mono/stereo.
resize / image_quality / stripenum / int / boolЗображення: ширина; якість 1–100; прибрати EXIF.
pages / dpienumPDF у картинки: all або first; 72/150/300.
gif_width / gif_fpsenumGIF: ширина й частота кадрів.

Завдання

POST /jobs

Створити завдання

Передайте або file (потім завантажте його за upload), або url — тоді файл завантажимо ми й завдання одразу стане в чергу.

У відповіді upload — одне з двох:

  • put_url і headers — файл до 64 МБ завантажується одним PUT із цими заголовками;
  • part_size, part_count, parts — більший файл завантажується частинами по part_size байт (остання коротша); у parts перші 50 посилань, решта — через POST /jobs/{id}/parts.

Для url блок upload порожній.

Тіло запиту (JSON)

ТипОпис
converterобов'язковоstringКонвертер із /registry, наприклад mov-mp4.
optionsobjectНалаштування конвертера.
file.namestringНазва файлу (до 1024 символів). З file.size — замість url.
file.sizeintТочний розмір файлу в байтах.
urlstringПосилання замість файлу: пряме, Google Drive, Dropbox, YouTube, TikTok, Instagram, Vimeo, X.
webhookstringКуди надіслати POST, коли завдання завершиться.
save_to_driveboolПокласти результат у хмару акаунта, коли він буде готовий.
drive_folderstringПапка хмари для результату (за замовчуванням — верхній рівень).
batch_idstringДодати завдання в наявний пакет (для ZIP і подій).

Приклад

curl -s -X POST https://convr.app/api/v1/jobs -H "Authorization: Bearer $CONVR_KEY" -H "Content-Type: application/json" \
  -d '{"converter":"mp4-mp4","options":{"target_mb":"25"},
       "file":{"name":"video.mp4","size":187654321}}'

Відповідь

201 Created
{
  "batch_id": "01m6he8m2e…",
  "job": { "id": "01m6he8nmn…", "state": "awaiting_input", … },
  "upload": {
    "put_url": "https://…",
    "headers": { "Content-Type": "video/quicktime" }
  }
}

// a file over 64 MB:
  "upload": {
    "part_size": 16777216,
    "part_count": 32,
    "parts": [{ "n": 1, "url": "https://…" }, …]
  }

Помилки

  • unknown_converter400 Немає такого конвертера — дивіться GET /registry.
  • invalid_options400 Невідоме налаштування або неприпустиме значення.
  • invalid_file400 Не вказано назву або розмір файлу.
  • invalid_url400 Посилання не http(s) або разом із ним передано файл.
  • invalid_webhook400 Адреса вебхука не http(s).
  • file_too_large413 Файл більший, ніж дозволяє тариф (limit — у байтах).
  • limit_active429 Забагато завдань виконується одночасно.
  • limit_daily429 Вичерпано добовий ліміт завдань.
  • speech_limit429 Вичерпано хвилини розпізнавання мовлення за 30 днів.
  • links_unavailable503 Завантаження з відеосайтів тимчасово недоступне.
PUT {put_url}

Завантажити файл

Запит іде напряму в сховище — без ключа API, із заголовками з upload.headers. Тіло — сам файл, рівно file.size байт. Посилання діє 15 хвилин.

Під час завантаження частинами: PUT кожної частини за її url, тіло — part_size байт (остання — залишок). Частини можна вантажити паралельно й у будь-якому порядку; збирати їх не треба.

Приклад

curl -X PUT "$PUT_URL" -H "Content-Type: video/mp4" --data-binary @video.mp4

# parts: split -b 16777216 big.mov part_ && upload part_aa to parts[0].url, …
curl -X PUT "$PART_1_URL" --data-binary @part_aa
POST /jobs/{id}/parts

Ще посилання на частини

Підписані посилання для частин від from до to включно, не більше 50 за раз.

Тіло запиту (JSON)

ТипОпис
fromобов'язковоintНомер першої частини (з 1).
toобов'язковоintНомер останньої частини.

Приклад

curl -s -X POST https://convr.app/api/v1/jobs/JOB/parts -H "Authorization: Bearer $CONVR_KEY" -H "Content-Type: application/json" -d '{"from":51,"to":100}'

Відповідь

{ "parts": [{ "n": 51, "url": "https://…" }, …] }

Помилки

  • bad_range400 from/to поза частинами файлу або понад 50 за раз.
  • no_upload409 Завдання не має незавершеного завантаження частинами.
POST /jobs/{id}/uploaded

Запустити після завантаження

Перевіряє, що файл завантажено повністю й потрібного розміру, і ставить завдання в чергу. Тіло не потрібне.

Приклад

curl -s -X POST https://convr.app/api/v1/jobs/JOB/uploaded -H "Authorization: Bearer $CONVR_KEY"

Відповідь

{ "id": "…", "state": "…", … }   // the job object

Помилки

  • upload_incomplete400 Файл (або частина) не завантажений повністю.
  • upload_size_mismatch400 Завантажено не стільки байтів, скільки вказано в file.size.
  • already_uploaded409 Завдання вже запущено.
GET /jobs/{id}

Статус завдання

Поточний стан, етап і прогрес.

Приклад

curl -s https://convr.app/api/v1/jobs/JOB -H "Authorization: Bearer $CONVR_KEY"

Відповідь

{ "id": "…", "state": "leased", "stage": "converting", "progress": 42, … }

Помилки

  • not_found404 Завдання немає або воно не ваше.
GET /jobs/{id}/download

Посилання на результат

Підписане посилання CDN на 30 хвилин (не довше терміну зберігання). Завантаження за ним — без ключа. Запитуйте знову, коли потрібно.

Приклад

curl -sL "$(curl -s https://convr.app/api/v1/jobs/JOB/download -H "Authorization: Bearer $CONVR_KEY" | jq -r .url)" -o result.mp4

Відповідь

{ "url": "https://dl.…/clip.mp4?token=…&expires=…", "expires_at": "2026-11-04T12:30:00Z" }

Помилки

  • not_ready409 Результату ще немає: завдання не в стані done.
  • not_found404 Завдання немає або воно не ваше.
POST /jobs/{id}/cancel

Скасувати

Зупиняє завдання, якщо воно ще не завершилося.

Приклад

curl -s -X POST https://convr.app/api/v1/jobs/JOB/cancel -H "Authorization: Bearer $CONVR_KEY"

Відповідь

{ "id": "…", "state": "…", … }   // the job object
DELETE /jobs/{id}

Видалити файли

Скасовує завдання й одразу видаляє вихідний файл і результат, не чекаючи терміну зберігання.

Приклад

curl -s -X DELETE https://convr.app/api/v1/jobs/JOB -H "Authorization: Bearer $CONVR_KEY"

Відповідь

204 No Content

Пакети

Кожне завдання входить у пакет (batch_id у відповіді на створення). Передайте той самий batch_id у наступні POST /jobs, щоб стежити за ними одним потоком подій або запакувати в ZIP.

GET /batches/{id}

Завдання пакета

Усі завдання пакета в порядку створення.

Відповідь

{ "id": "…", "jobs": [ { "id": "…", "state": "done", … }, … ] }
GET /batches/{id}/events

Потік подій (SSE)

Server-Sent Events: спершу snapshot з усіма завданнями, потім job за кожної зміни. З’єднання тримається відкритим; після обриву перепідключайтеся — знову прийде snapshot.

Приклад

curl -N https://convr.app/api/v1/batches/BATCH/events -H "Authorization: Bearer $CONVR_KEY"

Відповідь

event: snapshot
data: [{"id":"…","state":"queued",…}]

event: job
data: {"id":"…","state":"leased","stage":"converting","progress":37,…}
POST /batches/{id}/zip

Запакувати в ZIP

Створює завдання-архів з усіх готових результатів пакета (від двох). Повторний виклик для того самого набору поверне той самий архів.

Відповідь

{ "id": "…", "state": "…", … }   // the job object

Помилки

  • nothing_to_zip400 У пакеті менше двох готових результатів.
  • zip_too_large413 Архів вийшов би завеликим.

Хмара

Файли акаунта без строку зберігання, у папках, у межах місця тарифу. Завантаження — як у завдань: посилання на PUT або частини. Файл із хмари конвертується без повторного завантаження, результат лягає в ту саму папку.

GET /drive

Вміст папки

Папки й файли, шлях до папки, зайняте місце та квота.

Параметри рядка запиту

ТипОпис
folderstringПапка; без неї — верхній рівень.
qstringПошук за назвою в усіх папках.

Відповідь

{ "folder": null, "path": [], "folders": [ { "id": "…", "name": "Работа", "files": 3, "size": 1048576 } ],
  "files": [ { "id": "…", "name": "report.pdf", "size": 52011, "format": "pdf", "state": "ready" } ],
  "used": 1100587, "quota": 2147483648, "count": 4 }
POST /drive/files

Завантажити файл

Резервує місце й видає посилання для завантаження (як POST /jobs). Після завантаження — POST /drive/files/{id}/uploaded.

Тіло запиту (JSON)

ТипОпис
nameобов'язковоstringНазва файлу.
sizeобов'язковоintРозмір у байтах.
folderstringПапка.

Відповідь

{ "file": { "id": "…", "state": "uploading", … }, "upload": { "put_url": "…", "headers": { … } } }

Помилки

  • drive_full
  • drive_unavailable
  • file_too_large413 Файл більший, ніж дозволяє тариф (limit — у байтах).
POST /drive/files/{id}/convert

Конвертувати з хмари

Створює завдання, яке читає файл просто з хмари; результат кладеться в папку файлу (save: false — не класти).

Тіло запиту (JSON)

ТипОпис
converterобов'язковоstringКонвертер для формату файлу.
optionsobjectНалаштування.
folderstringІнша папка для результату.

Відповідь

{ "id": "…", "state": "…", … }   // the job object
POST /jobs/{id}/drive

Результат — у хмару

Копіює готовий результат завдання в хмару (всередині сховища, без завантаження).

Тіло запиту (JSON)

ТипОпис
folderstringПапка.

Помилки

  • drive_full
  • not_ready409 Результату ще немає: завдання не в стані done.
GET /drive/files/{id}/url

Посилання на завантаження

Підписане посилання CDN на час.

Відповідь

{ "url": "https://…", "expires_at": "…" }
PATCH /drive/files/{id}

Перейменувати або перемістити

name та/або folder ("" — верхній рівень). Папки — PATCH /drive/folders/{id} з name і parent.

DELETE /drive/files/{id}

Видалити файл

Одразу звільняє місце. Папка видаляється разом із вмістом: DELETE /drive/folders/{id}.

Кліпи й мовлення

Відео завантажується один раз як завдання-аналіз <формат>-scan, після чого з нього можна скільки завгодно разів різати кліпи й розпізнавати мовлення — без повторного завантаження, поки завдання зберігається.

POST /jobs {"converter":"mp4-scan"}

Аналіз відео

Звичайне створення завдання з конвертером mp4-scan (mov-scan, mkv-scan…). Результат аналізу — у полі result готового завдання: гучність, зміни сцен і найкращі моменти для кліпів по 15, 30, 60 і 90 секунд з оцінкою 0–100. Аналіз завантаженого файлу не витрачає добовий ліміт завдань.

Відповідь

"result": {
  "duration": 312.4,
  "loudness": [0.12, 0.4, …],
  "scenes": [4.2, 17.9, …],
  "clips": {
    "30": [{ "start": 81.5, "end": 111.5, "score": 100 }, …],
    "60": [ … ]
  }
}
POST /jobs/{id}/clips

Нарізати кліпи

{id} — завдання scan. Один відрізок дає MP4, кілька — ZIP із кліпами. Доступні налаштування відео: aspect (за замовчуванням 9:16), fit, quality, заголовок, водяний знак, фільтри, музика.

Тіло запиту (JSON)

ТипОпис
options.rangesобов'язковоrangesДо 20 відрізків, кожен 1–600 с.
options.*Інші налаштування конвертера <формат>-clips з /registry.
webhookstringЯк у POST /jobs.

Приклад

curl -s -X POST https://convr.app/api/v1/jobs/SCAN/clips -H "Authorization: Bearer $CONVR_KEY" -H "Content-Type: application/json" \
  -d '{"options":{"ranges":"81.5-111.5,140-170","aspect":"9:16","fit":"smart",
       "title":"Best moments"}}'

Відповідь

201 Created
{ "id": "…", "converter": "mp4-clips", "state": "queued", … }

Помилки

  • not_a_scan400 {id} — не завдання аналізу (scan).
  • not_uploaded409 Відео завдання scan ще не завантажено.
  • source_gone409 Завдання scan скасовано або воно минуло — файлу більше немає.
  • invalid_options400 Невідоме налаштування або неприпустиме значення.
  • limit_active429 Забагато завдань виконується одночасно.
  • limit_daily429 Вичерпано добовий ліміт завдань.
POST /jobs/{id}/transcribe

Розпізнати мовлення

{id} — завдання scan. Слова з таймкодами приходять у result готового завдання. До 20 хвилин мовлення за завдання; витрачає хвилини розпізнавання тарифу.

Тіло запиту (JSON)

ТипОпис
options.rangesобов'язковоrangesЯкі відрізки розпізнати.
options.langenumauto, ru, uk, en, de, es, fr, it, pl, pt, tr, kk, be.

Приклад

curl -s -X POST https://convr.app/api/v1/jobs/SCAN/transcribe -H "Authorization: Bearer $CONVR_KEY" -H "Content-Type: application/json" -d '{"options":{"ranges":"0-60","lang":"auto"}}'

Відповідь

"result": {
  "language": "ru",
  "clips": [{
    "start": 0, "end": 60,
    "words": [{ "w": "Привет", "s": 0.32, "e": 0.71 }, …]
  }]
}

Помилки

  • speech_too_long400 Понад 20 хвилин мовлення (limit — секунди).
  • speech_limit429 Вичерпано хвилини розпізнавання мовлення за 30 днів.
  • speech_unavailable503 Розпізнавання мовлення тимчасово недоступне.
  • not_a_scan400 {id} — не завдання аналізу (scan).

Довідники й акаунт

GET /registry

Формати й конвертери

Усі формати, конвертери та їхні налаштування. Ключ не обов’язковий. Змінюється рідко — можна кешувати за version.

Відповідь

{
  "version": 14,
  "formats": [{"id": "mov", "ext": "mov", "kind": "video", "mime": "video/quicktime"}, …],
  "converters": [{
    "id": "mov-mp4", "from": "mov", "to": "mp4", "engine": "ffmpeg",
    "options": [
      {"key": "quality", "type": "enum", "values": ["high", "medium", "small"], "default": "medium"},
      {"key": "trim_start", "type": "time", "max": 86400},
      …
    ]
  }, …],
  "tools": [ … ]
}
GET /limits

Ліміти тарифу

Ліміти вашого тарифу й витрачені секунди розпізнавання.

Відповідь

{
  "max_file_bytes": 10737418240,
  "max_jobs_day": 500,
  "max_active": 10,
  "max_duration_s": 14400,
  "retention_h": 72,
  "speech_minutes": 600,
  "speech_used_s": 1834.5
}
GET /account/jobs

Історія

Завдання акаунта, від нових до старих, по 50. Для наступної сторінки передайте created_at останнього в before.

Параметри рядка запиту

ТипОпис
beforetimeКурсор: RFC 3339.

Відповідь

{ "jobs": [{ "id": "…", "state": "done", …, "created_at": "2026-11-04T09:12:44.123Z" }, …] }

Помилки

  • bad_cursor400 before — не час RFC 3339.
POST /assets

Картинка для водяного знака

Тіло — PNG до 2 МБ і 2048×2048 (Content-Type: image/png). Отриманий id передавайте в options.wm_image.

Приклад

curl -s -X POST https://convr.app/api/v1/assets -H "Authorization: Bearer $CONVR_KEY" -H "Content-Type: image/png" --data-binary @logo.png

Відповідь

201 Created
{ "id": "…", "width": 512, "height": 512 }

Помилки

  • invalid_image400 Не PNG або понад 2048×2048.
  • file_too_large413 Файл більший, ніж дозволяє тариф (limit — у байтах).
  • too_many_assets429 Забагато картинок за добу.

Вебхуки

Передайте webhook під час створення завдання (або кліпів). Коли завдання дійде до кінцевого стану, ми надішлемо на цю адресу POST з JSON.

  • події: job.done, job.failed, job.canceled, job.expired;
  • у job.done є download_url — посилання на результат на 30 хвилин; пізніше беріть нове через /download;
  • дайте будь-яку відповідь 2xx за 10 секунд. Інакше повторимо: через 10 с, 40 с, ~3 хв, ~11 хв і ~43 хв — усього 6 спроб;
  • адреса має бути публічною: внутрішні мережі й редиректи не підтримуються;
  • одна подія може прийти двічі (наприклад, через мережевий збій після вашої відповіді) — перевіряйте job.id.

Кожен виклик підписано: X-Convr-Signature: sha256=<hex> — HMAC-SHA256 сирого тіла запиту із секретом whsec_… з кабінету. Перевіряйте підпис до розбору JSON і порівнюйте за сталий час.

POST /hooks/convr HTTP/1.1
Content-Type: application/json
User-Agent: convr-webhook
X-Convr-Event: job.done
X-Convr-Job: 01m6he8nmn6ykgpp3mzh4mek06
X-Convr-Signature: sha256=5d41402abc4b2a76b9719d911017c592…

{
  "event": "job.done",
  "job": { "id": "01m6he8nmn6ykgpp3mzh4mek06", "state": "done", "output_name": "clip.mp4", … },
  "download_url": "https://dl.…/clip.mp4?token=…",
  "sent_at": "2026-11-04T10:15:02Z"
}
import hashlib, hmac, os
from flask import Flask, abort, request

SECRET = os.environ["CONVR_WEBHOOK_SECRET"].encode()
app = Flask(__name__)

@app.post("/hooks/convr")
def convr_hook():
    sig = "sha256=" + hmac.new(SECRET, request.get_data(), hashlib.sha256).hexdigest()
    if not hmac.compare_digest(sig, request.headers.get("X-Convr-Signature", "")):
        abort(401)
    e = request.get_json()
    if e["event"] == "job.done":
        print(e["job"]["id"], e["download_url"])
    return "", 204

Помилки

Помилка запиту — HTTP-статус 4xx/5xx і тіло {"error": "код"}. Помилки лімітів мають ще limit — число, в яке ви вперлися. Спирайтеся на код, а не на текст: коди не змінюються.

HTTP/1.1 429 Too Many Requests
{"error": "limit_active", "limit": 10}
КодHTTPОпис
invalid_key401Ключ не знайдено, відкликано або акаунт вимкнено.
plan_required403Тариф акаунта без API.
not_for_keys403Цей метод доступний лише на сайті.
rate_limited429Понад 120 запитів на хвилину. Зачекайте Retry-After секунд.
limit_active429Забагато завдань виконується одночасно.
limit_daily429Вичерпано добовий ліміт завдань.
speech_limit429Вичерпано хвилини розпізнавання мовлення за 30 днів.
file_too_large413Файл більший, ніж дозволяє тариф (limit — у байтах).
json_required415Немає заголовка Content-Type: application/json.
bad_json400Тіло — не JSON або поля не того типу.
unknown_converter400Немає такого конвертера — дивіться GET /registry.
invalid_options400Невідоме налаштування або неприпустиме значення.
invalid_file400Не вказано назву або розмір файлу.
invalid_url400Посилання не http(s) або разом із ним передано файл.
invalid_webhook400Адреса вебхука не http(s).
not_found404Завдання немає або воно не ваше.
already_uploaded409Завдання вже запущено.
upload_incomplete400Файл (або частина) не завантажений повністю.
upload_size_mismatch400Завантажено не стільки байтів, скільки вказано в file.size.
not_ready409Результату ще немає: завдання не в стані done.
links_unavailable503Завантаження з відеосайтів тимчасово недоступне.
speech_unavailable503Розпізнавання мовлення тимчасово недоступне.
internal500Збій на нашому боці. Повторіть пізніше.

Якщо завдання завершилося з state: "failed", причина — в полі error завдання:

КодОпис
input_invalidФайл пошкоджений або не читається.
input_format_mismatchУсередині файлу інший формат, ніж у конвертера.
input_no_streamНемає потрібної доріжки (наприклад, звуку для mp4-mp3).
input_encryptedАрхів захищений паролем.
input_too_longВідео довше, ніж дозволяє тариф.
input_too_largeЗавантажений за посиланням файл більший за ліміт тарифу.
input_resolutionЗавелика роздільна здатність.
target_too_smallВідео не вмістити в target_mb навіть із мінімальною якістю.
output_too_largeРезультат вийшов більшим за ліміт.
convert_failedКонвертація не вдалася (після повторів на різних серверах).
timeoutОбробка тривала задовго.
url_unreachableПосилання не відкривається.
url_blockedПосилання веде у внутрішню мережу — заборонено.
no_videoЗа посиланням немає відео (допис із фото).
url_privateВідео приватне, видалене, з віковим чи регіональним обмеженням.
site_blockedСайт тимчасово не віддає відео. Повторіть пізніше.
fetch_failedНе вдалося отримати завантажений файл.
speech_too_longПонад 20 хвилин мовлення в одному завданні.
worker_lostСервер обробки зник; завдання зазвичай перезапускається саме.
internalВнутрішня помилка.