Pular para o conteúdo principal

Limites de uso

Os limites são aplicados por credencial, debaixo de um teto da conta, e por categoria de rota, numa janela móvel de 60 segundos.

CategoriaRotasLimite
Envio de mensagensPOST /messages e POST /v1/.../messages500 req/min
Upload de mídiaPOST /v1/.../media60 req/min
Consultastodo o resto (/templates, /events, demais /v1/*)60 req/min

Os valores da tabela são o padrão. O seu plano pode definir limites próprios por categoria, e aí valem os do plano.

Não têm limite: /plans e /health.

Por chave, com um teto da conta​

Cada chave de API tem o seu próprio balde, do tamanho que o plano define — e cada pessoa conectada ao painel também. Uma integração presa num loop esgota só a própria cota: a chave do plugin do WordPress martelando /v1 não deixa a chave do seu ERP em 429.

Acima dos baldes das chaves, a conta tem um teto por categoria, por padrão 3 vezes o limite do plano. É ele que impede que criar mais chaves multiplique a cota sem fim: com o envio em 500/min, uma chave sozinha chega a 500 envios por minuto, e todas as chaves da conta juntas, a 1.500.

O painel fica fora desse teto: quem está conectado gasta só o próprio balde. Uma chave em loop pode esgotar o teto da conta, mas não tranca você fora do painel — que é onde você encontra e revoga essa chave.

Headers de controle​

Toda resposta de rota limitada traz o estado atual do balde:

HeaderConteúdo
X-RateLimit-Categorysend, media ou default
X-RateLimit-ScopeO balde descrito: key (chave de API), session (painel) ou account
X-RateLimit-LimitTeto desse balde na janela
X-RateLimit-RemainingQuanto ainda resta

Numa resposta bem-sucedida, os headers descrevem o balde da sua credencial. Num 429, descrevem o balde que recusou — que pode ser o da conta.

HTTP/1.1 201 Created
X-RateLimit-Category: send
X-RateLimit-Scope: key
X-RateLimit-Limit: 500
X-RateLimit-Remaining: 487

Monitore X-RateLimit-Remaining e desacelere antes de bater no teto — é mais barato que tratar 429.

Quando o limite estoura​

HTTP/1.1 429 Too Many Requests
Retry-After: 12
X-RateLimit-Category: send
X-RateLimit-Scope: key
X-RateLimit-Limit: 500
X-RateLimit-Remaining: 0
{
"error": {
"message": "Rate limit exceeded for send requests with this credential. Try again in 12s.",
"type": "rate_limit",
"scope": "key"
}
}

O campo error.scope repete o X-RateLimit-Scope. Quando ele vem account, a sua chave ainda tinha cota: foram as outras chaves da conta, somadas, que esgotaram o teto. Distribuir as chamadas por mais chaves não resolve — só esperar.

O header Retry-After diz exatamente quantos segundos esperar. Respeite esse valor — insistir antes só consome cota.

Tratando o 429​

Node.js — retry respeitando o Retry-After
async function enviar(payload, tentativa = 0) {
const response = await fetch('https://api.joinotify.com/messages', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.JOINOTIFY_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(payload),
});

if (response.status === 429 && tentativa < 3) {
const espera = Number(response.headers.get('retry-after') ?? 5);
await new Promise((resolve) => setTimeout(resolve, espera * 1000));
return enviar(payload, tentativa + 1);
}

return response.json();
}

Para disparos em massa, prefira uma fila com taxa controlada (por exemplo 8 mensagens por segundo, bem abaixo das 500/min) em vez de disparar tudo e reagir ao erro.

Os limites da Meta também valem​

Os números acima são os limites do Joinotify. Por baixo, a Meta impõe os dela — o limite de mensagens iniciadas pela empresa em 24 horas, que varia conforme a qualidade e o nível de verificação do seu número.

Quando é a Meta que recusa, a resposta vem como meta_error com o corpo original dela em error.meta, e não como rate_limit.

Precisa de mais?​

Os limites são configuráveis por conta. Se o seu volume exige mais, fale com o suporte com uma estimativa de pico por minuto.