Erros e limites de requisições

Erros e limites de requisições

Todos os endpoints reportam falhas no mesmo formato, com um código legível por máquina e um ID da requisição.

Resposta de erro

Uma chamada que falha retorna success: false. code é estável e destinado a programas, error é uma mensagem curta em inglês destinada a pessoas, e request_id identifica a chamada nos nossos logs. param indica o parâmetro problemático quando o erro está na entrada.

Exemplos reais

Estas são respostas ao vivo, obtidas da API no momento em que esta página foi renderizada.

Parâmetro obrigatório ausente · GET /api/sd/oi · HTTP 400
{
  "success": false,
  "error": "coin required",
  "code": "INVALID_PARAM",
  "request_id": "cb-mwefukrd-bafd0bed30"
}
Endpoint desconhecido · HTTP 404
{
  "success": false,
  "code": "NOT_FOUND",
  "error": "unknown endpoint: GET /api/this-endpoint-does-not-exist",
  "request_id": "cb-mwefukre-0daef55e4b"
}

Códigos de erro

CódigoHTTPSignificadoO que fazer
INVALID_PARAM400Falta um parâmetro obrigatório ou um valor não é aceito. `param` indica o nome do parâmetro quando ele é conhecido.Não repita a requisição sem alterações; corrija-a.
UNAUTHORIZED401O cabeçalho `CB-API-KEY` foi enviado, mas a chave é desconhecida ou foi revogada. Dados públicos não exigem chave — remova o cabeçalho ou use uma chave válida.Não repita a requisição sem alterações.
FORBIDDEN403A rota não faz parte da API pública (é interna ou exclusiva de conta).Não tente novamente.
NOT_FOUND404Rota desconhecida, ou a moeda / corretora / fundo solicitado não existe.Não tente novamente; confira o caminho e os identificadores no catálogo.
RATE_LIMITED429Mais requisições do que o limite por minuto. `Retry-After` informa os segundos a aguardar.Aguarde `Retry-After` e então tente novamente com backoff.
INTERNAL500Erro inesperado do servidor. A mensagem é genérica de propósito; cite `request_id` ao reportá-lo.Tente novamente uma vez após alguns segundos; se persistir, reporte-o com o ID da requisição.
UPSTREAM_FAILED503A fonte de dados por trás deste endpoint não respondeu a tempo. Nenhum número desatualizado ou substituto é retornado em seu lugar.Tente novamente com backoff; consulte a página de status.
UNAVAILABLE501 / 503O conjunto de dados ainda não está pronto temporariamente (aquecimento do cache) ou o endpoint ainda não tem uma fonte pública lícita.Tente novamente mais tarde; o catálogo marca os endpoints que são indisponíveis por design.
REQUEST_FAILED200Alguns endpoints mais antigos respondem HTTP 200 com `success: false`. Verifique sempre `success`, não apenas o status HTTP.Depende da mensagem; trate como uma requisição com falha.
Endpoints mais antigos podem responder HTTP 200 com success: false e o código REQUEST_FAILED quando um item não existe. Verifique success em todas as respostas.

ID da requisição

Cada resposta traz um cabeçalho X-Request-Id. As respostas de erro o repetem no corpo como request_id. As respostas servidas pelo cache de borda de curta duração repetem o ID da requisição que as gerou; portanto, IDs idênticos em chamadas consecutivas significam que você recebeu uma cópia em cache.

Limites de requisições

Os limites valem por minuto: por endereço IP nas chamadas anônimas e por chave quando um cabeçalho CB-API-KEY válido é enviado. O limite é de 1200 requisições por minuto. As requisições de ícones em /api/coin-icon não são contabilizadas.

Cabeçalhos de limite de requisições

NomeDescrição
X-Request-IdIdentificador desta requisição. Cite-o nos relatos de bugs.
X-RateLimit-LimitRequisições permitidas na janela atual de um minuto.
X-RateLimit-RemainingRequisições restantes na janela atual.
X-RateLimit-ResetHorário Unix, em segundos, em que a janela é reiniciada.
Retry-AfterEnviado com HTTP 429: segundos a aguardar antes de tentar novamente.
X-CacheHIT, STALE ou MISS para o cache de respostas do servidor.

Quando você excede o limite

A API responde HTTP 429 com o código RATE_LIMITED. Aguarde o número de segundos informado em Retry-After e tente novamente. Consultar com frequência maior que o TTL do cache de um endpoint retorna a mesma resposta em cache; portanto, ajuste seu intervalo de consulta ao TTL indicado em cada página de referência.

Novas tentativas com backoff

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");
}

Ausência de dados não é erro

Quando os parâmetros são válidos, mas não há fonte pública lícita para o dado, a chamada é bem-sucedida com HTTP 200: os campos de valor são null, meta.quality é UNAVAILABLE e coverage.unavailable lista o motivo. Exiba um traço. Não converta para 0.

Dados desatualizados

Se um coletor se atrasa, os endpoints continuam servindo os últimos valores armazenados com meta.is_stale: true até que ultrapassem a janela de uso; depois disso, eles são retirados dos agregados e listados em coverage.stale_excluded.