Перейти к основному содержимому

Коды ошибок WebSocket

Прикладные ошибки приходят как сообщение type: "error":

{
"type": "error",
"code": "INVALID_MESSAGE",
"message": "Missing \"type\" field in subscribe message",
"timestamp": 1714123200000
}

Прикладные коды

КодУсловиеЧто делать
UNAUTHORIZEDAPI-ключ не передан или невалиденПередать корректный ?apiKey=... при подключении
INVALID_JSONТело сообщения не валидный JSONПроверить сериализацию
INVALID_MESSAGEВ сообщении не хватает обязательного поля (action, type, sportSlug, matchId) либо невалидный matchIdСвериться с Subscribe
UNKNOWN_ACTIONaction не один из subscribe / unsubscribe / pingПоддерживаются только эти три
NO_ACCESSТарифный план пользователя не покрывает запрошенный спортСменить тариф; см. Rate limits
SUBSCRIPTION_FAILEDВнутренняя ошибка при добавлении подпискиRetry; если повторяется — обратиться в support
UNSUBSCRIBE_FAILEDВнутренняя ошибка при удалении подпискиАналогично
INTERNAL_ERRORПрочая внутренняя ошибкаRetry с задержкой

Коды передаются в верхнем регистре с подчёркиваниями. На клиенте можно сравнивать msg.code === 'NO_ACCESS'.

Коды закрытия соединения

Сервер использует стандартные WebSocket close codes:

Close codeПричинаКогда
1000Connection timeout due to inactivity120 секунд без активности — см. Overview → Heartbeat
1001Server shutting downGraceful shutdown сервера
1008Unauthorized: Missing/Invalid API keyНевалидный/отсутствующий ключ при connect
1008Access revokedAPI-ключ удалён из Redis в процессе работы
1008Connection limit exceeded. Oldest connection closed.Открыто > 5 соединений с одним ключом — сервер закрывает старейшее
1011Internal server errorНепредвиденная ошибка в обработчике connect

После любого close — клиент должен переподключиться с экспоненциальным backoff (1s → 2s → 4s …).

Heartbeat и реальный pong

Сервер шлёт native WebSocket ping-frame каждые 30 секунд. Стандартные клиенты (ws в Node.js, websockets в Python, браузерный WebSocket) отвечают pong автоматически — отдельный код не нужен.

⚠️ Прикладной ping { "action": "ping" } — это другой механизм: он возвращает { "type": "pong" } JSON и нужен, например, чтобы проверить, что обработчик сообщений жив. На native heartbeat он не влияет.

Если ни native pong, ни любые входящие сообщения от клиента не приходят на сервер 120 секунд — соединение закрывается с close code 1000.

Recovery-стратегия

function connect(retryDelayMs = 1000) {
const ws = new WebSocket('wss://ws.api.api-sport.ru/?apiKey=' + KEY);

ws.addEventListener('close', (event) => {
// Любой close, кроме 1008 (auth) — пытаемся переподключиться
if (event.code === 1008) {
console.error('Auth/access error, stop reconnecting:', event.reason);
return;
}
setTimeout(() => connect(Math.min(retryDelayMs * 2, 60000)), retryDelayMs);
});

ws.addEventListener('message', (e) => {
const msg = JSON.parse(e.data);
if (msg.type === 'connected') retryDelayMs = 1000; // сбрасываем backoff
// … остальная логика
});
}