Никогда не повторять
invalid_request, invalid_amount, unknown_asset_or_rail, asset_not_offered, unauthorized. Виновен запрос: повторение его без изменений даёт тот же результат. Исправьте его или покажите причину.
Developers
Каждая ошибка несёт стабильный, машиночитаемый код и согласованный HTTP-статус. Код — это то, на что должна опираться ваша интеграция: текст может меняться, код — нет.
Текущая форма намеренно минимальна. Она стабильна, и это главное: код и ничего, что раскрывает внутренние детали.
{ "error": "rate_stale" }{
"error": "rail_not_open",
"reason": {
"fr": "La retenue TDS de 1 % et l’enregistrement FIU-IND exigent une entite locale…",
"en": "The 1% TDS withholding and FIU-IND registration require a local entity…"
}
}Некоторые ошибки содержат двуязычный объект причины, предназначенный для показа пользователю как есть. Закрытый канал — один из таких: причина объясняет названное регуляторное ограничение, а не сбой, и её показ экономит обращение в поддержку. Версионированный API добавит идентификатор запроса в этот конверт, чтобы вы могли указать нам на точную строку в наших журналах.
Эти коды возвращаются сегодня конечной точкой котировок.
| code | HTTP | Что это значит | Что делать |
|---|---|---|---|
invalid_request | 400 | Тело запроса не проходит проверку схемы: отсутствующее поле, неверный тип, значение вне допустимых границ. | Проверьте, что amount — строка, а не число, и что direction — ровно «sell» или «receive». |
invalid_amount | 400 | Сумма не может быть разобрана или содержит больше десятичных знаков, чем допускает актив или валюта. | Округлите до точности единицы: 6 десятичных знаков для USDT, 8 для BTC, 2 для евро, 0 для франка КФА. |
unknown_asset_or_rail | 404 | Идентификатор актива или канала не существует в каталоге. | Идентификаторы стабильны и никогда не переназначаются. Перезагрузите каталог, а не угадывайте их. |
rail_not_open | 409 | Канал существует, но не открыт. Ответ содержит точную причину на обоих языках. | Покажите причину как есть: она объясняет регуляторное ограничение, а не сбой. Предложите открытый канал в той же стране. |
asset_not_offered | 409 | Актив есть в каталоге, но не предлагается — случай для активов с повышенной анонимностью. | Не предлагайте его в своем селекторе. Каталог возвращает его с причиной, чтобы вы могли объяснить это. |
rate_stale | 503 | Последняя известная цена превышает максимально допустимый возраст. Движок отказывается котировать, а не подает устаревшую цену как твердую. | Повторите через несколько секунд. Не кэшируйте последнюю успешную котировку, чтобы заполнить пробел: это была бы именно та ошибка, которую предотвращает этот код. |
rate_unavailable | 503 | Нет доступной цены для этой пары актив/валюта. | Отключите пару в своем интерфейсе, а не показывайте оценку. Показанная оценка становится ожиданием. |
quote_failed | 500 | Непредвиденная ошибка во время вычисления. Котировка не возвращается. | Повторите один раз; если ошибка persists, напишите нам с точной меткой времени вызова. |
Эти коды сопровождают конечные точки, которые ещё не открыты. Они опубликованы, чтобы обработка ошибок была написана один раз.
| code | HTTP | Что это значит | Что делать |
|---|---|---|---|
unauthorized | 401 | Ключ отсутствует, отозван или используется в неправильной среде. | Ключ sk_test_ не работает в производственной среде, и наоборот: это сделано намеренно. |
idempotency_conflict | 409 | Тот же ключ идемпотентности уже использовался с другим телом запроса. | Ключ принадлежит одному намерению. Если содержимое меняется, ключ меняется; в противном случае невозможно определить, какой из двух заказов воспроизводить. |
quote_expired | 409 | Котировка вышла за пределы окна фиксации. | Запросите новую котировку и примите новую сумму. Мы никогда не меняем цену молча в ущерб клиенту. |
beneficiary_rejected | 422 | Данные бенефициара не проходят проверку платежной системы: неверная контрольная сумма, несоответствующий формат или имя, не совпадающее с подтвержденной личностью. | В ответе указано поле, вызвавшее ошибку. Имя бенефициара должно соответствовать подтвержденной личности: выплата третьим лицам невозможна. |
country_not_served | 451 | Страна назначения не обслуживается: санкции, ограничительные меры или отсутствие местной правовой базы. | Код 451 выбран намеренно вместо 404: когда мы отказываем, мы говорим, что это отказ, и объясняем причину. |
rate_limited | 429 | Слишком много вызовов в пределах скользящего окна. | Соблюдайте заголовок Retry-After. Котировки дешево ставить в очередь, но дорого отправлять повторно. |
not_found | 404 | Ресурс не существует или не принадлежит вашему ключу. | Оба случая возвращают один и тот же код: ответ, который их различал, позволил бы любому перечислить чужие ссылки. |
Сумма вне границ канала возвращает действительную котировку с объектом limitError. Это не сбой: это информация, которую ваш интерфейс должен отображать.
"limitError": { "code": "below_min", "limit": "20.00" }Рассмотрение этого случая как HTTP-ошибки лишило бы вас вычисленной суммы и, следовательно, возможности сказать пользователю: «Вам не хватает 16,53 EUR до минимума для этого способа выплаты». Ограничение применяется к чистой сумме, той, которую получает бенефициар.
Три семейства, три поведения. Повторение ошибки валидации в цикле только заполняет ваши журналы.
invalid_request, invalid_amount, unknown_asset_or_rail, asset_not_offered, unauthorized. Виновен запрос: повторение его без изменений даёт тот же результат. Исправьте его или покажите причину.
rate_stale, rate_unavailable, quote_failed и любое ограничение частоты. Подождите несколько секунд, увеличивая промежуток между попытками. Не заполняйте промежуток кэшированной котировкой.
rail_not_open, quote_expired, beneficiary_rejected, country_not_served. Ситуация требует выбора человека: предложите другой канал, свежую котировку, исправленные данные.