Agências

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

Este artigo também está disponível em: English · Español

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.

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.