> ## Documentation Index
> Fetch the complete documentation index at: https://docs.didit.me/llms.txt
> Use this file to discover all available pages before exploring further.

# Ошибки API Didit: коды статуса, тело ответа и решения

> Все ошибки API Didit: HTTP-коды статуса, структура тела ответа, стабильные коды ошибок и какие сбои безопасно повторять. Коды 401, 403, 409, 429 и 5xx.

Ответ API Didit сообщает об ошибке HTTP-кодом состояния и, почти всегда, телом в формате JSON.

Эта страница описывает, что означает каждый статус, как выглядит тело ответа, какие значения `code` можно использовать для ветвления логики и какие ошибки безопасно повторять.
Сначала опирайтесь на статус, а если `code` присутствует, то и на него, потому что текст сообщения может измениться.

## Коды состояния

| Статус | Что это значит | Что делать | Повторить? |
| - | - | - | - |
| `400` | Запрос некорректен: поле не прошло проверку или изображение либо документ не удалось прочитать | Исправьте то, что указано в теле | После исправления |
| `401` | Отправленный ключ неверный, имеет неправильный формат, отозван или истёк | Проверьте `DIDIT_API_KEY` или создайте новый ключ | После исправления |
| `402` | Проверку не удалось оплатить, поэтому она не выполнена | Пополните баланс | После пополнения |
| `403` | Ключ не был отправлен, ключ не имеет доступа к этому ресурсу или действию, запрос пришёл с IP-адреса вне списка ключа, или баланса недостаточно для вызова | Прочитайте тело, затем см. [ошибки API-ключа](#ошибки-api-ключа) и [Недостаточно кредитов](#недостаточно-кредитов) | После исправления |
| `404` | Ресурс не существует, либо сессия находится вне сценариев или статусов ключа | Проверьте идентификатор и ограничения ключа | Нет |
| `409` | Запрос конфликтует с текущим состоянием, например повторно использован `Idempotency-Key` или шаг уже выполнен | Прочитайте `code` и обновите состояние | Зависит от `code` |
| `410` | Срок действия ресурса истёк, например сессии или приглашения | Создайте новый | Нет |
| `415` | Тело запроса не в формате JSON | Отправьте `Content-Type: application/json` | После исправления |
| `422` | Адрес относится к нескольким блокчейнам, поэтому ничего не проверено и не списано | Отправьте запрос повторно с `blockchain`, равным одному из значений `candidate_chains` | После исправления |
| `429` | Достигнут лимит запросов или квота | Подождите `Retry-After`; см. [Ограничение частоты запросов](https://docs.didit.me/ru/integration/rate-limiting.md) | Да, после ожидания |
| `500` | Непредвиденная ошибка на стороне Didit | Повторите с увеличивающейся задержкой, а если ошибка сохраняется, обратитесь в поддержку | См. [Повторные попытки](#повторные-попытки-и-идемпотентность) |
| `502` | Сервис, от которого зависит Didit, вернул ошибку | Прочитайте `code` | См. [Повторные попытки](#повторные-попытки-и-идемпотентность) |
| `503` | Сервис, от которого зависит Didit, временно недоступен | Прочитайте `code` и повторите попытку | См. [Повторные попытки](#повторные-попытки-и-идемпотентность) |

## Тела ошибок

Тела ошибок не имеют единой структуры, поэтому читайте их осторожно.
Формат зависит от семейства endpoint:

| Формат | Где встречается | Пример |
| - | - | - |
| `detail` | Большинство ошибок, включая аутентификацию, отсутствие ресурса и лимиты запросов | `{"detail": "You do not have permission to perform this action."}` |
| `detail` и `code` | Ошибки со стабильным кодом | `{"detail": "This application was deleted.", "code": "application_deleted"}` |
| Ошибки полей | Проверка входных данных | `{"workflow_id": ["This field is required."]}` |
| `non_field_errors` | Проверка взаимосвязи между полями | `{"non_field_errors": ["..."]}` |
| Массив JSON | Некоторые ошибки проверки, например при вызове simulate | `["Scenario can only be armed before the verification starts."]` |
| `error` | Большинство автономных API | `{"error": "You don't have enough credits to perform this request. Please top up at https://business.didit.me"}` |
| `error` и `code` | Ошибки изображений в автономных API | `{"error": "...", "code": "invalid_image"}` |
| `error` как код, с `detail` | Верификация через кошелёк Digital ID | `{"error": "insufficient_credits", "detail": "..."}` |

Ответ `500` может не содержать тела JSON вовсе, поэтому обрабатывайте тело, которое не удаётся разобрать.

```javascript theme={null}
const raw = await response.text();
let body = {};
try {
  body = JSON.parse(raw);
} catch {
  // A 5xx response may not be JSON: rely on response.status.
}
const code = body.code ?? null;
const message = body.detail ?? body.error ?? (Array.isArray(body) ? body[0] : raw);
```

## Ошибки API-ключа

| Что вы отправили | Статус | `detail` |
| - | - | - |
| Нет заголовка `x-api-key` | `403` | `You do not have permission to perform this action.` |
| Неверный, некорректно сформированный или отозванный ключ | `401` | `Authentication credentials were not provided or are invalid.` |
| Истёкший ключ | `401` | `This API key has expired.` |
| Ключ, использованный с IP-адреса вне его списка | `403` | `This API key can't be used from this IP address.` |
| Ключ с ограниченными правами без доступа к этому ресурсу или действию | `403` | `This API key has no access to this endpoint.` |
| Ключ, ограниченный некоторыми сценариями или статусами, на endpoint, который он не может использовать | `403` | `This API key only reaches sessions inside its workflow or status limits, so it can't use this endpoint.` |
| Ключ, ограниченный некоторыми сценариями или статусами, на сессии вне этих ограничений | `404` | `Session not found.` |
| Ключ, приложение которого только что удалено | `403` | `This application was deleted.`, с `"code": "application_deleted"` |

В течение нескольких минут после удаления приложения API отвечает `application_deleted`, а затем отклоняет ключ так же, как любой неверный ключ.
Не повторяйте попытку: приложение и его ключи удалены.

См. [Аутентификация API](https://docs.didit.me/ru/getting-started/api-authentication.md) и [API-ключи](https://docs.didit.me/ru/console/api-keys.md): там описано, как работают ключи и их ограничения.

## Недостаточно кредитов

Каждое семейство API сообщает о низком балансе по-своему:

| Вызов | Статус | Тело |
| - | - | - |
| `POST /v3/session/` | `400` | `{"detail": "You don't have enough credits to perform this request. Please top up at https://business.didit.me"}` |
| Большинство автономных API | `403` | `{"error": "You don't have enough credits to perform this request. Please top up at https://business.didit.me"}` |
| `POST /v3/bank/account-check/` | `402` | `{"detail": "...", "code": "insufficient_credits"}` |
| Верификация через кошелёк Digital ID | `403` | `{"error": "insufficient_credits", "detail": "..."}` |
| Транзакции, Travel Rule и проверка адреса | `403` | `{"detail": "...", "code": "insufficient_credits"}` |

При контрактной оплате создание сессии возвращает `403` с `"code": "contract_billing_suspended"`, пока платные сервисы приостановлены для вашей организации.
[Приложения в песочнице](https://docs.didit.me/ru/integration/sandbox-testing.md) никогда не тарифицируются, поэтому эти проверки для них не выполняются.

## Коды ошибок

Значения `code` стабильны, поэтому по ним можно ветвить логику.
Чаще всего они находятся рядом с `detail`. При верификации через кошелёк цифровой идентификации код является значением `error`.

### Доступ и биллинг

| Код | Статус | Значение |
| - | - | - |
| `insufficient_credits` | `402`, `403` | Баланса недостаточно для вызова |
| `contract_billing_suspended` | `403` | Платные услуги для этой организации приостановлены |
| `contract_rate_missing` | `402`, `403` | В договоре нет тарифа для этой проверки |
| `application_deleted` | `403` | Приложение, которому принадлежит ключ, было удалено |
| `organization_deleted` | `403` | Организация, которой принадлежит ключ, была удалена |
| `event_monitoring_disabled` | `403` | Приём событий для этого приложения не включён |
| `networks_not_entitled` | `403` | Сети для выявления мошенничества для этой организации не включены |

### Запросы и идемпотентность

| Код | Статус | Значение |
| - | - | - |
| `invalid_image` | `400` | Изображение не удалось использовать |
| `return_url_invalid` | `400` | URL возврата не разрешён |
| `idempotency_key_invalid` | `400` | `Idempotency-Key` длиннее 255 символов |
| `idempotency_key_reused` | `409` | Этот ключ уже использовался с другим телом запроса |
| `idempotency_key_in_progress` | `409` | Первый запрос с этим ключом ещё выполняется; дождитесь `Retry-After` |
| `verification_in_progress` | `409` | Пользователь сейчас проходит эту верификацию, поэтому её нельзя отменить; дождитесь `Retry-After` |
| `feature_override_not_pending` | `409` | Переопределение уже применено или отменено |

### Проверки банка, телефона и рисков

| Код | Статус | Значение |
| - | - | - |
| `invalid_account_input` | `400` | Данные счёта недействительны |
| `country_not_covered` | `404` | Проверка не охватывает эту страну или этот тип счёта |
| `bank_not_covered` | `404` | Проверка не работает с этим банком |
| `bank_verification_not_available` | `404` | Верификация банковского счёта недоступна |
| `account_check_unavailable` | `503` | Проверка временно недоступна, запрос не тарифицирован |
| `phone_provider_unavailable` | `502` | Проверка телефона временно недоступна; оплата не списывается, попытка не расходуется |
| `risk_lookup_unavailable` | `502` | Поиск рисков временно недоступен, запрос не тарифицирован |

### Верификация бизнеса (KYB)

| Код | Статус | Значение |
| - | - | - |
| `kyb_registry_provider_unavailable` | `502` | Реестр компаний временно недоступен |
| `kyb_registry_country_unsupported` | `400` | Поиск в реестре не охватывает эту страну |
| `kyb_registry_search_limit_reached` | `429` | Приложение достигло лимита: 600 платных поисков в час |
| `kyb_session_not_writable` | `409` | Сессия завершена |
| `kyb_step_mismatch` | `409` | Сессия находится на другом шаге; `next_step` его называет |
| `kyb_no_party_drafts` | `409` | Нет черновиков сторон для отправки |
| `kyb_parties_already_submitted` | `409` | Стороны уже отправлены |
| `kyb_party_kyc_session_not_deleted` | `409` | Верификация стороны всё ещё активна, поэтому её нельзя пересоздать |

### Кошельки цифровой идентификации

| Код | Статус | Значение |
| - | - | - |
| `wallet_unavailable` | `403` | Этот кошелёк недоступен вашему приложению |
| `wallet_provider_unavailable` | `502` | Кошелёк не удалось запустить, ничего не создано |
| `wallet_not_configured` | `503` | Эта среда не может обратиться к кошельку |

### Отчёты и кейсы

| Код | Статус | Значение |
| - | - | - |
| `report_deletion_pending` | `409` | Отчёт удаляется; повторите удаление, чтобы завершить стирание его файлов |
| `report_storage_unavailable` | `503` | Файлы отчёта не удалось стереть; повторите удаление |
| `wallet_address_deletion_incomplete` | `503` | Не удалось удалить сохранённый файл, поэтому удаление остановлено; повторите попытку |
| `case_request_not_waiting` | `409` | Запрос больше не ожидает ответа клиента, поэтому напоминать не о чем |
| `case_request_reminder_too_soon` | `429` | Напоминание было отправлено недавно; `retry_at` указывает, когда можно отправить следующее |

### Электронная подпись

| Код | Статус | Значение |
| - | - | - |
| `signature_not_found` | `404` | Подпись не существует |
| `signature_field_not_found` | `404` | Поле подписи не существует |
| `signature_not_signed` | `404`, `409` | Документ не подписан |

При создании сессии ошибки документа передаются как значение поля, вызвавшего ошибку, со статусом `400`, например `{"sign": "signature_document_changed"}`:

| Значение | Смысл |
| - | - |
| `signature_document_changed` | Документ отличается от документа, отправленного первым |
| `signature_document_not_supported` | Формат документа не поддерживается |
| `signature_document_conversion_failed` | Документ не удалось преобразовать |
| `field_anchor_not_found` | Текстовый якорь поля не найден в документе |
| `field_value_missing` | У поля нет значения |

### Webhook

| Код | Статус | Значение |
| - | - | - |
| `webhook_url_missing` | `400` | Для доставки не записан URL, поэтому ничего не отправляется |
| `invalid_webhook_payload` | `400` | Данные webhook имеют неверный формат |
| `webhook_resend_error` | `400` | Сохранённую доставку не удалось подписать повторно или не удалось завершить попытку |

## Повторные попытки и идемпотентность

Одни ошибки безопасно повторять, а другие нет:

* **`429`:** дождитесь заголовка `Retry-After`, затем повторите запрос.
* **`502` и `503`:** повторяйте с задержкой, если в справочнике эндпоинта указано, что списания не было, как это указано для проверок телефона, электронной почты, банковских данных и рисков.
* **`502` на `POST /v3/database-validation/`:** сначала прочитайте каждый элемент `validation_errors`, поскольку один только этот статус не означает временного сбоя.
* **`503` при удалении:** повторяйте тот же запрос, пока он не вернёт `200`.
* **Другие `4xx`:** сначала исправьте запрос, поскольку тот же запрос завершится с той же ошибкой.

`POST /v3/aml/` и верификация кошелька Digital ID принимают заголовок `Idempotency-Key` длиной до 255 символов.
Повторный запрос с тем же ключом и тем же телом возвращает сохранённый ответ, поэтому операция выполняется, а списание производится один раз.
Тот же ключ с другим телом возвращает `409`, а пока первый запрос ещё выполняется, эндпоинты кошельков возвращают `409` с заголовком `Retry-After`.

`POST /v3/session/` не имеет ключа идемпотентности, поэтому, если при создании истёк тайм-аут, получите список своих сессий по полю `vendor_data`, прежде чем создавать новую.

## Связанные материалы

* [Ограничение частоты запросов](https://docs.didit.me/ru/integration/rate-limiting.md): лимиты, заголовки и тело ответа `429`.
* [Аутентификация API](https://docs.didit.me/ru/getting-started/api-authentication.md): как передавать ваш ключ.
* [Тестирование в песочнице](https://docs.didit.me/ru/integration/sandbox-testing.md): воспроизведение результатов без реальных данных и списаний.
* [Webhook](https://docs.didit.me/ru/integration/webhooks.md): доставка, повторные попытки и порядок.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.