Rate Limits WhatsApp API: Como Evitar Bloqueios e Escalar
Guia completo sobre limites de mensagens da WhatsApp Business API, tiers de qualidade e como evitar bloqueios em 2025
Entendendo os Rate Limits
A partir de 2025, a Meta mudou como os limites de mensagens funcionam. Agora os limites são aplicados no nível do Business Portfolio, não mais por número de telefone individual.
Tipos de Limites
1. Limite de Conversas por 24h
Este é o principal limite. Conta quantas novas conversas você pode iniciar em uma janela de 24 horas.
| Tier | Limite de Conversas/24h | |------|------------------------| | Não verificado | 250 | | Tier 1 | 1.000 | | Tier 2 | 10.000 | | Tier 3 | 100.000 | | Tier 4 | Ilimitado |
2. Limite de Requisições à API
Além das conversas, há limites na quantidade de chamadas à API:
- Mensagens: ~80 por segundo por número
- Templates: ~60 por segundo
- Mídia upload: ~30 por segundo
Erro 131056: Rate Limit Atingido
{
"error": {
"message": "(#131056) Rate limit hit",
"type": "OAuthException",
"code": 131056,
"error_subcode": 2494055,
"fbtrace_id": "..."
}
}
Causas Comuns
- Muitas conversas iniciadas em 24h
- Muitas mensagens para o mesmo número
- Muitas requisições à API em curto período
Solução: Implementar Rate Limiting
import Bottleneck from 'bottleneck';
// Limiter para requisições à API
const apiLimiter = new Bottleneck({
minTime: 50, // 50ms entre requisições = 20/segundo
maxConcurrent: 5,
reservoir: 1000, // 1000 requisições
reservoirRefreshAmount: 1000,
reservoirRefreshInterval: 60 * 1000 // Renova a cada minuto
});
// Limiter para novas conversas
const conversationLimiter = new Bottleneck({
reservoir: 200, // Buffer de segurança abaixo do limite
reservoirRefreshAmount: 200,
reservoirRefreshInterval: 24 * 60 * 60 * 1000 // Renova a cada 24h
});
async function sendMessage(to, message) {
return apiLimiter.schedule(() =>
conversationLimiter.schedule(() =>
sendWhatsAppMessage(to, message)
)
);
}
Como Subir de Tier
Requisitos para Upgrade
- Verificação do Business: Complete a verificação no Meta Business Suite
- Qualidade da conta: Mantenha status "Connected" ou "High"
- Volume consistente: Envie mensagens regularmente sem problemas
Processo Automático
A Meta aumenta seu tier automaticamente quando:
- Você envia 2x o limite do tier atual em 7 dias
- Sua qualidade permanece alta
- Não há muitos bloqueios/denúncias
// Monitorar uso para saber quando está próximo do upgrade
async function checkUsageStats() {
const response = await fetch(
`https://graph.facebook.com/v18.0/${wabaId}?fields=analytics.start(${startDate}).end(${endDate}).granularity(DAY)`,
{
headers: {
'Authorization': `Bearer ${accessToken}`
}
}
);
const data = await response.json();
return data.analytics;
}
Quality Rating: A Chave para Escalar
Status de Qualidade
| Status | Significado | Ação | |--------|-------------|------| | 🟢 High | Excelente | Continue assim | | 🟡 Medium | Atenção | Revise suas mensagens | | 🔴 Low | Problema | Pare e corrija | | ⚫ Flagged | Crítico | Risco de suspensão |
O que Afeta a Qualidade
Negativo:
- Usuários bloqueando seu número
- Denúncias de spam
- Respostas "Não quero receber"
- Templates rejeitados
Positivo:
- Usuários respondendo
- Conversas longas
- Poucas denúncias
- Templates aprovados de primeira
Monitorar Qualidade via API
async function checkQualityRating() {
const response = await fetch(
`https://graph.facebook.com/v18.0/${phoneNumberId}?fields=quality_rating,messaging_limit_tier`,
{
headers: {
'Authorization': `Bearer ${accessToken}`
}
}
);
const data = await response.json();
console.log('Qualidade:', data.quality_rating);
console.log('Tier atual:', data.messaging_limit_tier);
return data;
}
Estratégias para Evitar Bloqueios
1. Warm-up Gradual
Não envie no limite máximo logo de início:
class MessageWarmup {
constructor(dailyLimit) {
this.dailyLimit = dailyLimit;
this.warmupDays = 14;
this.currentDay = 0;
}
getDailyAllowance() {
// Começa com 10% e cresce até 100% em 14 dias
const percentage = Math.min(
0.1 + (this.currentDay * 0.9 / this.warmupDays),
1
);
return Math.floor(this.dailyLimit * percentage);
}
incrementDay() {
this.currentDay++;
}
}
// Uso
const warmup = new MessageWarmup(1000);
console.log('Dia 1:', warmup.getDailyAllowance()); // ~100
warmup.incrementDay();
console.log('Dia 2:', warmup.getDailyAllowance()); // ~164
// ...continua crescendo
2. Backoff Exponencial
Quando receber rate limit, aguarde antes de tentar novamente:
async function sendWithBackoff(to, message, attempt = 1) {
try {
return await sendMessage(to, message);
} catch (error) {
if (error.code === 131056 && attempt <= 5) {
const delay = Math.pow(2, attempt) * 1000; // 2s, 4s, 8s, 16s, 32s
console.log(`Rate limit. Aguardando ${delay/1000}s...`);
await new Promise(r => setTimeout(r, delay));
return sendWithBackoff(to, message, attempt + 1);
}
throw error;
}
}
3. Fila com Prioridade
import { Queue, Worker } from 'bullmq';
const messageQueue = new Queue('whatsapp-messages');
// Adicionar mensagem na fila
async function queueMessage(to, message, priority = 'normal') {
await messageQueue.add(
'send',
{ to, message },
{
priority: priority === 'urgent' ? 1 : 10,
attempts: 3,
backoff: {
type: 'exponential',
delay: 2000
}
}
);
}
// Worker processa respeitando rate limits
const worker = new Worker('whatsapp-messages', async job => {
await sendMessage(job.data.to, job.data.message);
}, {
limiter: {
max: 50, // 50 mensagens
duration: 1000 // por segundo
}
});
4. Segmentação Inteligente
Não envie para toda sua base de uma vez:
async function sendCampaign(recipients, template) {
// Divida em lotes
const batchSize = 100;
const batches = [];
for (let i = 0; i < recipients.length; i += batchSize) {
batches.push(recipients.slice(i, i + batchSize));
}
// Envie com intervalo entre lotes
for (const batch of batches) {
await Promise.all(
batch.map(r => queueMessage(r.phone, template))
);
// Aguarde 1 minuto entre lotes
await new Promise(r => setTimeout(r, 60000));
// Verifique qualidade
const quality = await checkQualityRating();
if (quality.quality_rating === 'LOW') {
console.log('Qualidade baixa! Pausando campanha.');
break;
}
}
}
Limites por Número de Destino
Além dos limites gerais, há limite de mensagens por destinatário:
- Máximo de ~256 mensagens de template por conversa
- Se o usuário não responde, espaçe as mensagens
// Tracking de mensagens por usuário
const userMessageCount = new Map();
async function sendToUser(userId, message) {
const count = userMessageCount.get(userId) || 0;
if (count >= 3 && !hasUserReplied(userId)) {
// Usuário não respondeu após 3 mensagens
console.log('Muitas mensagens sem resposta. Pulando.');
return;
}
await sendMessage(userId, message);
userMessageCount.set(userId, count + 1);
}
Dashboard de Monitoramento
class WhatsAppMonitor {
constructor() {
this.metrics = {
sent: 0,
delivered: 0,
read: 0,
failed: 0,
rateLimited: 0
};
}
recordSent() { this.metrics.sent++; }
recordDelivered() { this.metrics.delivered++; }
recordFailed() { this.metrics.failed++; }
recordRateLimited() { this.metrics.rateLimited++; }
getStats() {
return {
...this.metrics,
deliveryRate: this.metrics.sent > 0
? (this.metrics.delivered / this.metrics.sent * 100).toFixed(2) + '%'
: '0%',
rateLimitRate: this.metrics.sent > 0
? (this.metrics.rateLimited / this.metrics.sent * 100).toFixed(2) + '%'
: '0%'
};
}
shouldPause() {
// Pause se mais de 5% das mensagens estão dando rate limit
const rate = this.metrics.rateLimited / this.metrics.sent;
return rate > 0.05;
}
}
Conclusão
Para escalar com a WhatsApp API sem bloqueios:
- Comece devagar - Faça warm-up gradual
- Monitore qualidade - Pare se cair
- Use filas - Controle o volume
- Implemente backoff - Respeite os limites
- Segmente campanhas - Não envie tudo de uma vez
Quer ajuda para escalar sua operação WhatsApp? Fale comigo para consultoria especializada.