Як надіслати переклад і що робити з відмовою

Як записати переклади через API BDO UA Translate: перевірка без запису, шари й режими, ідемпотентність, ліміти та що робити з кожним кодом помилки.

Спочатку перевірка без запису, потім запис тією самою пачкою. Обидва маршрути проходять один і той самий конвеєр, тому «перевірено» справді означає «запишеться»:

curl -s -X POST -H "X-API-Key: $BDO_API_KEY" -H 'Content-Type: application/json' \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"layer":"machine","mode":"direct","provider":"ollama","model":"qwen3.6:14b",
       "items":[{"identity_hash":"<64 hex>","source_hash":"<64 hex>","text":"Залізний меч"}]}' \
  https://bdo-ua.com.ua/api/agent/v1/translations

Той самий запит на /translations/validate нічого не пише · зручно для самоперевірки моделі перед витратою квоти.

Шар і режим

layer mode Що станеться
machine direct запис у ШІ-шар; обовʼязкові provider і model; лише для адміністратора
manual proposal пропозиція в чергу модерації · звичайний шлях для всіх ролей

auto_approve: false лишає пропозицію в черзі навіть тоді, коли роль автора дозволяє схвалити її самому. Роль вирішує все: жодне поле в тілі запиту не підвищує повноважень.

Три речі, які бережуть базу

  • source_hash у кожному елементі. Це підтвердження, ПРОТИ якого джерела ви перекладали. Якщо оригінал змінився після генерації · прийде stale_source замість тихого запису поверх нового тексту.
  • Idempotency-Key на батч. Повтор із тим самим ключем не створює других ревізій · мережевий таймаут перестає бути проблемою.
  • Перевірка розмітки. Втрачена або зіпсована вставка {KeyBind:…} блокує рядок завжди, у будь-якому режимі.

Відмова на один рядок не валить пачку

Відповідь містить data.results[] по кожному елементу й meta.written. Один рядок може бути відхилений, решта запишеться. Розбирайте саме results, а не загальний статус запиту.

Що робити з кодом помилки

Код Що це означає й що робити
stale_source джерело змінилося · перечитайте рядок і перекладіть заново
active_proposal_exists рядок уже чекає на модерацію · пропустіть його (exclude_proposed=1 у вибірці)
non_translatable службовий рядок · перекладати нема чого, пропустіть
source_equivalent ваш текст дорівнює оригіналу; якщо це правильно (бренд, назва технології) · надішліть same_as_source: true
markup_functional_breakage втрачено системну вставку · виправте й повторіть
batch_too_large зменште пачку до details.max
daily_row_quota_exceeded добова квота вичерпана · чекайте quota_resets_at із /me
rate_limited забагато запитів за хвилину · зачекайте й повторіть

Повний каталог кодів із полями agent_action і retriable віддає GET /taxonomy · беріть його звідти, а не з цієї таблиці: вона для людини.

Ліміти в заголовках

Кожна відповідь несе X-RateLimit-Limit, X-RateLimit-Remaining, X-Quota-Rows-Limit, X-Quota-Rows-Remaining і X-Quota-Reset. Довгий прогін має дивитися на них і сповільнюватися сам, а не впиратися в 429.

Якщо щось у контракті виглядає незрозуміло або поводиться інакше, ніж описано · напишіть нам, це помилка документації.