Errors
Finance OS API возвращает стандартные HTTP-коды и единообразное JSON-тело для всех ошибок. Это позволяет писать унифицированный обработчик в клиенте.
Формат тела ошибки
{
"message": "The given data was invalid.",
"errors": {
"email": ["The email field is required."],
"password": ["The password must be at least 8 characters."]
},
"error_code": "VALIDATION_FAILED"
}
Поля
| Name | Type | Required | Description |
|---|---|---|---|
message
|
string
|
required | Человекочитаемое описание ошибки. На английском (локализация — v1.1). |
errors
|
object
|
optional |
Только для 422: словарь поле → массив строк. Используйте для подсветки конкретных input в UI.
|
error_code
|
string
|
optional | Машиночитаемый код. Используйте для switch-логики и логирования. |
request_id
|
string (uuid)
|
optional | UUID запроса. Приложите его в support-тикет — мы найдём по логам. |
HTTP-коды
Семейство 2xx — успех
| Name | Type | Required | Description |
|---|---|---|---|
200 OK
|
|
optional | Чтение успешно. Тело — JSON с данными. |
201 Created
|
|
optional |
Ресурс создан. Заголовок Location указывает на новый ресурс.
|
202 Accepted
|
|
optional | Запрос принят в обработку (асинхронно — например, вывод средств). |
204 No Content
|
|
optional |
Успех без тела (после DELETE).
|
Семейство 4xx — клиентская ошибка
| Name | Type | Required | Description |
|---|---|---|---|
400 Bad Request
|
|
optional | Запрос не парсится (битый JSON, неправильный Content-Type). |
401 Unauthorized
|
|
optional |
Токен отсутствует, истёк или отозван. Получите новый через POST /mobile/login.
|
403 Forbidden
|
|
optional | Токен валидный, но у пользователя нет прав на ресурс. Например, чужой кошелёк. |
404 Not Found
|
|
optional | Ресурс не существует или удалён. |
409 Conflict
|
|
optional | Конфликт состояния (двойной submit, уже подтверждённая операция). |
422 Unprocessable Entity
|
|
optional |
Валидация не прошла. errors содержит детали по каждому полю.
|
423 Locked
|
|
optional | Аккаунт заморожен (KYC-fail, compliance-hold). |
429 Too Many Requests
|
|
optional | Превышен лимит. См. Rate Limiting. |
Семейство 5xx — серверная ошибка
| Name | Type | Required | Description |
|---|---|---|---|
500 Internal Server Error
|
|
optional |
Неожиданная ошибка на сервере. Логи у нас, в теле — request_id. Повторите через минуту.
|
502 Bad Gateway
|
|
optional | Сбой апстрима (платёжный шлюз или verification-провайдер недоступен). Повторите через минуту. |
503 Service Unavailable
|
|
optional |
Плановое обслуживание. Заголовок Retry-After укажет ожидаемое окно.
|
504 Gateway Timeout
|
|
optional | Долгий ответ от апстрима. Часто — операции с блокчейном. Повторите с idempotency-key. |
Машиночитаемые коды
Часто встречающиеся error_code значения:
| Name | Type | Required | Description |
|---|---|---|---|
VALIDATION_FAILED
|
422
|
optional |
Ошибки в полях — детали в errors.
|
TOKEN_INVALID
|
401
|
optional | Bearer-токен невалиден или истёк. |
TWO_FACTOR_REQUIRED
|
422
|
optional |
Включён 2FA — повторите с two_factor_code.
|
INSUFFICIENT_BALANCE
|
422
|
optional | Недостаточно средств для операции (вывод, перевод). |
KYC_REQUIRED
|
403
|
optional |
Операция требует завершённого KYC. Направьте пользователя на /account/kyc.
|
SANCTION_HIT
|
423
|
optional | Адрес/контрагент попал под санкции — операция заблокирована. |
ACCOUNT_FROZEN
|
423
|
optional | Аккаунт заморожен (compliance). |
NETWORK_CONGESTED
|
503
|
optional | Сеть блокчейна перегружена — попробуйте позже или измените сеть. |
IDEMPOTENCY_CONFLICT
|
409
|
optional | Idempotency-key уже использован с другим телом запроса. |
Идемпотентность
Для всех POST на создание ресурса (особенно денежных операций) клиент может передать заголовок Idempotency-Key — UUID, который сервер запомнит на 24 часа и при повторном запросе с тем же ключом вернёт оригинальный ответ, не выполняя операцию повторно.
curl -X POST https://fin-os.io/api/wallet/withdraw \
-H "Authorization: Bearer ${TOKEN}" \
-H "Idempotency-Key: 5f8d-7a3c-…" \
-d '{"amount": "10.00", "currency": "USDT"}'
⚠
Используйте Idempotency-Key для money-операций
Сеть моргнула, ваш запрос не дошёл — вы повторяете. Без idempotency-key возможен двойной вывод. С ним — гарантия «exactly-once».