Glossário

Por que o 429 Retry-After falta na maioria das APIs de redes sociais

Taras Shynkarenko
Taras Shynkarenko
•Atualizado: •10 min de leitura
Uma resposta HTTP 429 com cabeçalho Retry-After ao lado dos sinais de limite de taxa de cinco plataformas sociaisUma resposta HTTP 429 com cabeçalho Retry-After ao lado dos sinais de limite de taxa de cinco plataformas sociais

TL;DR, Resposta Rápida

10 min de leitura

A RFC 6585 define o 429 Too Many Requests e diz que a resposta MAY incluir um cabeçalho Retry-After, que a RFC 9110 define como um número de segundos ou uma data HTTP. Nenhuma das cinco grandes APIs sociais documenta o envio dele. O X aponta para o x-rate-limit-reset, um timestamp Unix. A Meta sinaliza limites com os códigos de erro 4, 17, 32, 613 e 80001 e nunca informa o status HTTP. O LinkedIn devolve 429 sem cabeçalhos documentados e zera à meia-noite UTC. O TikTok devolve 429 com rate_limit_exceeded. O YouTube reporta uma cota esgotada como 403, não como 429.

O que significa 429 Retry-After?

Uma resposta 429 Retry-After é um servidor dizendo a um cliente que ele enviou requisições demais e, opcionalmente, quanto tempo esperar antes da próxima. As duas metades vêm de duas especificações diferentes.

A RFC 6585 define o código de status: "The 429 status code indicates that the user has sent too many requests in a given amount of time ("rate limiting")." Em seguida, torna o cabeçalho opcional: "The response representations SHOULD include details explaining the condition, and MAY include a Retry-After header indicating how long to wait before making a new request."

A RFC 9110 define o cabeçalho em si, na seção 10.2.3: "Servers send the "Retry-After" header field to indicate how long the user agent ought to wait before making a follow-up request." A seção segue descrevendo o que o cabeçalho significa em um 503 e em um redirecionamento 3xx. Ela nunca menciona o 429. A ligação entre o código de status e o cabeçalho está inteira na RFC 6585, e lá ela é um MAY.

A RFC 6585 também deixa a contagem a cargo do servidor: "Note that this specification does not define how the origin server identifies the user, nor how it counts requests." Essa frase explica por que cada plataforma abaixo se comporta de um jeito. O padrão dá a elas um código de status e um cabeçalho opcional, e mais nada.

Se houver um cache na frente do seu cliente de API, a RFC 6585 tem mais uma regra para ele: "Responses with the 429 status code MUST NOT be stored by a cache."

Como fazer o parsing de um valor Retry-After?

A RFC 9110 permite duas formas: "The Retry-After field value can be either an HTTP-date or a number of seconds to delay after receiving the response."

Retry-After: Fri, 31 Dec 1999 23:59:59 GMT
Retry-After: 120

A forma em segundos é "a non-negative decimal integer, representing time in seconds", e a RFC deixa claro que o segundo exemplo significa uma espera de 2 minutos. Um parser precisa lidar com as duas. Tente o inteiro primeiro e, se falhar, trate como data:

from email.utils import parsedate_to_datetime
from datetime import datetime, timezone
 
def retry_after_seconds(value):
    if value.strip().isdigit():
        return int(value)
    when = parsedate_to_datetime(value)
    return max(0, (when - datetime.now(timezone.utc)).total_seconds())

Fileiras de carros parados em um congestionamento na rodovia, uma imagem de um servidor recusando requisições quando chegam demais ao mesmo tempo.

Quais APIs de redes sociais enviam um cabeçalho Retry-After?

Nenhuma das cinco, segundo a própria documentação delas. Cada uma sinaliza um limite de taxa do seu jeito, e duas delas nem sempre usam 429.

PlataformaStatus em um limite de taxaSinal no corpoSinal de tempo na documentaçãoRetry-After documentado
X429code: 88, "Rate limit exceeded"x-rate-limit-reset, um timestamp UnixNão
Meta Graph APINão informadoerror.code de 4, 17, 32, 613 ou 80001estimated_time_to_regain_access em minutos, só no caso de uso comercialNão
LinkedIn429"Resource level throttle limit for calls to this resource is reached."Nenhum, limites diários zeram à meia-noite UTCNão
TikTok429rate_limit_exceededNenhum, janela deslizante de um minutoNão
YouTube403 para cota, 429 só para miniaturasquotaExceeded, uploadRateLimitExceededNenhumNão

Bluesky e Pinterest têm seus próprios esquemas de cabeçalho, tratados no detalhamento do limite de taxa da API do Bluesky e na referência do limite de taxa da API do Pinterest.

Como a API do X sinaliza um limite de taxa?

Com um 429 e três cabeçalhos em toda resposta. A página de limites de taxa do X: "Exceeding limits results in a 429 error until the window resets." Ela documenta x-rate-limit-limit como "Maximum requests allowed", x-rate-limit-remaining como "Requests remaining in window" e x-rate-limit-reset como "Unix timestamp when window resets."

x-rate-limit-reset é o campo a usar, e ele é um horário absoluto, não uma espera. O valor de exemplo do X é 1705420800. Passe isso para uma chamada de sleep como segundos e o worker dorme por uns 54 anos, então subtraia antes o horário Unix atual. A estratégia de recuperação do próprio X tem três passos: "Check x-rate-limit-reset for when the window resets", "Wait until that time before retrying", "Use exponential backoff if needed." O código de exemplo dele espera max(reset_time - time.time(), 60), então nunca menos de um minuto.

O X documenta dois corpos diferentes para a mesma condição. A página de limites de taxa mostra um 429 devolvendo {"errors": [{"code": 88, "message": "Rate limit exceeded"}]}. A página de códigos de resposta descreve os erros como objetos com type, title e detail, e lista um tipo .../rate-limit-exceeded. Baseie-se no status HTTP e trate qualquer um dos dois formatos de corpo como limite de taxa.

A mesma página traz uma pegadinha. O X define o 429 como "Rate limit or usage cap exceeded" e lista um tipo de erro separado, .../usage-capped. Um 429 causado por um teto de uso não se resolve quando o x-rate-limit-reset passa. Confira o tipo de erro antes de agendar um retry para o horário de reset.

Como a Meta sinaliza um limite de taxa?

Com códigos de erro no corpo JSON. A referência de limites de taxa e o guia de tratamento de erros da Meta listam esses códigos, e nenhuma das duas páginas informa qual status HTTP vem junto.

AdaptlyPost
AdaptlyPost

Comece seu teste grátis de 7 dias

Análises multiplataforma

Caixa Social

Assistente com IA

CódigoO que a Meta diz
4"Indicates that the app whose token is being used in the request has reached its rate limit."
17"Indicates that the User whose token is being used in the request has reached their rate limit."
32"Indicates that the User or app whose token is being used in the Pages API request has reached its rate limit."
613"Indicates that a custom rate limit has been reached."
80001"There have been too many calls to this Page account. Wait a bit and try again."

A Meta se contradiz sobre o que fazer em seguida. O guia de tratamento de erros diz, tanto para 4 quanto para 17: "Temporary issue due to throttling. Wait and retry the operation, or examine your API request volume." A referência de limites de taxa diz: "When the limit has been reached, stop making API calls. Continuing to make calls will continue to increase your call count, which will increase the time before calls will be successful again." Fique com a mais rígida, porque tentar de novo sob as regras da Meta deixa o bloqueio mais longo.

O sinal de tempo da Meta depende de qual dos seus dois sistemas de limite de taxa pegou você. O cabeçalho de caso de uso comercial traz estimated_time_to_regain_access, definido como "Time, in minutes, until calls will not longer be throttled." Repare na unidade: o Retry-After conta em segundos, e esse campo conta em minutos. O cabeçalho por app não tem nenhum campo de tempo, o que o detalhamento do cabeçalho x-app-usage explica em detalhe.

Close de um relógio de parede analógico, representando limites que zeram em horário fixo do dia, como a meia-noite UTC.

Como o LinkedIn e o TikTok sinalizam um limite de taxa?

Os dois devolvem um 429 simples e não documentam nenhum cabeçalho de tempo.

A página de limites de taxa do LinkedIn: "Rate limited requests will receive a 429 response." A página de tratamento de erros dá a mensagem: "Resource level throttle limit for calls to this resource is reached." O LinkedIn também não publica os limites em si: "Standard rate limits are not published in documentation." Você os encontra na aba Analytics do Developer Portal, e só para endpoints que você chamou pelo menos uma vez naquele dia UTC.

O tempo vem do calendário, não de um cabeçalho. O LinkedIn afirma que os limites cobrem "a 24 hour period" e "reset at midnight UTC every day." Depois de um 429 do LinkedIn causado pelo seu próprio volume, o primeiro retry útil é às 00:00 UTC seguintes. O LinkedIn também envia 429 por um motivo que não é seu: "In rare cases, LinkedIn may also return a 429 response as part of infrastructure protection. API service will return to normal automatically." Nada na resposta distingue os dois casos.

A página de limites de taxa do TikTok: "Request rate calculation is based on a one minute sliding window. If the number of requests exceeds the threshold, new requests will be throttled and a response will be returned with HTTP status 429 and error code rate_limit_exceeded." A página lista 600 requisições para cada um de /v2/user/info/, /v2/video/query/ e /v2/video/list/. O endpoint de publicação é bem mais apertado. A referência da Content Posting API diz sobre /v2/post/publish/video/init/: "Each user access_token is limited to 6 requests per minute."

O teto diário de postagem do TikTok não é um 429. É um 403 com spam_risk_too_many_posts, descrito como "The daily post cap from the API is reached for the current user." Um loop de retry baseado em 429 nunca vai vê-lo, e um loop que repete todo 4xx vai martelá-lo à toa.

Como o YouTube sinaliza um erro de cota?

Na maioria das vezes, com um 403. A referência de erros do YouTube lista quotaExceeded (403): "The request cannot be completed because you have exceeded your quota." Esse é o erro que uma cota diária esgotada produz, e ele não é um 429.

A visão geral do YouTube informa o orçamento padrão: "Projects that enable the YouTube Data API have a default quota allocation of 100 search.list calls, 100 videos.insert calls, and 10,000 units per day combined for all other endpoints." Ela também observa que "All API requests, including invalid requests, incur at least a one-point quota cost", então retries que falham também gastam cota.

O único 429 na referência de erros do YouTube é das miniaturas: tooManyRequests (429) uploadRateLimitExceeded, "The channel has uploaded too many thumbnails recently. Please try the request again later." O teto diário de uploads é um terceiro status, badRequest (400) uploadLimitExceeded, com uma descrição incisiva: "This is a YouTube platform restriction and is entirely separate from your Google Cloud project's API quota." Um quotaExceeded não dá para repetir no mesmo dia. Aumentar o teto é um processo burocrático, explicado em o que envolve uma extensão de cota da API do YouTube.

O que uma política de retry deve fazer quando falta o Retry-After?

Ler o sinal próprio da plataforma e separar tetos de limites de taxa antes de repetir qualquer coisa.

Se uma resposta trouxer Retry-After, respeite. Caso contrário, tire a espera da plataforma: x-rate-limit-reset menos o horário atual no X, estimated_time_to_regain_access em minutos nos limites de caso de uso comercial da Meta, a próxima meia-noite UTC no LinkedIn e pelo menos um minuto na janela deslizante do TikTok. Para os erros por app da Meta, pare a fila e confira o X-App-Usage antes de retomar.

Depois, desvie os erros que parecem limites de taxa mas não são: o spam_risk_too_many_posts do TikTok, o quotaExceeded e o uploadLimitExceeded do YouTube e o teto de uso do X. Esses são tetos diários, e um backoff medido em segundos não resolve nenhum deles.

Ordem de decisão para o retry
1
Classifique o erro. Tetos diários, como spam_risk_too_many_posts do TikTok, quotaExceeded e uploadLimitExceeded do YouTube e o teto de uso do X, não somem com backoff. Não tente de novo.
2
Procure o Retry-After. Se a resposta trouxer o cabeçalho, respeite o valor.
3
Leia o sinal da plataforma. x-rate-limit-reset menos o horário atual no X, estimated_time_to_regain_access em minutos na Meta, a próxima meia-noite UTC no LinkedIn e pelo menos um minuto no TikTok.
4
Verifique os erros da Meta no nível do app. Pare a fila e confira o X-App-Usage antes de retomar.
Separar tetos de limites de taxa vem primeiro, porque um backoff de segundos só resolve os limites de taxa.

Perguntas frequentes

O cabeçalho Retry-After é obrigatório em uma resposta 429?

Não. A RFC 6585 diz que uma resposta 429 "MAY include a Retry-After header indicating how long to wait before making a new request." Só a explicação da condição é um SHOULD.

AdaptlyPost
AdaptlyPost

Comece seu teste grátis de 7 dias

Análises multiplataforma

Caixa Social

Assistente com IA

Quais formatos um cabeçalho Retry-After pode usar?

A RFC 9110 permite uma data HTTP, como Fri, 31 Dec 1999 23:59:59 GMT, ou um número inteiro não negativo de segundos, como 120. Os parsers precisam lidar com os dois.

A API do X envia Retry-After em um 429?

As páginas de limites de taxa e de erros do X não documentam isso. Elas mandam você para o x-rate-limit-reset, um timestamp Unix que marca quando a janela zera, e o código de exemplo do X espera pelo menos 60 segundos.

Que status HTTP a Graph API do Facebook devolve para um limite de taxa?

A Meta não informa isso na referência de limites de taxa nem no guia de tratamento de erros. As duas páginas identificam limites de taxa pelo campo code no corpo de erro JSON: 4, 17, 32, 613, ou 80001 para os limites de caso de uso comercial de Páginas.

A YouTube Data API devolve 429 quando a cota acaba?

Não. Uma cota esgotada devolve 403 com o motivo quotaExceeded. O único 429 na referência de erros do YouTube é o uploadRateLimitExceeded em uploads de miniaturas.

Quando o limite de taxa da API do LinkedIn zera?

À meia-noite UTC. A página de limites de taxa do LinkedIn diz que os limites cobrem um período de 24 horas e "reset at midnight UTC every day." O LinkedIn não documenta nenhum cabeçalho de reset, então calcule a espera pelo relógio.

Como transformar o x-rate-limit-reset em um tempo de espera?

Subtraia o horário Unix atual, porque ele é um timestamp absoluto e não um atraso. O valor de exemplo do X é 1705420800, e, passado como segundos a uma chamada sleep, o worker dorme cerca de 54 anos. O código de exemplo do X espera max(reset_time - time.time(), 60), ou seja, nunca menos de um minuto.

Devo tentar de novo um erro quotaExceeded do YouTube?

No mesmo dia, não. Um quotaExceeded (403) significa que a cota diária acabou, e toda requisição, inclusive as inválidas, custa pelo menos um ponto, então novas tentativas só gastam mais cota. Subir o teto é um processo burocrático.

O que o TikTok devolve quando o limite diário de posts é atingido?

Um 403 com o código de erro spam_risk_too_many_posts, descrito como "O limite diário de posts da API foi atingido para o usuário atual." Ele não é um 429, então um loop de retry baseado em 429 nunca o vê. Repetir todo 4xx só martela o endpoint à toa.

Devo continuar tentando quando a Meta devolve o código de erro 4 ou 17?

Pare as chamadas. A referência de rate limiting da Meta avisa que continuar chamando aumenta a contagem de chamadas, o que alonga o tempo até as chamadas voltarem a funcionar. O guia de tratamento de erros manda esperar e tentar de novo, então as duas páginas se contradizem, e a regra mais estrita é a mais segura.

Este artigo foi útil para você?

Conte-nos o que você achou!

Veja-nos mais no Google

Um clique marca a AdaptlyPost como fonte preferida e nossos artigos passam a aparecer mais acima nas suas Principais notícias, no modo IA e nas visões gerais com IA.

Antes de ir...

AdaptlyPost

AdaptlyPost

Agende seu conteúdo em todas as plataformas

Gerencie todas as suas contas de redes sociais em um só lugar com o AdaptlyPost.

Análises multiplataforma

Caixa Social

Assistente com IA

Termos relacionados do glossário

Artigos Relacionados