Errori e limiti di richieste

Errori e limiti di richieste

Tutti gli endpoint segnalano gli errori con la stessa struttura, con un codice leggibile dalle macchine e un ID della richiesta.

Risposta di errore

Una chiamata non riuscita restituisce success: false. code è stabile ed è pensato per i programmi, error è un breve messaggio in inglese pensato per le persone e request_id identifica la chiamata nei nostri log. Quando il problema riguarda un input, param indica il parametro errato.

Esempi reali

Queste sono risposte reali, ottenute dall'API al momento del rendering di questa pagina.

Parametro obbligatorio mancante · GET /api/sd/oi · HTTP 400
{
  "success": false,
  "error": "coin required",
  "code": "INVALID_PARAM",
  "request_id": "cb-mwefrqni-1ef28bb31a"
}
Endpoint sconosciuto · HTTP 404
{
  "success": false,
  "code": "NOT_FOUND",
  "error": "unknown endpoint: GET /api/this-endpoint-does-not-exist",
  "request_id": "cb-mwefrqni-62b44e62a4"
}

Codici di errore

CodiceHTTPSignificatoChe cosa fare
INVALID_PARAM400Manca un parametro obbligatorio oppure un valore non è accettato. `param` indica il nome del parametro quando è noto.Non riprovare senza modifiche; correggere la richiesta.
UNAUTHORIZED401L'header `CB-API-KEY` è stato inviato ma la chiave è sconosciuta o revocata. I dati pubblici non richiedono alcuna chiave: rimuovere l'header o usare una chiave valida.Non riprovare senza modifiche.
FORBIDDEN403La route non fa parte dell'API pubblica (interna o riservata agli account).Non riprovare.
NOT_FOUND404Route sconosciuta, oppure la moneta / l'exchange / il fondo richiesto non esiste.Non riprovare; verificare il percorso e gli identificatori nel catalogo.
RATE_LIMITED429Più richieste del limite al minuto. `Retry-After` indica i secondi da attendere.Attendere `Retry-After`, poi riprovare con backoff.
INTERNAL500Errore imprevisto del server. Il messaggio è volutamente generico; citare `request_id` quando lo si segnala.Riprovare una volta dopo qualche secondo; se persiste, segnalarlo con l'ID della richiesta.
UPSTREAM_FAILED503La fonte di dati alla base di questo endpoint non ha risposto in tempo. Al suo posto non vengono restituiti numeri obsoleti o sostitutivi.Riprovare con backoff; controllare la pagina di stato.
UNAVAILABLE501 / 503Il dataset è temporaneamente non pronto (riscaldamento della cache) oppure l'endpoint non ha ancora una fonte pubblica lecita.Riprovare più tardi; il catalogo contrassegna gli endpoint non disponibili per scelta progettuale.
REQUEST_FAILED200Alcuni endpoint meno recenti rispondono HTTP 200 con `success: false`. Controllare sempre `success`, non solo lo stato HTTP.Dipende dal messaggio; trattare come una richiesta non riuscita.
Gli endpoint meno recenti possono rispondere con HTTP 200, success: false e codice REQUEST_FAILED quando un elemento manca. Controllare success in ogni risposta.

ID della richiesta

Ogni risposta contiene un header X-Request-Id. Le risposte di errore lo ripetono nel corpo come request_id. Le risposte servite dalla cache edge di breve durata riportano l'ID della richiesta che le ha generate: ID identici in chiamate consecutive indicano quindi che si è ricevuta una copia dalla cache.

Limiti di richieste

I limiti si applicano al minuto: per indirizzo IP nelle chiamate anonime e per chiave quando viene inviato un header CB-API-KEY valido. Il limite è di 1200 richieste al minuto. Le richieste di icone sotto /api/coin-icon non vengono conteggiate.

Header del limite di richieste

NomeDescrizione
X-Request-IdIdentificativo di questa richiesta. Va citato nelle segnalazioni di bug.
X-RateLimit-LimitRichieste consentite nell'attuale finestra di un minuto.
X-RateLimit-RemainingRichieste residue nella finestra attuale.
X-RateLimit-ResetTempo Unix, in secondi, in cui la finestra si azzera.
Retry-AfterInviato con HTTP 429: secondi da attendere prima di riprovare.
X-CacheHIT, STALE o MISS per la cache delle risposte lato server.

Quando si supera il limite

L'API risponde con HTTP 429 e codice RATE_LIMITED. Attendere il numero di secondi indicato in Retry-After, quindi riprovare. Un polling più frequente del TTL della cache di un endpoint restituisce la stessa risposta in cache: conviene quindi allineare l'intervallo di polling al TTL indicato in ogni pagina di riferimento.

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

L'assenza di dati non è un errore

Quando i parametri sono validi ma non esiste una fonte pubblica lecita per i dati, la chiamata riesce con HTTP 200: i campi di valore sono null, meta.quality è UNAVAILABLE e coverage.unavailable ne riporta il motivo. Va visualizzato come un trattino. Non va convertito in 0.

Dati obsoleti

Se un collector accumula ritardo, gli endpoint continuano a servire gli ultimi valori archiviati con meta.is_stale: true finché non superano la finestra di utilizzabilità; dopodiché vengono esclusi dagli aggregati ed elencati in coverage.stale_excluded.