Rate Limit e Quote
Comprendi i rate limit dell'API e pianifica la tua integrazione
Due Rate Limit
Ogni richiesta viene contata due volte, su due limiti indipendenti. Entrambi
restituiscono 429 RATE_LIMITED.
| Limite | Conteggiato per | Si applica a |
|---|---|---|
| 100 richieste / secondo | chiave API | ogni endpoint autenticato |
| 500 richieste / minuto | IP client | ogni endpoint, autenticato o no |
Il limite per chiave è quello che un'integrazione incontra per primo: un ciclo
che invia senza pause tocca le 100/s molto prima delle 500/min. Il messaggio
d'errore nomina il limite — Rate limit exceeded: 100 requests/second per API key.
Il limite al minuto è per IP client, non per tenant. Due workspace che chiamano dallo stesso IP di uscita lo condividono; un workspace che chiama da più IP ha un'allowance per ciascun IP.
POST /v1/templates/render-preview ha un proprio limite per IP di 60
richieste / minuto, che su quell'endpoint prende il posto delle 500/minuto. Il
limite per chiave vale anche lì.
Header di Rate Limit
Le risposte riportano lo stato del limite per IP:
x-ratelimit-limit: 500
x-ratelimit-remaining: 245
x-ratelimit-reset: 47x-ratelimit-reset è il numero di secondi rimanenti nella finestra corrente,
non un timestamp Unix. Quando superi il limite per IP, il 429 include anche
l'header retry-after, in secondi.
Questi header descrivono soltanto il limite per IP: 500/minuto, o 60/minuto
su render-preview. Il limite per chiave, 100/secondo, non vi compare: puoi
essere a x-ratelimit-remaining: 400 e ricevere comunque un 429 per aver
mandato 100 richieste nello stesso secondo. Quel 429 per chiave non ha né questi
header né retry-after.
Verificare lo Stato del Rate Limit
Prima di raggiungere il limite, controlla gli header:
curl -i https://api.tratto.email/v1/emails \
-H "Authorization: Bearer tratto_live_..."Restituisce gli header con le richieste rimanenti e l'orario di reset.
Rate Limit Superato (429)
Entrambi i limiti rispondono con lo stesso codice. Oltre il limite per IP:
{
"error": {
"code": "RATE_LIMITED",
"message": "Rate limit exceeded, retry in 47 seconds",
"docs": "https://docs.tratto.email/en/docs/error-codes"
}
}Oltre il limite per chiave, message è
Rate limit exceeded: 100 requests/second per API key.
Il body non contiene alcun campo retryAfter. Dopo un 429 per IP, attendi i
secondi indicati da retry-after. Dopo un 429 per chiave non c'è un header da
leggere, ma la finestra è di un secondo: basta un breve backoff.
Strategia di Retry
Usa un backoff esponenziale con jitter, rispetta retry-after quando è
presente e non riprovare QUOTA_EXCEEDED, che condivide lo status 429:
async function sendWithRetry(url, options, maxRetries = 3) {
for (let attempt = 0; ; attempt++) {
const res = await fetch(url, options);
if (res.status !== 429 || attempt === maxRetries) return res;
const { error } = await res.clone().json();
if (error?.code === 'QUOTA_EXCEEDED') return res; // riprovare non serve
const retryAfter = Number(res.headers.get('retry-after'));
const delay = retryAfter
? retryAfter * 1000
: 2 ** attempt * 1000 + Math.random() * 1000;
await new Promise((r) => setTimeout(r, delay));
}
}Limiti di Piano
Ogni piano ha due tetti:
| Piano | Email al mese | Domini |
|---|---|---|
| Free | 3.000 | 2 |
| Starter | 75.000 | 5 |
| Growth | 500.000 | illimitati |
Non esiste un tetto giornaliero legato al piano. L'unico limite giornaliero del prodotto è quello del test mode — 100 invii di test al giorno, vedi Test Mode.
Se superi la quota mensile le richieste falliscono con QUOTA_EXCEEDED,
anch'esso 429. A differenza di RATE_LIMITED non si risolve riprovando: vedi
Codici di Errore.
Il limite di domini conta tutti i domini del workspace, qualunque sia il loro
stato di verifica, e viene controllato solo quando ne aggiungi uno
(POST /v1/domains). Eliminare un dominio (DELETE /v1/domains/{id}) libera il
suo posto.
Leggi i tuoi limiti dall'API
Non scrivere a mano i numeri qui sopra. GET /v1/workspace restituisce i
limiti realmente applicati al tuo workspace, dove null significa nessun
limite:
curl https://api.tratto.email/v1/workspace \
-H "Authorization: Bearer tratto_live_..."{
"data": {
"plan": "free",
"limits": { "emailsPerMonth": 3000, "domains": 2 }
}
}È la stessa tabella che legge l'enforcement, quindi non può discordare da ciò che ti è davvero permesso inviare.
Il mese è il mese di calendario UTC
La quota non è una finestra mobile di 30 giorni. Il contatore è indicizzato
sul mese di calendario UTC (2026-09) e rotola al primo invio del mese
nuovo: non c'è nessun job schedulato di reset. Un workspace che a ottobre non
invia nulla riparte comunque da zero a novembre, al primo invio di novembre.
Non esiste un piano "Pro", né un piano senza tetto mensile di email. I
piani sono quelli della tabella qui sopra, e GET /v1/workspace riporta sempre
uno di questi.
Comportamento nei Picchi
Nessuno dei due limiti fa una media, e nessuno ammette picchi oltre la soglia. Il limite per chiave conta le richieste in ogni secondo di orologio. Il limite per IP apre una finestra di un minuto alla tua prima richiesta e si azzera quando la finestra finisce. Distribuisci le richieste invece di inviarle a raffiche.
Prossimo: Codici di Errore
Modifica questa pagina su GitHub
Ultimo aggiornamento