Ошибки и notices
Ошибки отклоняют команду или сообщают о сбое сервиса. Notices — асинхронные сообщения об открытом стриме.
Фрейм ошибки
Ошибка несёт id команды, которая её вызвала:
{
"op": "error",
"id": 1,
"code": "not_on_plan",
"feature": "detail_full",
"message": "..."
}| Code | Meaning | Client action |
|---|---|---|
unauthorized | Ключ отсутствует, неизвестен или отозван | Остановитесь и предоставьте валидный ключ |
invalid_params | Неизвестный/отсутствующий параметр или значение вне допустимого набора | Исправьте команду; не повторяйте без изменений |
invalid_address | mint или wallet не является адресом Solana | Проверьте адрес локально |
invalid_mint | Адрес существует, но это не mint токена | Используйте mint токена |
unknown_stream | Имя стрима не существует | Используйте одно из восьми документированных имён |
duplicate_subscription | Имя sub уже занято на этом соединении | Возьмите другое имя или используйте уже открытую подписку |
subscription_limit | Исчерпан лимит открытых подписок плана | Отпишитесь или обновите план |
connection_limit | Исчерпан лимит одновременных соединений плана | Закройте другое соединение или обновите план |
rate_limited | Слишком высокая частота команд | Сделайте backoff перед повтором |
not_on_plan | Запрошенная функция вне плана | Смотрите feature; уберите её или обновите план |
internal_error | Сервис не смог обработать команду | Повторите с backoff; сообщайте о устойчивых сбоях |
Фичи not_on_plan
feature — одно из:
streamdetail_fullinclude_rawcursorcandlescandle_intervalquota
Человекочитаемое сообщение содержит ссылку на страницу цен. Ветвьте логику клиента по code и feature, а не по тексту сообщения.
Фрейм notice
Notice не привязан к команде. Он сообщает о состоянии стрима и обычно несёт затронутую подписку:
{
"op": "notice",
"code": "gap",
"sub": "tt_1",
"message": "..."
}Notices делятся на два вида, и логике переподключения нужно от них только это различие: после первого вида соединение продолжает работать, после второго оно закрывается.
Соединение продолжает работать
| Code | What happened | Client action |
|---|---|---|
gap | Курсор старше окна replay; доставка начинается с live | Зафиксируйте разрыв и продолжайте |
replay_rate_limited | Лимит replay исчерпан; доставка начинается с live | Продолжайте без replay |
dropped | Клиент читал слишком медленно, события потеряны; cursor — первое потерянное событие | Зафиксируйте разрыв, сузьте фильтры или ускорьте потребление |
quota_exceeded | Исчерпана месячная квота трафика Free | Дождитесь следующего периода или обновите план |
dropped эмитится один раз на серию потерь. Повторные notices означают, что подписку нужно сузить фильтрами или потреблять быстрее.
При quota_exceeded соединение и все подписки остаются открытыми — просто останавливается выдача до следующего периода, а новые подписки получают not_on_plan с feature: "quota". Предупреждения перед лимитом нет.
Соединение закрывается
Notice приходит прямо перед close-кадром, то есть это последнее, что вы получите. Прочитайте код, прежде чем решать, переподключаться ли.
| Code | What happened | Client action |
|---|---|---|
ping_timeout | В пределах таймаута чтения не пришло ни pong, ни команды | Отвечайте на пинги сервера или присылайте {"op":"ping"}, если их съедает прокси; затем переподключитесь |
slow_consumer | Чтение стабильно отстаёт | Переподключайтесь только после исправления скорости потребления |
server_restart | Сервис перезапускается | Переподключитесь с backoff и последним обработанным курсором |
plan_changed | Тариф на аккаунте изменился | Переподключитесь: новые лимиты действуют со следующего соединения |
key_revoked | Ключ отозван при открытом соединении | Прекратите им пользоваться и смените его |
account_banned | Аккаунт заблокирован | Не переподключайтесь, напишите в поддержку |
account_deleted | Аккаунта больше нет | Не переподключайтесь |
plan_changed стоит обработать осознанно: лимиты читаются при открытии соединения, поэтому апгрейд вступает в силу на следующем. Переподключились — получили новый тариф.
Политика повторов
Используйте экспоненциальный backoff с джиттером для internal_error, перезапусков и сетевых разрывов. Не повторяйте автоматически без изменений некорректные команды, невалидные ключи или отказы по плану.