Errori

Un unico documento di problema leggibile dalle macchine per ogni errore, e cosa significa ciascun tipo per la sua logica di ritentativo.

Ogni errore — compresa una rotta che non esiste — risponde con application/problem+json, la forma definita dalla RFC 9457. Non esiste alcun percorso in questa API che restituisca una pagina di errore HTML, quindi un parser che dà per scontato il JSON su una risposta non 2xx è al sicuro.

{
  "type": "https://api.backresto.com/problems/forbidden",
  "title": "Forbidden",
  "status": 403,
  "detail": "The authenticated client lacks the required scope.",
  "instance": "/v1/restaurants/restaurant-1/deliveries/8f2c/images",
  "requestId": "b1c8b0a4-6c1e-4f6b-9e1c-3b2a5d7f0e91"
}

type è l'identificatore stabile: si ramifichi su quello, non su detail, che è prosa e può essere riformulato. requestId è il valore da citare in un messaggio al supporto — viene restituito anche nell'header di risposta X-Request-ID, e può impostare lei stesso quell'header per correlare con le sue tracce.

Suffisso di typeStatoCosa è successoRitentare?
invalid-request400Manca un parametro oppure è malformato: un intervallo di consegne invertito o troppo lungo, una collezione sconosciuta, oppure un cursore che non corrisponde al ristorante, alla collezione e al limit con cui sta paginando.No — corregga la richiesta.
unauthorized401Nessun header Authorization, oppure una chiave malformata, sconosciuta, revocata, scaduta o rimasta senza alcuna concessione.No — la chiave richiede attenzione.
forbidden403La chiave ha una concessione per questo ristorante ma non l'ambito richiesto da questo endpoint.No — il cliente deve far emettere una chiave con quell'ambito.
not-found404Nessuna concessione per questo ristorante, oppure quella consegna o quel record non esistono. I casi sono deliberatamente indistinguibili.No.
conflict409La richiesta è in conflitto con una risorsa esistente.No.
payload-too-large413Il corpo della richiesta supera il limite.No.
rate-limit-exceeded429Il suo client ha superato il proprio budget di richieste.Sì, dopo Retry-After.
dependency-unavailable503Un componente necessario all'API è momentaneamente non disponibile.Sì, con backoff.
internal-error500Un errore imprevisto, già registrato da parte nostra.Una volta, con backoff; poi ci comunichi il requestId.

Cosa dovrebbe fare un client

Tre categorie, e nient'altro vale il codice che costa:

Non ritentare — 400, 401, 403, 404, 409, 413. La richiesta fallirà di nuovo in modo identico. Registri il type e il requestId, e li porti in superficie: un 401 in particolare significa che una persona dalla parte del suo cliente ha revocato qualcosa, e un ciclo di tentativi non farà che nasconderlo per una settimana.

Ritentare con backoff — 429, 503. Rispetti Retry-After su un 429; è il numero di secondi prima che il suo budget si ricarichi, e non è un suggerimento. Per il 503, backoff esponenziale con jitter, e rinunci invece di martellare.

Ritentare una volta, poi segnalare — 500. Se si ripete sulla stessa richiesta, non è transitorio.

Ogni endpoint di questa API è un GET, quindi ritentare è sempre sicuro dal punto di vista dell'API; il motivo per non ritentare un 4xx è che spreca il suo budget, non che rischia una doppia scrittura.

Correlare con i suoi log

Invii un suo identificatore e le torna indietro:

curl "https://api.backresto.com/v1/restaurants/$RESTAURANT_ID/deliveries?from=1787846400000&to=1787932800000" \
  -H "Authorization: Bearer $BACKRESTO_PARTNER_API_KEY" \
  -H "X-Request-ID: 3f7a1c9e-2b4d-4a86-9f0c-5e1d8b6a2c40" \
  --include

Il valore viene riproposto nell'header di risposta e nel requestId di un documento di problema, il che fa sì che un solo grep risponda a «cosa ha visto BackResto quando il mio job è fallito alle 04:12?».

Ultimo aggiornamento 2026-09-19.