Limitação de requisições
Limites de requisições definem quantas requisições sua organização pode fazer em uma janela de tempo. Use os cabeçalhos de resposta para controlar o tráfego e o atraso de nova tentativa para se recuperar de uma requisição rejeitada.
Como os limites são definidos
Sua organização compartilha um limite regional para cada política, entre todas as suas chaves API e espaços de trabalho. Criar outra chave não adiciona capacidade. Organizações diferentes têm limites separados.
Cada requisição consome uma política de cliente. Políticas de produto têm capacidade independente: consultar o status de uma mensagem não consome o limite geral de recuperação de recursos, e enviar um e-mail não consome o limite de criação de recursos.
Login, redefinição de senha e outras operações sensíveis à segurança têm proteções adicionais contra abuso. Verificações de fornecedor e limites de conexão também podem rejeitar requisições independentemente dos limites de requisições do seu plano.
Grupos
Operações comuns de API usam estas políticas:
| Política | Operações |
|---|---|
| api_get | Recuperar um recurso |
| api_list | Listar ou pesquisar uma coleção |
| api_create | Criar um recurso |
| api_update | Atualizar ou fazer upsert de um recurso |
| api_delete | Excluir um recurso |
Operações de produto usam uma política nomeada no lugar da política comum API. Exemplos incluem email_send, email_batch, sms_send, whatsapp_send, lookup e message_status_read. Políticas de lote contam requisições de envio; a quantidade de destinatários do lote não consome unidades extras de política. Consulte envio de e-mail em lote e envio de SMS em lote para limites de tamanho de lote.
E-mail REST e envio SMTP compartilham a capacidade de email_send. Um envio DATA SMTP consome uma unidade; autenticação SMTP não consome. Se a política negar um envio, o servidor retorna 452 4.3.1 temporário com um atraso de nova tentativa e não aceita a mensagem. Mantenha a mensagem na fila e tente novamente após esse atraso.
Criar um broadcast usa api_create; iniciar um broadcast existente usa api_update. A entrega em segundo plano aos destinatários não consome email_send. Cotas de envio e controle de ritmo de entrega continuam sendo controles separados.
A política voice_call limita a admissão de chamadas de entrada e saída. Uma política esgotada recusa a chamada e registra calls_per_second_exceeded; nenhuma resposta HTTP está envolvida. Consulte Chamadas rejeitadas.
Como seu limite é resolvido
Uma substituição ativa na organização define sua taxa efetiva. Sem substituição, o valor do plano ativo é aplicado; se o plano não tiver valor para essa política, o padrão é aplicado. Um plano ou substituição pode aumentar ou diminuir a taxa. A janela de tempo da política permanece fixa.
Leia sua cota efetiva no cabeçalho de resposta RateLimit-Policy, que informa a chave da política junto com a taxa e a janela aplicadas àquela chamada. Se você precisar de capacidade adicional, entre em contato com o suporte informando a chave da política e o tráfego esperado.
Cabeçalhos de resposta
As avaliações de limitação de requisições fornecem dois cabeçalhos no formato IETF Structured Fields (RFC 9651):
Exemplo de código
RateLimit-Policy: "email_send";q=1000;w=60
RateLimit: "email_send";r=842;t=35| Cabeçalho | Significado |
|---|---|
| RateLimit-Policy | A política aplicada: q é a cota (máximo de unidades) e w é a janela em segundos. |
| RateLimit | Seu estado atual: r é o número de unidades restantes e t é os segundos até a janela ser reiniciada. |
A string entre aspas nomeia a política. Neste exemplo, a organização tem um limite efetivo email_send de 1.000 envios por 60 segundos, com 842 restantes e 35 segundos até o reinício.
Use r e t para reduzir requisições antes de receber um 429. O valor de t é um atraso relativo em segundos, não um timestamp Unix.
Quando você atinge um limite
Sua integração deve tratar respostas 429 como parte da operação normal. No mínimo, respeite Retry-After e tente novamente com backoff. Um cliente que também controla seu ritmo com base nos cabeçalhos RateLimit ativos (consulte Cabeçalhos de resposta) evita atingir o limite.
Uma política de cliente esgotada retorna 429 Too Many Requests com Retry-After em segundos e cabeçalhos de limitação de requisições mostrando r=0. Uma proteção independente contra abuso ou de fornecedor pode retornar 429 mesmo quando sua política de cliente ainda tem capacidade restante. Siga Retry-After para decidir quando tentar novamente; ele pode diferir do valor de t da política.
O corpo usa a resposta de erro padrão:
Exemplo de código
{
"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"
}
}Faça a ramificação com base em type: rate_limit_error. A mensagem legível pode mudar. Leia a chave da política e o tempo de nova tentativa nos cabeçalhos:
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');
}Para novas tentativas da mesma operação, reutilize sua chave de idempotência. Mantenha o corpo da requisição inalterado.
Consulte conceitos de SDK para comportamento de nova tentativa automática e backoff.
Modo de falha
O limitador de requisições falha de forma aberta: se Bird não conseguir avaliar um limite, a requisição prossegue em vez de receber uma recusa espúria. A limitação de requisições protege a capacidade do serviço. Autenticação e autorização continuam sendo os limites de segurança. Uma indisponibilidade do limitador no lado Bird não causa um 429.
Próximos passos
- Erros: a resposta de erro e como ramificar por tipos de erro
- Idempotência: novas tentativas seguras para requisições que alteram dados
- Conceitos de SDK: comportamento de nova tentativa automática e backoff
Recursos relacionados
Continue com a documentação, guias e exemplos sobre este tópico. Os recursos estão em inglês.
Assista ao guiaSend 100 emails in one API callEntenda o conceitoWhat does SMS mean?Explore a funcionalidadeEmail batch sendingSiga o percurso de aprendizagemBuild your first integration
Obtenha um resumo de implementação