Коды ошибок

Коды ошибок

Единый envelope для всех ошибок BCS API. Машинно-читаемый code + человеко-читаемый message + опциональные details.

Envelope

{
  "error": {
    "code": "validation_error",
    "message": "bank_account_id обязателен (UUID)",
    "details": {
      "field": "bank_account_id"
    }
  }
}
ПолеТипОбяз.Описание
error.codestringСтабильный машинный код. Не меняется без bump'а major-версии API. Клиент должен matching'овать по code, не по message.
error.messagestringЧеловеко-читаемое описание (RU). Показывайте оператору, не парсите.
error.detailsobjectСтруктурированный контекст (например, {"field": "..."}, {"retry_after_seconds": 30}). Опционален.

Полный справочник кодов

HTTPcodeКогда возникает
400validation_errorНевалидный формат запроса: missing field, плохой UUID, плохая дата, период вне допустимого, и т.п. Универсальный код валидации.
400invalid request bodyНевалидный JSON в body или malformed UUID в URL-path. Срабатывает до ручного валидатора.
401invalid_token_formatНет header Authorization, либо токен не начинается с bcs_live_ / bcs_test_.
401invalid_tokenФормат корректный, но токен не найден / отозван / истёк.
403forbidden_ipЗапрос с IP вне allowed_ips токена.
403forbidden_purposeНазначение токена не подходит endpoint'у (например, MCP-токен на REST integration-endpoint'е или integration-токен на /api/v1/mcp).
403forbidden_scopeУ токена нет нужного scope (read_statements / send_payments).
403forbidden_accountscope есть, но у токена нет per-account allow на конкретный bank_account_id.
403forbidden_companyЗапрошенный bank_account_id принадлежит другой компании. Cross-tenant попытка.
403forbidden_originТолько MCP HTTP transport. Origin вне MCP_ALLOWED_ORIGINS.
404not_foundResource (batch / payment / statement) либо отсутствует, либо принадлежит другому токену. Намеренно не различаем — не светим существование.
405method_not_allowedHTTP-метод не поддержан на endpoint'е. На /api/v1/mcp — GET → 405 (SSE upgrade не реализован).
409conflictТот же external_id у этого токена для другого payload / периода / РС. Для платежей: single-item submit. Для выписок: POST /statements.
409not_readyЗапрос export на выписку до того, как её статус стал ready.
413payload_too_largeBody превышает лимит. Для платежного файла — 10 MB; для MCP HTTP — 16 KB.
422account_mismatchВ 1С-файле указан РС-плательщик, не совпадающий с bank_account_id запроса. Batch не создаётся.
429rate_limitedПревышен per-token лимит. error.details.retry_after_seconds + HTTP header Retry-After подсказывают, через сколько ретраить.
500internal_errorНеожиданная ошибка backend'а. Запишите request_id из X-Request-Id header и эскалируйте админу.
500bank_errorБанк-адаптер вернул ошибку. error.details может содержать bank-specific код.
501bank_not_supportedБанк-адаптер целевого РС не реализует данную операцию (например, выписки на адаптере без SupportsStatements).
503service_unavailableТолько MCP HTTP transport. Redis session store недоступен — fail-closed контракт.

MCP JSON-RPC error codes

MCP HTTP transport использует JSON-RPC 2.0 envelope. Ошибки протокольного уровня — внутри JSON-RPC error object с одним из стандартных кодов:

codenameКогда возникает
-32700Parse errorНевалидный JSON в body.
-32600Invalid RequestНет/неверный jsonrpc; нет Mcp-Session-Id на non-initialize методе; сессия истекла; сессия другого токена.
-32601Method not foundUnknown JSON-RPC method или unknown tool name. Все write-tools (send_payment, approve и т.п.) фактически попадают в эту категорию — их нет в registry.
-32602Invalid paramsBad params в tools/call.
-32603Internal errorВнутренняя ошибка backend.

:::info Tool-level ошибки (валидация аргументов tool, ACL, not_found для конкретной выписки) приходят как {"jsonrpc":"2.0","id":N,"result":{"isError":true,"content":[…],"_meta":{"notice":…}}} — HTTP 200, JSON-RPC success, но внутри tool result isError=true. Это спецификация MCP, не пропуск backend'а. :::

Политика retry

КатегорияПоведение
401, 403НЕ ретраить. Решается ротацией токена / правкой ACL.
404НЕ ретраить.
409 conflictНЕ ретраить с тем же external_id. Нужно поменять идентификатор (новый Номер 1С).
409 not_readyРетраить с backoff (1s → 2s → 4s, до status=ready).
413, 422НЕ ретраить. Исправить запрос на клиенте.
429Ждать Retry-After секунд, потом повторить. Реализуйте exponential backoff на случай шквала 429'ов.
500 internal_errorЭскалировать с request_id. Ретрай только после устранения root cause.
500 bank_errorЗависит от bank-specific кода. Часть — transient (network к банку), часть — permanent (отказ банка). На бизнес-уровне всегда показывать оператору.
503 service_unavailableРетраить с backoff. Обычно временное.

X-Request-Id

Каждый HTTP-ответ BCS содержит X-Request-Id header — уникальный идентификатор запроса. Если клиент шлёт свой X-Request-Id, backend его пропускает; иначе генерит свой. При репортинге об ошибке в support — обязательно включайте этот id, по нему легко найти полный контекст в audit log.