Коды ошибок и лимиты
В этом документе перечислены все ошибки, возвращаемые нативным API платформы. Суммы в примерах носят иллюстративный характер; актуальные ставки запрашивайте через GET /v1/prices.
Структура ответа с ошибкой
{ "error": { "code": 4001, "slug": "insufficient_funds",
"message": "Required 1300000 SUN, available 420000 SUN",
"field": null, "retryable": true,
"details": { "required_sun": 1300000, "available_sun": 420000 } },
"request_id": "req_01J9Z5P8T3WQ7X" }
| Поле | Назначение |
|---|---|
code | Постоянный целочисленный код ошибки. Номера стабильны и никогда не переназначаются на другой смысл. |
slug | Стабильный символьный идентификатор в нижнем регистре (snake_case). Взаимно однозначен с code. |
message | Сообщение на английском языке для чтения человеком. Может изменяться без предварительного уведомления. Используйте для логирования, не парсите программно. |
field | Имя поля запроса, вызвавшего ошибку валидации; для остальных ошибок — null. |
retryable | Признак возможности успешного повторения абсолютно идентичного запроса через некоторое время. |
details | Опциональный объект с контекстом ошибки в машинном формате; структура зависит от кода ошибки. |
request_id | Уникальный ID запроса, дублируется в заголовке ответа X-Request-Id. Указывайте его при обращении в поддержку. |
Опирайтесь в программной логике на slug или code, а не на HTTP-статус — один и тот же статус может соответствовать совершенно разным ситуациям (например, статус 409 используется как для конфликта идемпотентности, так и для попытки отзыва неотзываемого заказа, при этом реакция приложения на них должна быть противоположной). Если вы встретили неизвестный код, обрабатывайте его по классу HTTP-статуса (4xx — ошибка на стороне клиента, не спамьте повторами; 5xx — временный сбой сервиса, повторите с задержкой).
Диапазоны кодов: 1000–1099 аутентификация и учетные данные · 1100–1199 лимиты частоты и квоты · 2000–2099 валидация параметров · 3000–3099 бизнес-состояние объектов · 4000–4099 баланс и биллинг · 5000–5099 поставка ресурсов · 9000–9099 внутренние ошибки.
Список кодов ошибок
| Код | Slug | HTTP | Условие возникновения | Повтор запроса |
|---|---|---|---|---|
| 1001 | missing_credentials | 401 | Отсутствует один или несколько заголовков: X-API-KEY, X-API-TIMESTAMP, X-API-SIGN. Некорректный формат — это код 1002; 1001 означает, что заголовок не был передан вовсе. | Нет — исправьте клиент. |
| 1002 | invalid_signature | 401 | Подпись X-API-SIGN не совпадает со значением, вычисленным сервером. | Нет. Проверьте формирование канонической строки: типичные причины — перекодирование query, подписание JSON с пробелами при отправке сжатого, или лишний перенос строки. |
| 1003 | signature_timestamp_skew | 401 | Разница между X-API-TIMESTAMP и часами сервера превышает 5 секунд. Поле details.server_time содержит время сервера. | Да, один раз после синхронизации времени по NTP. |
| 1004 | ip_not_allowed | 401 | IP-адрес источника не входит в белый список ключа. В details.source_ip возвращается зафиксированный IP. | Нет. Добавьте адрес в кабинете; при работе за NAT укажите всю подсеть выхода. |
| 1005 | insufficient_scope | 403 | Ключ действителен, но не имеет прав (scope) для данного эндпоинта. Необходимое разрешение указано в details.required_scope. | Нет — расширение прав ключа требует осознанного изменения владельцем аккаунта в кабинете. |
| 1006 | key_revoked | 401 | Ключ удален или истек срок его действия. | Нет. |
| 1007 | key_inactive | 401 | Ключ существует, но временно отключен в кабинете. | Нет. |
| 1008 | account_suspended | 403 | Аккаунт заблокирован: чтение разрешено, оформление заказов запрещено. | Нет. Обратитесь в поддержку. |
| 1009 | replayed_signature | 401 | Данная подпись уже была использована; в рамках допустимого временного окна каждая подпись одноразовая. | Нет — генерируйте свежие метку времени и подпись для каждой попытки (включая ретраи). |
| 1010 | challenge_invalid | 401 | Ошибка валидации челленджа авторизации кошелька: неизвестный nonce, истек срок, nonce уже использован или подпись не восстанавливает адрес. | Да, один раз после повторного запроса POST /v1/accounts/challenge. |
| 1011 | bootstrap_token_expired | 401 | 15-минутный временный токен истек или применен к запрещенной операции. | Да — пройдите авторизацию кошельком заново. |
| 1012 | key_environment_mismatch | 401 | Префикс ключа не соответствует окружению: отправка ключа ak_live_ на хост тестнета Nile или ключа ak_test_ на хост Mainnet. | Нет — используйте ключ соответствующего окружения. |
| 1013 | session_expired | 401 | Кука сессии кабинета отсутствует, истекла или был выполнен выход. | Нет — авторизуйтесь заново через кошелек. |
| 1014 | csrf_token_invalid | 403 | Запрос на запись с авторизацией по кукам отправлен без валидного заголовка X-CSRF-Token. | Нет — передавайте токен из куки CSRF. |
| 1100 | rate_limited | 429 | Превышен лимит частоты запросов на ключ или IP. Заголовок Retry-After указывает паузу в секундах. | Да — с соблюдением Retry-After и экспоненциальной задержкой. |
| 1101 | concurrency_limited | 429 | Слишком много незавершенных заказов или пакетов в обработке одновременно. | Да, после завершения текущих задач. Снизьте параллелизм запросов. |
| 1102 | quota_exceeded | 429 | Достигнут суточный или месячный лимит объема на аккаунте. Время сброса в details.resets_at. | Да, после наступления времени сброса лимита. |
| 2000 | malformed_json | 400 | Тело запроса не является валидным JSON, либо Content-Type отличается от application/json. | Нет. |
| 2001 | validation_failed | 400 | Параметр отсутствует, имеет неверный тип или выходит за рамки допустимых значений. Поле указано в field. | Нет. |
| 2002 | empty_patch | 422 | Запрос PATCH не содержит ни одного изменяемого поля в теле. | Нет. |
| 2003 | tier_unavailable | 422 | Запрошенный тариф синтаксически корректен, но временно закрыт для продажи. Список открытых тарифов в details.available_tiers. | Нет. |
| 2004 | quote_mismatch | 422 | Передан quote_id вместе с явными параметрами заказа, которые противоречат котировке. | Нет. |
| 2005 | idempotency_key_required | 400 | Пакетный заказ создан без client_batch_id и без заголовка Idempotency-Key. | Нет. |
| 2006 | duplicate_receiver | 400 | Один и тот же адрес получателя указан в пакете несколько раз. Объедините суммы. | Нет. |
| 2007 | invalid_address | 400 | Некорректный адрес TRON формата Base58Check (ошибка контрольной суммы, длины или hex-формат). | Нет. |
| 2008 | amount_out_of_range | 400 | Количество меньше минимума или больше максимума тарифа. См. details.min_amount / details.max_amount. | Нет. |
| 2009 | batch_too_large | 400 | В пакете более 100 получателей либо общий объем превышает лимит пакета. | Нет. |
| 2010 | invalid_webhook_url | 400 | URL вебхука не использует HTTPS, ведет на локальный/приватный IP, содержит логин/пароль или длиннее 2048 символов. | Нет. |
| 2011 | unsupported_contract | 422 | Смарт-контракт в оценке перевода не является поддерживаемым токеном TRC-20. | Нет. |
| 3001 | order_not_found | 404 | Заказ не найден либо принадлежит другому аккаунту. | Нет. |
| 3002 | order_not_cancellable | 409 | Попытка отмены элемента пакета, который уже взят в исполнение. Одиночные заказы отмене не подлежат. | Нет — проверьте статус заказа, скорее всего он уже доставлен. |
| 3003 | receiver_is_ours | 422 | Адрес получателя является внутренним адресом пула платформы. | Нет. |
| 3004 | receiver_not_activated | 422 | Адрес получателя не активирован, а в запросе передано activate: false. Средства не списывались. | Да, с флагом activate: true либо после самостоятельной активации адреса. |
| 3005 | quote_expired | 409 | Время действия котировки (expires_at) истекло. | Да — предварительно запросите новую котировку. |
| 3006 | price_above_limit | 409 | Текущая цена превышает указанный вами лимит max_price_sun. Средства не списывались. | Да, позже — когда цена снизится в следующем окне, либо увеличьте лимит. |
| 3007 | nothing_to_reclaim | 409 | Заказ не привел к активному делегированию либо срок аренды уже завершился. | Нет. |
| 3008 | reclaim_unavailable | 409 | Заказ исполнен сторонним провайдером, ресурсы которого не поддерживают досрочный отзыв. Источник в details.filled_by. | Нет. |
| 3009 | order_in_terminal_state | 409 | Запрошено изменение состояния заказа, который уже находится в финальном статусе. | Нет. |
| 3010 | idempotency_conflict | 409 | Повторное использование ключа идемпотентности с другим телом запроса. Ссылка на исходный объект в details.original_id. | Нет — ошибка логики клиента. Повторите идентичный запрос либо используйте новый ключ. |
| 3011 | subscription_exists | 409 | Для этого адреса уже оформлена подписка на данный ресурс. Идентификатор в details.subscription_id. | Нет — обновите существующую подписку через PATCH. |
| 3012 | subscription_not_active | 409 | Вызов операции, требующей активной подписки, над отмененной подпиской. | Нет. |
| 3013 | webhook_limit_reached | 409 | Уже зарегистрировано максимальное количество эндпоинтов вебхуков (два). | Нет — удалите или измените существующий. |
| 3014 | webhook_role_taken | 409 | Запрошенная роль вебхука уже занята другим эндпоинтом. | Нет — измените роли через PATCH. |
| 3015 | request_in_progress | 409 | Идентичный запрос с данным ключом идемпотентности еще выполняется. Заголовок Retry-After рекомендует паузу. | Не повторяйте создание. Подождите и запросите статус объекта по client id. |
| 3017 | api_key_limit_reached | 409 | Достигнут лимит на количество активных API-ключей. Лимит и текущее число в details.limit и details.used. | Нет — отзовите неиспользуемый ключ, слот освободится мгновенно. |
| 3018 | deposit_rotation_limited | 429 | Превышен лимит частоты смены адреса депозита. | Да — после наступления времени из details.next_allowed_at. |
| 3019 | address_book_full | 409 | Адресная книга заполнена (максимум 100 адресов). | Нет — удалите ненужный адрес для освобождения места. |
| 4001 | insufficient_funds | 402 | Доступного баланса недостаточно для оплаты заказа и возможной активации. См. details.required_sun, details.available_sun. | Да — пополните баланс и повторите запрос с тем же client_order_id. |
| 4002 | balance_reserved | 402 | Номинальный баланс достаточен, но средства временно заблокированы параллельными заказами. | Да, после завершения текущих заказов. |
| 4003 | currency_not_supported | 422 | Валюта не поддерживается для данной операции. | Нет. |
| 4004 | ledger_conflict | 409 | Конфликт одновременного списания с баланса при высокой конкуренции. Средства не списались. | Да, немедленно, с тем же ключом идемпотентности. При частых ошибках выстраивайте списания в очередь. |
| 5001 | insufficient_supply | 503 | Ни собственные пулы, ни внешние провайдеры не смогли предоставить нужный объем по приемлемой цене. Списания не было. | Да, с задержкой — объем высвобождается по мере завершения чужих аренд. Для коротких тиров переключение на более длинный тариф часто срабатывает сразу. |
| 5002 | delegation_failed | 503 | Транзакция делегирования была сформирована, но отклонена сетью или не подтвердилась. Списание полностью возвращено, заказ перешел в статус failed с полем refunded_amount_sun. | Да — с новым client_order_id, так как предыдущий заказ завершен. |
| 5003 | chain_unavailable | 503 | Локальная нода TRON не отвечает, доставка временно невозможна. | Да, с экспоненциальной задержкой. |
| 5004 | provider_unavailable | 503 | Все внешние поставщики ликвидности недоступны или ответили тайм-аутом, а собственный пул исчерпан. Списания не было. | Да, с задержкой. |
| 5005 | receiver_capacity_exceeded | 422 | Адрес получателя исчерпал лимит одновременных делегирований в сети TRON. См. details.max_additional. | Нет в текущем виде — уменьшите объем или дождитесь завершения действующих аренд на адресе. |
| 5006 | supply_paused | 503 | Продажи данного тарифа или ресурса временно приостановлены административно. | Да, позже; приостановленные тарифы исключаются из GET /v1/prices. |
| 5007 | capacity_unavailable | 503 | Собственная емкость исчерпана, а условиями контракта запрещен перелив во внешние пулы. Средства возвращены. | Да, с задержкой — емкость вернется по мере закрытия аренд. |
| 9000 | internal_error | 500 | Необработанная ошибка сервиса. Состояние заказа неизвестно только по этому ответу. | Да — строго с тем же client_order_id, чтобы безопасно узнать, был ли создан заказ. |
| 9001 | timeout | 504 | Тайм-аут на уровне шлюза; результат операции неизвестен. | Да, с тем же client_order_id. |
| 9002 | not_implemented | 501 | Метод описан в спецификации, но еще не развернут на данном инстансе. | Нет. |
Ошибки валидации (2000–2099) всегда имеют retryable: false и содержат имя проблемного поля в field; исправьте параметры запроса перед отправкой.
Гарантия безопасности поставки: код 503 при создании заказа является безопасным отказом (fail-secure) — заказ не сохранился и средства не списались, поэтому повтор с тем же client_order_id полностью безопасен. Если средства были списаны, но делегирование сорвалось (5002), деньги автоматически возвращены на баланс, а заказ завершен: создавайте новый заказ с новым id.
Политика повторных запросов (Retry policy)
Повторяйте запросы при кодах 429, 5xx, а также 4001/4002/4004 после устранения причины. Не повторяйте запросы с кодами 400, 401, 403, 404 и 409 (кроме 4004) — они требуют обязательной модификации запроса или исправления прав. Всегда передавайте client_order_id при создании заказов. Используйте экспоненциальную задержку от 250 мс со случайным разбросом (Full Jitter), ограничивая максимальную паузу 30 секундами и общее время ожидания 60 секундами. При наличии заголовка Retry-After всегда придерживайтесь указанного в нем времени.
Лимиты частоты запросов (Rate limits)
Лимиты действуют на каждый API-ключ, а также на IP-адрес источника. В заголовках каждого ответа возвращаются: RateLimit-Limit (лимит), RateLimit-Remaining (остаток) и RateLimit-Reset (секунды до сброса). Превышение возвращает 429, ошибку 1100 rate_limited и заголовок Retry-After.
Базовые лимиты на ключ (в секунду):
| Группа операций | Лимит |
|---|---|
Создание заказов (POST /v1/orders, POST /v1/batches) | 30 rps |
Чтение данных (GET заказы, котировки, цены, ресурсы) | 50 rps |
| Управление аккаунтом, ключами и вебхуками | 5 rps |