Pular para o conteúdo
Decoding Chat API

Limites de taxa

O Decoding Chat limita o tráfego da API HTTP com um bucket por rota e um bucket global. Um bucket é uma cota contada em uma janela. O Decoding Chat recusa uma requisição acima da cota com 429, code definido como RATE_LIMITED, um objeto de resposta de limite de taxa e os cabeçalhos de limite de taxa.

Quase toda rota declara o próprio bucket. O nome de um bucket pode conter um marcador de parâmetro de caminho, escrito como dois-pontos seguidos do nome do parâmetro, como em guild:emojis:list::guild_id. O Decoding Chat substitui o valor da requisição antes de indexar o bucket, então uma rota mantém cota separada para cada recurso de caminho.

Todo bucket também é indexado pela identidade de quem chama. Uma requisição autenticada é indexada pela conta e pelo tipo de credencial, e uma credencial bearer OAuth2 é indexada também pela aplicação dona. Uma sessão, um token de bot, uma chave da API de administração e cada aplicação bearer consomem, portanto, cotas separadas para a mesma conta.

Uma requisição que não resolve conta é indexada pelo endereço IP do cliente, exatamente no caso de IPv4 e pelo /64 no caso de IPv6, então clientes no mesmo /64 dividem uma cota. Quando a implantação está configurada para ler o endereço de um cabeçalho que a requisição não traz, o Decoding Chat recusa a requisição com 403 FORBIDDEN antes de avaliar qualquer bucket.

Uma requisição também conta contra o bucket global, a menos que o bucket de rota dela seja declarado isento. O bucket global é indexado pela mesma identidade, então uma requisição que não resolve conta consome a cota global do endereço IP do cliente.

Estes buckets são isentos, e cada um é o único bucket que sua rota declara: webhook:execute::webhook_id, webhook:message_get::webhook_id, webhook:message_edit::webhook_id, webhook:message_delete::webhook_id, webhook:github::webhook_id, webhook:instatus::webhook_id e stripe:webhook. Essas rotas não consomem cota global. Os buckets user:group_dm:create e user:group_dm:recipient:add também são isentos. Cada um é um segundo bucket em uma rota cujo primeiro bucket não é isento, então as duas rotas continuam consumindo a cota global.

Toda operação da API HTTP e da API de administração declara um bucket, com exceção das rotas de download do desktop, que não declaram nenhum. Quem chama o documento de cliente Bluesky sem credencial é indexado pelo endereço IP do cliente.

A janela global é de um segundo. A cota padrão é de 50 requisições por segundo, e uma conta com o sinalizador HIGH_GLOBAL_RATE_LIMIT recebe 1.200 requisições por segundo. O sinalizador RATE_LIMIT_BYPASS isenta a conta do bucket global e de todos os buckets de rota. Uma resposta bem-sucedida para essa conta não traz cabeçalho de limite de taxa.

Algumas operações aplicam um limite adicional dentro do handler. RATE_LIMIT_BYPASS não isenta a conta de nenhum deles. Limites aplicados dentro de um handler traz o conjunto completo.

Algumas rotas declaram um segundo bucket de rota, entre elas a criação de mensagem direta em grupo, a adição de destinatários ao grupo e a exclusão de emoji ou figurinhas do servidor. Cada operação lista os próprios limites. O Decoding Chat conta a requisição nos buckets de rota antes de o handler rodar, então uma requisição que o handler recusa ainda consome cota.

Uma implantação pode desligar os dois buckets pela configuração da instância. Enquanto estiverem desligados, nenhuma resposta traz cabeçalho X-RateLimit-* e nenhuma requisição é recusada com 429 RATE_LIMITED. Essa chave também desliga as cotas de login. Todo outro limite aplicado dentro de um handler continua valendo.

O corpo da recusa traz os membros da resposta de erro comum e mais dois membros.

CampoTipoDescrição
code1stringRATE_LIMITED em uma recusa de bucket
message2stringA mensagem de limite de taxa localizada
globalbooleanSe a recusa veio do bucket global, presente e falso em recusa de rota
retry_after3numberO atraso em segundos fracionários antes de outra requisição ser admitida

1 Um limite aplicado fora do middleware de bucket de rota pode reutilizar este corpo com código próprio. Enviar verificação de telefone é o único caso em uso, informando PHONE_RATE_LIMIT_EXCEEDED

2 O idioma resolvido para a requisição, que a configuração da conta seleciona antes do Accept-Language

3 Nunca abaixo de 0,001, recorrendo ao valor de Retry-After em segundos inteiros quando nenhum atraso fracionário foi calculado

O período de espera de Reenviar autorização de IP responde 429 com código próprio e corpo diferente. Cotas que respondem 429 descreve o que esse corpo traz.

Uma recusa de modo lento responde 400 SLOWMODE_RATE_LIMITED.

{
"code": "RATE_LIMITED",
"message": "You're being rate limited.",
"global": false,
"retry_after": 0.428
}

O cabeçalho X-RateLimit-Scope traz o escopo que produziu a recusa.

ValorDescrição
userA recusa veio de uma cota indexada apenas por quem chamou
globalA recusa veio do bucket global
shared1A recusa veio de uma cota que várias contas podem esgotar umas para as outras

1 Nenhum bucket de rota declara escopo próprio, então toda recusa de bucket de rota informa user. Enviar verificação de telefone é a única origem em uso de shared

A verificação de telefone informa shared quando a cota de envios por número ou um período de espera do provedor por número produziu a recusa. As duas são indexadas pelo número enviado, então duas contas enviando para um mesmo número dividem a cota.

Estes cabeçalhos descrevem uma decisão de limite de taxa. Uma operação que responde 429 devolve este conjunto.

CampoTipoDescrição
Retry-After?1stringO atraso em segundos inteiros antes de outra requisição ser admitida, arredondado para cima e nunca abaixo de 1
X-RateLimit-Scope?1stringO escopo de limite de taxa que produziu a recusa
X-RateLimit-Global?2stringO valor literal true em um HTTP 429 global
X-RateLimit-Limit?3stringO máximo de requisições que a cota de rota admite de uma vez
X-RateLimit-Remaining?3stringAs requisições inteiras que a cota de rota ainda admite, sempre 0 em uma recusa
X-RateLimit-Reset?3 4stringO timestamp Unix em segundos em que a cota de rota inteira volta a estar disponível
X-RateLimit-Reset-After?3 5stringOs segundos até a cota de rota inteira voltar a estar disponível
X-RateLimit-Bucket?3 6stringO identificador hexadecimal estável de 16 caracteres do bucket de rota

1 Enviado em toda recusa por limite de taxa e em nenhuma resposta bem-sucedida

2 Enviado apenas quando o bucket global produziu a recusa, caso em que nenhum dos cabeçalhos de bucket de rota é enviado

3 Enviado em um HTTP 429 de rota, observada a nota 6 para X-RateLimit-Bucket. Em resposta bem-sucedida eles são enviados apenas quando a credencial resolve para conta de bot, ou quando a requisição não resolve conta alguma em rota que tenha tanto um parâmetro de caminho webhook_id quanto um token

4 Um valor no segundo atual ou antes dele é substituído pelo segundo seguinte

5 Arredondado com precisão de milissegundos e sem zeros à direita em resposta bem-sucedida, e emitido como o decimal exato calculado em uma recusa

6 Um identificador opaco do bucket da rota, não de quem chama

Um 429 vindo de limite aplicado dentro de um handler traz os demais cabeçalhos de rota e nenhum X-RateLimit-Bucket.

Uma cota aplicada dentro de um handler é indexada de forma independente do bucket de rota e do bucket global, então esgotá-la recusa a requisição enquanto os dois buckets ainda têm espaço. O conjunto abaixo é completo.

A chave de implantação disable_rate_limits desliga as cotas de login junto dos dois buckets. relax_registration_rate_limits desliga as cotas de registro. Toda outra cota abaixo é aplicada em qualquer implantação.

Uma recusa assume uma das formas abaixo. Uma cota listada em Cotas que respondem 429 responde 429 com o objeto de resposta de limite de taxa e os cabeçalhos de limite de taxa menos o X-RateLimit-Bucket. Uma cota listada em Cotas que respondem 400 responde 400 INVALID_FORM_BODY com uma entrada de erro de validação cujo code nomeia a cota esgotada.

A forma 400 não traz membro retry_after, nem cabeçalho X-RateLimit-*, nem cabeçalho Retry-After. O atraso restante aparece apenas na message localizada da entrada.

OperaçãoCotaCódigo
Entrar com senha5 por 15 minutos, indexada pelo e-mail enviadoRATE_LIMITED
Entrar com senha10 por 30 minutos, indexada pelo IP do cliente, exatamente no IPv4 e pelo /64 no IPv6RATE_LIMITED
Registrar uma conta3 por 15 minutos, indexada pelo e-mail enviadoRATE_LIMITED
Registrar uma conta3 por hora, indexada pelo IP do clienteRATE_LIMITED
Registrar uma conta15 por hora, indexada pela sub-rede do cliente, o /24 no IPv4 ou o /48 no IPv6RATE_LIMITED
Reenviar verificação de e-mail3 por 15 minutos, indexada pelo e-mail armazenado da contaRATE_LIMITED
Solicitar recuperação de senha20 por 30 minutos, indexada pelo IP do clienteRATE_LIMITED
Solicitar recuperação de senha5 por 30 minutos, indexada pelo e-mail enviadoRATE_LIMITED
Iniciar troca de e-mail e Reenviar código do e-mail original3 envios por 15 minutos, indexada pela conta autenticadaRATE_LIMITED
Solicitar novo e-mail, Reenviar código do novo e-mail e os dois envios de recuperação de e-mail com devolução5 envios por 15 minutos, indexada pela conta autenticadaRATE_LIMITED
Iniciar troca de senha3 envios por 15 minutos, indexada pela conta autenticadaRATE_LIMITED
Reenviar código de troca de senha3 envios por 15 minutos, indexada pela conta autenticadaRATE_LIMITED
Todo reenvio de código e toda solicitação de novo endereço em um tíquete de troca de e-mail ou de senha1 envio a cada 30 segundos, indexada pelo tíquete e contada a partir do envio anteriorRATE_LIMITED
Denunciar mensagem, Denunciar usuário, Denunciar servidor e Criar denúncia DSA5 por hora, indexada por quem denuncia, seja conta ou e-mail verificadoRATE_LIMITED
Denunciar mensagem3 por hora, indexada por quem denuncia e pelo canal em conjuntoRATE_LIMITED
Denunciar mensagem20 por hora, indexada pela mensagem denunciada, somando todos que denunciamRATE_LIMITED
Denunciar mensagem4 por hora, indexada por quem denuncia e pelo servidor em conjunto, para mensagem de servidorRATE_LIMITED
Enviar verificação de telefone3 por 6 horas, indexada pela conta autenticadaPHONE_RATE_LIMIT_EXCEEDED
Enviar verificação de telefone3 por 5 dias, indexada pelo número enviadoPHONE_RATE_LIMIT_EXCEEDED
Reenviar autorização de IPNada nos primeiros 30 segundos depois de o tíquete ser emitido, indexada pelo tíquete de autorizaçãoIP_AUTHORIZATION_RESEND_COOLDOWN

A limitação do provedor de SMS pode impor um período de espera adicional. Ela retorna PHONE_RATE_LIMIT_EXCEEDED com o atraso restante.

O período de espera de Reenviar autorização de IP não traz cabeçalho X-RateLimit-*. Ele traz um cabeçalho Retry-After em segundos inteiros, e o corpo repete esse atraso como resend_available_in e retry_after no nível raiz. Um segundo reenvio em um mesmo tíquete retorna 400 IP_AUTHORIZATION_RESEND_LIMIT_EXCEEDED. A cota nunca se reabastece, e o tíquete expira 15 minutos depois de emitido.

OperaçãoCotaCódigo de validação
Modificar usuário atual5 por 3 horas sobre o nome de usuário ou discriminador resultanteUSERNAME_CHANGED_TOO_MANY_TIMES
Modificar usuário atual25 por 30 minutos sobre a biografia, quando o valor enviado for diferenteBIO_CHANGED_TOO_MANY_TIMES
Modificar usuário atual25 por 30 minutos sobre os pronomes, quando o valor enviado for diferentePRONOUNS_CHANGED_TOO_MANY_TIMES
Modificar usuário atual25 por 30 minutos sobre a cor de destaque, quando o valor enviado for diferenteACCENT_COLOR_CHANGED_TOO_MANY_TIMES
Modificar usuário atual25 por 30 minutos sobre qualquer avatar não nuloAVATAR_CHANGED_TOO_MANY_TIMES
Modificar usuário atual25 por 30 minutos sobre qualquer valor de banner que passe pela verificação de direitoBANNER_CHANGED_TOO_MANY_TIMES
Atualizar perfil do bot5 por 3 horas sobre o nome de usuário ou discriminador resultante do botUSERNAME_CHANGED_TOO_MANY_TIMES
Modificar membro atual do servidor25 por 30 minutos sobre o avatar do servidor, sempre que enviadoAVATAR_CHANGED_TOO_MANY_TIMES
Modificar membro atual do servidor25 por 30 minutos sobre o banner do servidor, sempre que enviadoBANNER_CHANGED_TOO_MANY_TIMES
Modificar membro atual do servidor25 por 30 minutos sobre a biografia no servidor, quando o valor enviado for diferenteBIO_CHANGED_TOO_MANY_TIMES
Modificar membro atual do servidor25 por 30 minutos sobre os pronomes no servidor, quando o valor enviado for diferentePRONOUNS_CHANGED_TOO_MANY_TIMES
Modificar membro atual do servidor25 por 30 minutos sobre a cor de destaque no servidor, quando o valor enviado for diferenteACCENT_COLOR_CHANGED_TOO_MANY_TIMES
Modificar a divulgação de atividade de voz1 por 24 horas sobre o padrão de divulgaçãoVOICE_ACTIVITY_SHARING_ON_COOLDOWN
Concluir login com TOTP e Concluir login com MFA WebAuthn10 tentativas de múltiplos fatores por 15 minutosINVALID_CODE
Concluir login com TOTP e Concluir login com MFA WebAuthn5 tentativas de múltiplos fatores por 5 minutos em um mesmo tíquete de MFAINVALID_CODE
Modo sudo com o método totp10 tentativas de múltiplos fatores por 15 minutosINVALID_MFA_CODE

Toda cota de Modificar usuário atual é indexada pela conta autenticada, e a cota de tag do bot pela conta do bot, então um dono que altere a tag de um bot consome a cota do bot. As cotas de membro de servidor são indexadas pelo servidor e pelo membro em conjunto, e uma conta mantém cota separada em cada servidor. As cotas de login são indexadas pela conta e pelo tíquete de MFA, respectivamente, e a cota de sudo pela conta.

O Decoding Chat consome toda cota de múltiplos fatores antes de verificar o código, então um código correto enviado contra uma cota esgotada é reportado exatamente como um código errado. Um código correto zera o contador. A cota por tíquete também destrói o tíquete de MFA ao recusar, e o cliente recomeça a partir de Entrar com senha.

Cotas que não respondem em nenhuma das duas formas

Seção intitulada “Cotas que não respondem em nenhuma das duas formas”

Obter informações de transferência para o desktop e Concluir transferência para o desktop compartilham um contador de tentativas falhas indexado pelo IP do cliente. Cinco falhas bloqueiam as duas operações por 15 minutos a partir da falha mais recente, e uma requisição bloqueada retorna 400 INVALID_HANDOFF_CODE como código raiz, sem entrada de validação. Obter informações de transferência para o desktop permite, à parte, três consultas bem-sucedidas para cada código de transferência e reporta a quarta com o mesmo código raiz.

O modo lento também é aplicado dentro do handler.

O modo lento limita com que frequência uma conta envia mensagem em um canal. O Decoding Chat reporta a recusa como falha comum de requisição. Um envio recusado retorna 400 SLOWMODE_RATE_LIMITED com um retry_after raiz em segundos fracionários e um cabeçalho Retry-After em segundos inteiros. A resposta não traz cabeçalho X-RateLimit-*, então o cliente a distingue de uma recusa de bucket pelo status e pelo código.

A cota é de uma mensagem por intervalo configurado no canal em rate_limit_per_user, contada separadamente para cada par de conta e canal. O Decoding Chat só a conta para conta que não seja bot enviando em canal de servidor cujo intervalo configurado seja maior que zero. Quem tiver BYPASS_SLOWMODE é isento. Obter estado do modo lento no canal informa o atraso restante de quem chama antes de uma tentativa de envio.

Cada superfície de protocolo documenta o próprio contrato de limite de taxa. O Gateway principal descreve seus limites de sessão, comando, replay, contrapressão e admissão em Limites do Gateway. A API do Proxy de mídia não tem limite de taxa por contagem de requisições e limita o trabalho por concorrência, payload e prazo. O repasse de upload autoriza cada transferência com uma URL de upload que expira e limita o tamanho do corpo.