Ошибки и лимиты запросов

Ошибки и лимиты запросов

Все эндпоинты сообщают об ошибках в едином формате — с машиночитаемым кодом и ID запроса.

Ответ с ошибкой

Неудачный вызов возвращает success: false. Поле code стабильно и предназначено для программ, error — краткое сообщение на английском языке для людей, а request_id идентифицирует вызов в наших журналах. Если проблема во входных данных, поле param называет некорректный параметр.

Реальные примеры

Это настоящие ответы, полученные от API при формировании этой страницы.

Отсутствует обязательный параметр · GET /api/sd/oi · HTTP 400
{
  "success": false,
  "error": "coin required",
  "code": "INVALID_PARAM",
  "request_id": "cb-mwefrnxl-5e7dc77bd0"
}
Неизвестный эндпоинт · HTTP 404
{
  "success": false,
  "code": "NOT_FOUND",
  "error": "unknown endpoint: GET /api/this-endpoint-does-not-exist",
  "request_id": "cb-mwefrnxl-ddc3046308"
}

Коды ошибок

КодHTTPЗначениеЧто делать
INVALID_PARAM400Отсутствует обязательный параметр, или значение не принимается. `param` называет параметр, если он известен.Не повторяйте запрос без изменений; исправьте его.
UNAUTHORIZED401Заголовок `CB-API-KEY` был отправлен, но ключ неизвестен или отозван. Для публичных данных ключ не нужен — уберите заголовок или используйте действительный ключ.Не повторяйте запрос без изменений.
FORBIDDEN403Маршрут не входит в публичный API (внутренний или только для аккаунта).Не повторяйте запрос.
NOT_FOUND404Неизвестный маршрут, либо запрошенная монета / биржа / фонд не существует.Не повторяйте запрос; сверьте путь и идентификаторы с каталогом.
RATE_LIMITED429Запросов больше, чем позволяет поминутный лимит. `Retry-After` указывает, сколько секунд нужно подождать.Дождитесь истечения `Retry-After`, затем повторите запрос с нарастающей задержкой.
INTERNAL500Непредвиденная ошибка сервера. Сообщение намеренно общее; при обращении указывайте `request_id`.Повторите запрос один раз через несколько секунд; если ошибка сохраняется, сообщите о ней, указав ID запроса.
UPSTREAM_FAILED503Источник данных, стоящий за этим эндпоинтом, не ответил вовремя. Устаревшие или подменные значения вместо него не возвращаются.Повторите запрос с нарастающей задержкой; проверьте страницу статуса.
UNAVAILABLE501 / 503Набор данных временно не готов (прогрев кеша), либо у эндпоинта пока нет законного публичного источника.Повторите запрос позже; каталог помечает эндпоинты, недоступные по проектному решению.
REQUEST_FAILED200Некоторые более старые эндпоинты отвечают HTTP 200 с `success: false`. Всегда проверяйте `success`, а не только статус HTTP.Зависит от сообщения; считайте запрос неудачным.
Более старые эндпоинты при отсутствии объекта могут отвечать HTTP 200 с success: false и кодом REQUEST_FAILED. Проверяйте success в каждом ответе.

ID запроса

Каждый ответ содержит заголовок X-Request-Id. В ответах с ошибкой он дублируется в теле как request_id. Ответы, отданные из короткого пограничного кеша, повторяют ID того запроса, который их сформировал, поэтому одинаковые ID в последовательных вызовах означают, что получена кешированная копия.

Лимиты запросов

Лимиты действуют в расчёте на минуту: по IP-адресу для анонимных вызовов и по ключу, если передан действительный заголовок CB-API-KEY. Лимит запросов в минуту: 1200. Запросы иконок по пути /api/coin-icon не учитываются.

Заголовки лимита запросов

ИмяОписание
X-Request-IdИдентификатор этого запроса. Указывайте его в сообщениях об ошибках.
X-RateLimit-LimitЧисло запросов, разрешённых в текущем минутном окне.
X-RateLimit-RemainingЧисло запросов, оставшихся в текущем окне.
X-RateLimit-ResetВремя сброса окна в формате Unix, в секундах.
Retry-AfterПередаётся с HTTP 429: сколько секунд нужно подождать перед повтором.
X-CacheHIT, STALE или MISS для серверного кеша ответов.

При превышении лимита

API отвечает HTTP 429 с кодом RATE_LIMITED. Подождите столько секунд, сколько указано в Retry-After, и повторите запрос. Опрос чаще, чем TTL кеша эндпоинта, возвращает тот же кешированный ответ, поэтому согласуйте интервал опроса с TTL, указанным на странице справочника.

Повтор с нарастающей задержкой

JavaScript
async function getJson(url, tries = 4) {
  for (let i = 0; i < tries; i++) {
    const res = await fetch(url);
    if (res.status === 429 || res.status >= 500) {
      const wait = Number(res.headers.get("Retry-After")) || 2 ** i;
      await new Promise((r) => setTimeout(r, wait * 1000));
      continue;
    }
    const body = await res.json();
    if (body.success === false) {
      throw new Error(body.code + ": " + body.error + " (" + body.request_id + ")");
    }
    return body;
  }
  throw new Error("gave up after " + tries + " attempts");
}

Отсутствие данных — не ошибка

Если параметры корректны, но законного публичного источника данных нет, вызов завершается успешно с HTTP 200: поля значений равны null, meta.quality имеет значение UNAVAILABLE, а причина указана в coverage.unavailable. Отображайте такое значение прочерком. Не преобразуйте его в 0.

Устаревшие данные

Если коллектор отстаёт, эндпоинты продолжают отдавать последние сохранённые значения с meta.is_stale: true, пока те не выйдут за окно пригодности; после этого значения исключаются из агрегатов и перечисляются в coverage.stale_excluded.