Limitazione delle richieste
I limiti di frequenza definiscono quante richieste la tua organizzazione può effettuare in una finestra temporale. Usa gli header di risposta per regolare il traffico e il ritardo di riprovare per recuperare dopo una richiesta rifiutata.
Come vengono associati i limiti
La tua organizzazione condivide un unico limite regionale per ogni policy, tra tutte le sue chiavi API e i suoi spazi di lavoro. Creare un'altra chiave non aggiunge capacità. Organizzazioni diverse hanno limiti separati.
Ogni richiesta consuma una policy cliente. Le policy di prodotto hanno capacità indipendente: recuperare lo stato di un messaggio non consuma il limite generale di recupero risorse, e inviare un'email non consuma il limite di creazione risorse.
Login, reimpostazione della password e altre operazioni sensibili per la sicurezza hanno protezioni anti-abuso aggiuntive. I controlli del fornitore e i limiti di connessione possono anch'essi rifiutare richieste indipendentemente dai limiti di frequenza del tuo piano.
Gruppi
Le operazioni API ordinarie usano queste policy:
| Policy | Operazioni |
|---|---|
| api_get | Recupera una risorsa |
| api_list | Elenca o cerca in una collezione |
| api_create | Crea una risorsa |
| api_update | Aggiorna o esegui upsert di una risorsa |
| api_delete | Elimina una risorsa |
Le operazioni di prodotto usano una policy con nome al posto della policy API ordinaria. Esempi: email_send, email_batch, sms_send, whatsapp_send, lookup e message_status_read. Le policy batch contano le richieste di invio; il numero di destinatari del batch non consuma unità di policy aggiuntive. Consulta invio email in batch e invio SMS in batch per i limiti di dimensione dei batch.
Le email REST e l'invio SMTP condividono la capacità email_send. Un invio SMTP DATA consuma un'unità; l'autenticazione SMTP no. Se la policy rifiuta un invio, il server restituisce un errore temporaneo 452 4.3.1 con un ritardo di riprovare e non accetta il messaggio. Mantieni il messaggio in coda e riprova dopo quel ritardo.
La creazione di un broadcast usa api_create; l'avvio di un broadcast esistente usa api_update. La consegna in background ai destinatari non consuma email_send. Le quote di invio e il pacing di consegna restano controlli separati.
La policy voice_call limita l'ammissione delle chiamate in entrata e in uscita. Una policy esaurita rifiuta la chiamata e registra calls_per_second_exceeded; nessuna risposta HTTP è coinvolta. Consulta Chiamate rifiutate.
Come viene determinato il tuo limite
Un override attivo dell'organizzazione imposta la tua frequenza effettiva. Senza un override, si applica il valore del piano attivo; se il piano non ha un valore per quella policy, si applica il default. Un piano o un override può aumentare o diminuire la frequenza. La finestra temporale della policy resta fissa.
Leggi la tua quota effettiva dall'header di risposta RateLimit-Policy, che riporta la chiave della policy insieme alla frequenza e alla finestra applicate a quella chiamata. Se hai bisogno di capacità aggiuntiva, contatta il supporto indicando la chiave della policy e il traffico previsto.
Header di risposta
Le valutazioni della limitazione delle richieste forniscono due header nel formato IETF Structured Fields (RFC 9651):
Esempio di codice
RateLimit-Policy: "email_send";q=1000;w=60
RateLimit: "email_send";r=842;t=35| Header | Significato |
|---|---|
| RateLimit-Policy | La policy applicata: q è la quota (unità massime) e w è la finestra in secondi. |
| RateLimit | Il tuo stato corrente: r è il numero di unità rimanenti e t sono i secondi fino al reset della finestra. |
La stringa tra virgolette indica il nome della policy. In questo esempio, l'organizzazione ha un limite effettivo email_send di 1000 invii ogni 60 secondi, con 842 rimanenti e 35 secondi fino al reset.
Usa r e t per rallentare le richieste prima di ricevere un 429. Il valore t è un ritardo relativo in secondi, non un timestamp Unix.
Quando raggiungi un limite
La tua integrazione deve gestire le risposte 429 come parte del funzionamento normale. Come minimo, rispetta Retry-After e riprova con backoff. Un client che regola anche il proprio ritmo in base agli header RateLimit in tempo reale (vedi Header di risposta) evita di raggiungere il limite.
Una policy cliente esaurita restituisce 429 Too Many Requests con Retry-After in secondi e header di limitazione delle richieste che mostrano r=0. Una protezione indipendente anti-abuso o del fornitore può restituire 429 anche quando la tua policy cliente ha capacità residua. Segui Retry-After per decidere quando riprovare; può differire dal valore t della policy.
Il corpo usa la risposta di errore standard:
Esempio di codice
{
"error": {
"type": "rate_limit_error",
"code": "E01003",
"name": "RateLimited",
"message": "Too many requests. Please retry after the period indicated in the Retry-After header.",
"doc_url": "https://bird.com/docs/api/errors/E01003",
"request_id": "req_01ky7qavkff7qr88vadv6bv948"
}
}Fai branching su type: rate_limit_error. Il messaggio leggibile può cambiare. Leggi la chiave della policy e i tempi di riprovare dagli header:
async function sendWithBackoff(url, headers, payload, maxAttempts = 5) {
for (let attempt = 0; attempt < maxAttempts; attempt++) {
const response = await fetch(url, {
method: "POST",
headers,
body: JSON.stringify(payload),
});
if (response.status !== 429) return response;
const retryAfter = Number(response.headers.get("Retry-After") ?? 2 ** attempt);
await new Promise((resolve) => setTimeout(resolve, retryAfter * 1000));
}
throw new Error("rate limited after max retries");
}import time
import requests
def send_with_backoff(url, headers, payload, max_attempts=5):
for attempt in range(max_attempts):
response = requests.post(url, headers=headers, json=payload)
if response.status_code != 429:
return response
retry_after = int(response.headers.get("Retry-After", 2 ** attempt))
time.sleep(retry_after)
raise RuntimeError("rate limited after max retries")func sendWithBackoff(req *http.Request, maxAttempts int) (*http.Response, error) {
for attempt := range maxAttempts {
if attempt > 0 && req.Body != nil {
if req.GetBody == nil {
return nil, errors.New("request body cannot be replayed")
}
body, err := req.GetBody()
if err != nil {
return nil, err
}
req.Body = body
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
if resp.StatusCode != http.StatusTooManyRequests {
return resp, nil
}
resp.Body.Close()
wait := 1 << attempt
if s, err := strconv.Atoi(resp.Header.Get("Retry-After")); err == nil {
wait = s
}
time.Sleep(time.Duration(wait) * time.Second)
}
return nil, errors.New("rate limited after max retries")
}function sendWithBackoff(ClientInterface $http, RequestInterface $request, int $maxAttempts = 5): ResponseInterface
{
for ($attempt = 0; $attempt < $maxAttempts; $attempt++) {
$response = $http->sendRequest($request);
if ($response->getStatusCode() !== 429) {
return $response;
}
$retryAfter = (int) ($response->getHeaderLine('Retry-After') ?: 2 ** $attempt);
sleep($retryAfter);
}
throw new RuntimeException('rate limited after max retries');
}Per i tentativi successivi della stessa operazione, riutilizza la sua chiave di idempotenza. Mantieni invariato il corpo della richiesta.
Consulta i concetti SDK per il comportamento automatico di riprovare e backoff.
Modalità di errore
Il limitatore di frequenza è fail open: se Bird non riesce a valutare un limite, la richiesta procede anziché ricevere un rifiuto spurio. La limitazione delle richieste protegge la capacità del servizio. Autenticazione e autorizzazione restano i confini di sicurezza. Un'interruzione del limitatore lato Bird non causa un 429.
Prossimi passi
- Errori: la risposta di errore e come fare branching sui tipi di errore
- Idempotenza: riprovare in sicurezza per le richieste con mutazione
- Concetti SDK: comportamento automatico di riprovare e backoff
Risorse correlate
Prosegui con la documentazione, le guide e gli esempi per questo argomento. Le risorse sono in inglese.
Guarda la guidaSend 100 emails in one API callComprendi il concettoWhat does SMS mean?Esplora la funzionalitàEmail batch sendingSegui il percorso di apprendimentoBuild your first integration
Ottieni un brief di implementazione