API per partner (B2B)
Errors & rate limits
Partner API error codes, per-key rate limits with X-RateLimit headers, and how to retry.
On this page
Error format#
I corpi degli errori hanno la forma { statusCode, code, message }. message è un testo in inglese leggibile e può cambiare, quindi basa sempre la logica su code.
// Success
{ "success": true, "data": ..., "total": 128, "page": 1, "limit": 20 }
// Error
{ "statusCode": 401, "code": "INVALID_API_KEY", "message": "The API key is invalid." }Nota
Error codes#
| HTTP | code | Significato e soluzione |
|---|---|---|
| 401 | API_KEY_REQUIRED | Nessuna chiave inviata — aggiungi l’header X-API-Key |
| 401 | INVALID_API_KEY | Chiave non valida o sconosciuta — verifica che la copia non sia stata troncata e che non si tratti di una chiave della Public API |
| 401 | KEY_REVOKED | Chiave revocata — creane una nuova |
| 401 | KEY_EXPIRED | Chiave scaduta (inclusa una vecchia chiave dopo il periodo di tolleranza della rotazione): usa la nuova chiave |
| 403 | PARTNER_SUSPENDED | L’account non è attivo — contatta esimoa |
| 403 | INSUFFICIENT_SCOPE | Richiesta al di fuori degli ambiti della chiave |
| 403 | IP_NOT_ALLOWED | Chiamata da un IP non presente nella lista consentita — aggiungi l’IP in uscita del tuo server |
| 404 | PRODUCT_NOT_FOUND | Prodotto sconosciuto o fuori produzione |
| 429 | RATE_LIMITED | Limite di richieste superato — riprova dopo i secondi indicati in Retry-After |
Rate limits#
Nota
Le richieste API B2B sono limitate per impostazione predefinita a 20,000 all’ora per chiave.
La finestra di 3,600 secondi parte dalla prima richiesta; si applica anche il limite al minuto. Le quote contano le chiamate, non i MB trasferiti. Le impostazioni operative possono modificare la quota.
X-RateLimit-Hour-Limit · X-RateLimit-Hour-Remaining · X-RateLimit-Hour-Reset
Questi header indicano il limite orario, le chiamate rimanenti e l’ora di reset (secondi Unix). Esaurito il limite orario, viene restituito HTTP 429 con Retry-After in secondi. Le chiamate rifiutate dal limite al minuto non vengono conteggiate nella quota oraria.
Il valore predefinito è 300 richieste al minuto per chiave (per finestra di 60 secondi, condivisa tra tutti i server). esimoa può aumentarlo per account in base al contratto. Ogni risposta autenticata include header di quota.
X-RateLimit-Limit— richieste consentite al minutoX-RateLimit-Remaining— richieste rimanenti nella finestra attualeX-RateLimit-Reset— quando la finestra si azzera (secondi Unix)Retry-After— con 429, secondi da attendere prima di riprovare
HTTP/1.1 200 OK
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 57
X-RateLimit-Reset: 1790000000
HTTP/1.1 429 Too Many Requests
Retry-After: 18
{ "statusCode": 429, "code": "RATE_LIMITED", "message": "Rate limit exceeded (300 requests per minute)." }Retrying#
- In caso di 429, attendi i secondi indicati in Retry-After e riprova.
- Riprova gli errori 5xx alcune volte con backoff esponenziale.
- 400, 401, 403 e 404 non cambiano riprovando: risolvi la causa.
- Memorizzare il catalogo nella cache per qualche minuto ti mantiene ben al di sotto del limite.
async function b2bFetch(url, attempt = 0) {
const res = await fetch(url, { headers: { 'X-API-Key': process.env.ESIMOA_PARTNER_KEY } });
if (res.status === 429 && attempt < 3) {
const wait = Number(res.headers.get('Retry-After') ?? 1);
await new Promise((r) => setTimeout(r, wait * 1000));
return b2bFetch(url, attempt + 1);
}
const body = await res.json();
if (!res.ok) throw Object.assign(new Error(body.message), { code: body.code, status: res.status });
return body;
}