Rodízio de números no WhatsApp: como distribuir a carga entre instâncias
Quando um cliente tem vários números, a pergunta deixa de ser como enviar e passa a ser por qual número enviar. Jogar tudo no mesmo chip concentra o risco e deixa os outros parados. O rodízio divide o volume, respeita o teto de cada número e tira da fila quem caiu. Este guia mostra a regra, um exemplo em Node.js sobre os endpoints documentados e os limites do método. A API não traz um balanceador pronto: o rodízio é lógica sua, em cima de GET /instances e de send/text. A ZapZap é uma solução não oficial, e o WhatsApp pode limitar ou bloquear qualquer número, mesmo com a carga bem dividida.
Publicado em · 4 min de leitura
Quando o rodízio vale a pena (e quando não)
Vale para operações em que um único cliente conversa com muita gente: um time comercial com várias linhas, uma clínica com unidades, uma loja que responde leads de anúncio o dia inteiro. Dividir o envio reduz o volume por número e deixa a operação viva quando um chip cai.
Não vale para disparo em massa para quem nunca falou com você. Dividir uma lista fria em cinco números só espalha o problema em cinco chips, e o consentimento continua sendo o que mais pesa. Se o número é novo, aqueça antes: veja o aquecimento de chip.
As quatro regras de um rodízio seguro
Primeira, rodízio só entre números conectados: leia a lista de instâncias e filtre pelo status. Segunda, teto diário por número, definido por você a partir da fase de cada chip (a planilha de operação guarda isso). Terceira, o mesmo contato sempre pelo mesmo número: quem já conversou com o número A não deve receber a próxima mensagem do número B, porque a troca confunde o cliente e parece suspeita para o WhatsApp. Quarta, pausa imediata no número que devolve 429 ou queda de status.
A terceira regra pede uma tabela simples no seu sistema: contato, instância de origem. O rodízio só vale para contatos novos. Contatos que já têm dono seguem com ele.
Código: rodízio com teto diário sobre a API
O exemplo lê GET /instances, filtra as conectadas (o status vem como CONNECTED na resposta de exemplo da referência), gira um cursor e pula quem já bateu o teto. O contador está em memória só para o exemplo: em produção, guarde por dia em banco, ou o rodízio zera a cada reinício. A chamada de envio é POST /{instanceId}/send/text com number e text. Veja a referência para os demais campos.
Node.js: round-robin with a daily cap
// Round-robin sender: picks the next CONNECTED instance that is under its daily cap
const BASE = "https://api.zapzapapi.com/api/v1";
const H = {
"Content-Type": "application/json",
"x-api-key": process.env.ZAPZAP_API_KEY,
"x-api-secret": process.env.ZAPZAP_API_SECRET,
};
const DAILY_CAP = 40; // your own limit per number, from your operations sheet
const sentToday = new Map(); // instance id -> count (persist it in a database in production)
let cursor = 0;
async function connectedInstances() {
const res = await fetch(BASE + "/instances", { headers: H });
if (!res.ok) throw new Error("GET /instances failed: HTTP " + res.status);
const list = await res.json();
return list.filter((i) => i.status === "CONNECTED");
}
function pickInstance(pool) {
for (let n = 0; n < pool.length; n++) {
const inst = pool[(cursor + n) % pool.length];
if ((sentToday.get(inst.id) || 0) < DAILY_CAP) {
cursor = (cursor + n + 1) % pool.length;
return inst;
}
}
return null; // every number hit its cap: stop and try again tomorrow
}
export async function sendBalanced(number, text) {
const pool = await connectedInstances();
const inst = pickInstance(pool);
if (!inst) throw new Error("no instance available under the daily cap");
const res = await fetch(BASE + "/" + inst.id + "/send/text", {
method: "POST",
headers: H,
body: JSON.stringify({ number, text }),
});
if (res.status === 429) throw new Error("rate limited, back off on " + inst.name);
if (!res.ok) throw new Error("send failed on " + inst.name + ": HTTP " + res.status);
sentToday.set(inst.id, (sentToday.get(inst.id) || 0) + 1);
return { instance: inst.name, status: res.status };
}Ritmo, 429 e queda: o que o código não resolve sozinho
A referência lista 429 como limite de requisições excedido. Trate como sinal para recuar naquele número e seguir pelos outros, em vez de repetir a chamada em laço. Se todos baterem o teto, a resposta correta é parar e retomar no dia seguinte, e não aumentar o teto.
Não distribua rajadas idênticas: varie o texto, espace os envios e prefira conversas a disparos. A API tem opções de atraso por mensagem, e o envio por lista em /sender/simple aceita atrasos mínimo e máximo; use-os em vez de dormir no seu código quando for campanha agendada.
Custo e acompanhamento
Mais números não mudam o preço unitário: R$15 por número ativo ao mês, pré-pago, sem cobrança por mensagem, então dividir a carga entre 4 números custa R$60 ao mês, qualquer que seja o volume. Antes de criar mais instâncias, consulte o custo no GET /instances/cost, que mostra a taxa de ativação e o saldo necessário.
Registre, por número e por dia: enviadas, respostas e falhas. Um número com taxa de resposta caindo e falhas subindo recua uma fase. Para a visão de preço em escala, veja custo por número e volume e a página de preços. Para o perfil de quem opera assim, veja agências com IA e gestores de tráfego.
Resumo rápido
- A API não traz balanceador pronto: o rodízio é lógica sua, sobre GET /instances e send/text.
- Rodízio só entre números conectados, com teto diário por número e o mesmo contato sempre no mesmo número.
- 429 e queda de status tiram o número da fila na hora; se todos estourarem, pare, não aumente o teto.
- Dividir a carga não substitui consentimento nem aquecimento, e o risco do canal não oficial continua.
- O custo é linear: R$15 por número ativo ao mês, sem cobrança por mensagem.
Continue lendo
Perguntas frequentes
A ZapZap tem rodízio de números pronto na API?
Não há um endpoint de rodízio na referência. A distribuição é feita no seu sistema, escolhendo a instância antes de chamar send/text, como no exemplo do guia.
Qual teto diário devo usar por número?
A API não publica um teto único. Defina o seu por fase do chip: número novo conversa só com quem já conhece o cliente, número maduro recebe mais volume aos poucos. Veja o guia de aquecimento.
Posso trocar o número de quem já conversou?
Evite. O contato espera falar com o mesmo número, e a troca vira ruído e denúncia. O rodízio vale para contatos novos.
Dividir em vários números evita bloqueio?
Não. Reduz a concentração de risco, mas a ZapZap é uma solução não oficial e o WhatsApp pode limitar ou bloquear qualquer número.
Quanto custa operar 5 números em rodízio?
R$75 por mês (5 x R$15), pré-pago e sem cobrança por mensagem, mais a taxa de ativação única por instância criada, que você consulta em GET /instances/cost.
Teste o rodízio com dois números
Crie a conta, conecte dois números e rode o exemplo. R$15 por número ativo ao mês, sem cobrança por mensagem. Ao verificar o telefone há crédito de boas-vindas, sujeito à campanha vigente.
