Limity żądań
Limity żądań określają, ile żądań Twoja organizacja może wysłać w danym oknie czasowym. Korzystaj z nagłówków odpowiedzi, aby regulować ruch, oraz z opóźnienia retry, aby odzyskać sprawność po odrzuconym żądaniu.
Jak przydzielane są limity
Twoja organizacja współdzieli jeden regionalny limit dla każdej polityki między wszystkimi swoimi kluczami API i obszarami roboczymi. Utworzenie kolejnego klucza nie zwiększa przepustowości. Różne organizacje mają osobne limity.
Każde żądanie zużywa jedną jednostkę polityki klienta. Polityki produktowe mają niezależną przepustowość: pobranie statusu wiadomości nie zużywa ogólnego limitu pobierania zasobów, a wysłanie e-maila nie zużywa limitu tworzenia zasobów.
Logowanie, resetowanie hasła i inne operacje wrażliwe pod względem bezpieczeństwa mają dodatkowe zabezpieczenia przed nadużyciami. Kontrole dostawcy i limity połączeń również mogą odrzucać żądania niezależnie od limitów Twojego planu.
Grupy
Zwykłe operacje API korzystają z następujących polityk:
| Polityka | Operacje |
|---|---|
| api_get | Pobranie jednego zasobu |
| api_list | Listowanie lub wyszukiwanie kolekcji |
| api_create | Utworzenie zasobu |
| api_update | Aktualizacja lub upsert zasobu |
| api_delete | Usunięcie zasobu |
Operacje produktowe używają nazwanej polityki zamiast zwykłej polityki API. Przykłady to email_send, email_batch, sms_send, whatsapp_send, lookup i message_status_read. Polityki batch zliczają żądania wysyłki; liczba odbiorców w batchu nie zużywa dodatkowych jednostek polityki. Limity rozmiaru batcha opisano w sekcjach wysyłanie e-maili w batchach i wysyłanie SMS w batchach.
E-mail REST i wysyłka SMTP współdzielą przepustowość email_send. Wysyłka SMTP DATA zużywa jedną jednostkę; uwierzytelnianie SMTP nie zużywa. Jeśli polityka odrzuci wysyłkę, serwer zwraca tymczasowy 452 4.3.1 z opóźnieniem retry i nie przyjmuje wiadomości. Zachowaj wiadomość w kolejce i spróbuj ponownie po tym opóźnieniu.
Utworzenie broadcastu zużywa api_create; uruchomienie istniejącego broadcastu zużywa api_update. Dostarczanie w tle do jego odbiorców nie zużywa email_send. Limity wysyłki i ograniczanie tempa dostarczania pozostają osobnymi mechanizmami.
Polityka voice_call ogranicza przyjmowanie połączeń przychodzących i wychodzących. Wyczerpana polityka odrzuca połączenie i rejestruje calls_per_second_exceeded; odpowiedź HTTP nie jest tu stosowana. Zobacz Odrzucone połączenia.
Jak ustalany jest Twój limit
Aktywne nadpisanie na poziomie organizacji wyznacza Twój obowiązujący limit. Bez nadpisania obowiązuje wartość z aktywnego planu; jeśli plan nie ma wartości dla danej polityki, stosowana jest wartość domyślna. Plan lub nadpisanie może podnieść lub obniżyć limit. Okno czasowe polityki pozostaje stałe.
Odczytaj obowiązujący przydział z nagłówka odpowiedzi RateLimit-Policy, który zawiera klucz polityki wraz z limitem i oknem zastosowanym do tego wywołania. Jeśli potrzebujesz większej przepustowości, skontaktuj się ze wsparciem, podając klucz polityki i oczekiwany ruch.
Nagłówki odpowiedzi
Ewaluacje limitów żądań zwracają dwa nagłówki w formacie IETF Structured Fields (RFC 9651):
Przykład kodu
RateLimit-Policy: "email_send";q=1000;w=60
RateLimit: "email_send";r=842;t=35| Nagłówek | Znaczenie |
|---|---|
| RateLimit-Policy | Polityka, która obowiązuje: q to przydział (maksymalna liczba jednostek), a w to okno w sekundach. |
| RateLimit | Twój bieżący stan: r to liczba pozostałych jednostek, a t to sekundy do resetu okna. |
Ciąg znaków w cudzysłowie oznacza nazwę polityki. W tym przykładzie organizacja ma obowiązujący limit email_send wynoszący 1000 wysyłek na 60 sekund, z 842 pozostałymi i 35 sekundami do resetu.
Używaj r i t, aby zwalniać żądania, zanim otrzymasz 429. Wartość t to względne opóźnienie w sekundach, a nie znacznik czasu Unix.
Gdy osiągniesz limit
Twoja integracja musi obsługiwać odpowiedzi 429 jako część normalnego działania. Jako minimum honoruj Retry-After i ponawiaj żądanie z backoffem. Klient, który dodatkowo reguluje tempo na podstawie bieżących nagłówków RateLimit (zobacz Nagłówki odpowiedzi), unika osiągnięcia limitu.
Wyczerpana polityka klienta zwraca 429 Too Many Requests z Retry-After w sekundach i nagłówkami limitu pokazującymi r=0. Niezależne zabezpieczenie przed nadużyciami lub ochrona dostawcy może zwrócić 429 nawet wtedy, gdy Twoja polityka klienta ma jeszcze wolną przepustowość. Kieruj się wartością Retry-After, aby zdecydować, kiedy ponowić żądanie; może się ona różnić od wartości t polityki.
Treść odpowiedzi używa standardowej odpowiedzi z błędem:
Przykład kodu
{
"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"
}
}Rozgałęziaj logikę na podstawie type: rate_limit_error. Czytelna dla człowieka wiadomość może się zmienić. Odczytaj klucz polityki i czas ponowienia z nagłówków:
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');
}Przy ponowieniach tej samej operacji użyj ponownie jej klucza idempotentności. Nie zmieniaj treści żądania.
Zobacz koncepcje SDK, aby poznać automatyczne ponawianie i zachowanie backoff.
Tryb awarii
Limiter przepuszcza w razie awarii: jeśli Bird nie może ocenić limitu, żądanie jest realizowane zamiast otrzymać fałszywe odrzucenie. Ograniczanie liczby żądań chroni przepustowość usługi. Uwierzytelnianie i autoryzacja pozostają granicami bezpieczeństwa. Awaria limitera po stronie Bird nie powoduje 429.
Następne kroki
- Błędy: odpowiedź z błędem i rozgałęzianie logiki według typów błędów
- Idempotentność: bezpieczne ponawianie żądań modyfikujących
- Koncepcje SDK: automatyczne ponawianie i zachowanie backoff
Powiązane zasoby
Kontynuuj z dokumentacją, przewodnikami i przykładami dotyczącymi tego tematu. Zasoby są w języku angielskim.
Obejrzyj przewodnikSend 100 emails in one API callZrozum koncepcjęWhat does SMS mean?Poznaj możliwościEmail batch sendingPodążaj ścieżką naukiBuild your first integration
Uzyskaj brief wdrożeniowy