Operations

Multiple WhatsApp numbers in one system: a multi-instance guide

To use several WhatsApp numbers in the same system, create one instance per number, store each instance ID next to the customer or function it belongs to, and let each instance send events to an identifiable webhook URL. That is the multi-instance model: one system, isolated connections, and an outage on one number does not take down the others. Below are the data model, the real API endpoints, a Node.js example and a monitoring routine.

Published on · 6 min read

This article is also available in: Português · Español

Why split into several numbers

There are three recurring reasons. The first is failure isolation: if one number drops or is restricted, only that one stops. The second is separating functions, such as support, sales and collections on different numbers, which also makes the conversation clearer to the customer. The third is the agency or software house model, where each end customer has their own number and history.

Splitting is not a way to dodge limits. Spreading the same cold blast across many numbers repeats the pattern that generates reports and worsens the risk; read the risk matrix. Multi-instance is for organizing and isolating, not for multiplying volume.

The data model: what your system must store

Each instance has an ID. Your system needs a table that links that ID to the owner of the number. A minimal design:

FieldWhat it is for
------
instance_idThe instance ID in the API
tenant_id or functionEnd customer or function (sales, support)
phone_numberConnected number, for display and checks
statusLast known status (connected, connecting, disconnected)
webhook_secretA secret of yours to validate webhook origin
created_at, updated_atAudit

Keep the API keys (x-api-key and x-api-secret) on the server, in environment variables or a secrets vault. Authentication belongs to the account, and the instance ID goes in the path of each call, so a single key pair operates all numbers. Details in authentication.

Creating and listing instances by API

The management API has endpoints to list, create, query and remove instances. Before creating, the cost endpoint reports the activation fee, the prorated amount and the balance needed, and creation debits the account balance. The name accepts only letters, numbers, underscore and hyphen. After creation, the instance stays pending until the number is paired with a QR code.

The typical automated onboarding flow: check cost, create the instance, store the ID, fetch the QR code, show it to the customer to scan, set the webhook and follow the status until it becomes connected. The snippet below does this in Node.js 18 or later.

Node.js: listar, criar e configurar webhook

const BASE = "https://api.zapzapapi.com/api/v1";
const headers = {
  "Content-Type": "application/json",
  "x-api-key": process.env.ZAPZAP_API_KEY,
  "x-api-secret": process.env.ZAPZAP_API_SECRET,
};

async function call(method, path, body) {
  const res = await fetch(BASE + path, {
    method,
    headers,
    body: body ? JSON.stringify(body) : undefined,
  });
  if (!res.ok) throw new Error(method + " " + path + " -> " + res.status);
  return res.json();
}

const cost = await call("GET", "/instances/cost");
console.log("total to create:", cost.total);

const created = await call("POST", "/instances", { name: "cliente-042-vendas" });
const id = created.instance.id;

await call("PUT", "/instances/" + id + "/webhook", {
  webhook_url: "https://app.example.com/hooks/whatsapp/" + id,
});

const all = await call("GET", "/instances");
console.log(all.map((i) => i.name + " " + i.status));

One webhook per instance, with the ID in the URL

Configure a URL of its own for each instance that carries the ID, for example /hooks/whatsapp/ followed by the ID. That way, when the event arrives, your server already knows which number it came from and which customer it belongs to, without guessing from the content. Validate origin with a secret of yours in the URL or a header, and answer 2xx quickly, leaving heavy processing to a queue.

Check what is arriving with the recent deliveries endpoint and the webhook errors endpoint, and test the URL with the test endpoint. It is worth reading the guide on receiving messages by webhook and the webhooks page. For automation tools, the n8n integration shows the design with one URL per flow.

Sending through the right instance

Sending uses the instance ID in the path, so choosing the outgoing number means choosing the ID. Keep an explicit routing rule in the system: by customer, by function or by queue. Avoid random picks between numbers for the same conversation, because the customer should always see the same contact.

In a support flow, the reply goes out from the same instance that received the message. In a collections flow, it goes out from the collections function's instance. Document these rules in your code so that whoever joins the team understands without asking.

cURL: enviar texto por uma instância específica

curl -X POST https://api.zapzapapi.com/api/v1/ID_DA_INSTANCIA/send/text \
  -H "Content-Type: application/json" \
  -H "x-api-key: SUA_API_KEY" \
  -H "x-api-secret: SEU_API_SECRET" \
  -d '{"number":"5511999999999","text":"Olá! Aqui é o atendimento."}'

Monitoring the health of all numbers

Run a routine every few minutes that lists the instances and queries the status of each. If any number leaves connected, record the time, alert the responsible person and, if it is a disconnection, offer a new QR code. Keep the status history to spot patterns, such as a number that drops every day at the same hour.

Also track the reply rate per number and the new conversation limit, which the limits endpoint reports. A number with falling replies is a candidate for a pause before it becomes a problem. The endpoint reference is in the API documentation.

Node.js: verificar o status de cada instância

const list = await call("GET", "/instances");

for (const inst of list) {
  const s = await call("GET", "/" + inst.id + "/instance/status");
  const status = s.instance.status;
  if (status !== "connected") {
    console.warn("instance down:", inst.name, status);
  }
}

Cost and organizational limits

At ZapZap each active number costs R$15 per month, prepaid, with no per-message charge; the current value is on the pricing page. Because the cost is per number, multi-instance cost is predictable: add up the numbers and multiply. Creation charges an activation fee and a prorated amount, which the cost endpoint shows before you create.

A practical limit is organizational: without standard names and a table linking instance to owner, the system turns into a mess with just a few numbers. Standardize names (customer, function, number) and review monthly which instances are still in use. Whoever reaches many numbers should also plan the contingency in the guide blocked number: what to do.

Common multi-instance mistakes

The most frequent mistakes are using the wrong instance ID in the path, mixing customers on the same number, forgetting to update the table when a number is swapped, leaving the webhook secret in public code and not monitoring drops. All are solved with standardized names, a single source-of-truth table and automatic alerts.

Quick summary

  • Multi-instance is one instance per number, a single system and isolated failure: one number drops and the others keep running.
  • Store in a table of your own the instance ID, the owner (customer or function), the number and the last status.
  • One account key pair operates all numbers; the instance ID goes in the path of each call.
  • Set one webhook per instance with the ID in the URL and answer 2xx quickly, processing in a queue.
  • Splitting numbers is for organizing and isolating, not for multiplying cold blast volume.

Also read

Frequently asked questions

Can I use several instances with a single API key?

Yes. Authentication belongs to the account, with x-api-key and x-api-secret, and the instance ID goes in the path of each call. One key pair operates all numbers on the account.

How do I know which number an incoming message came from?

Configure a different webhook URL per instance, with the ID in the URL. The server identifies the number by the route that received the event and looks up your table to find the customer.

How many instances can I have on one account?

We do not publish a limit here. Each active number is an instance billed monthly; check the pricing page and the dashboard for current terms.

Does spreading a blast across several numbers reduce the ban risk?

It is not a solution. Repeating the same cold pattern on several numbers spreads the problem. What lowers risk is consent, text variation, intervals and warm-up. See the risk matrix.

How do I automate creating instances for my customers?

Use the cost, creation, QR code and webhook endpoints in sequence in your onboarding, store the instance ID in your database and track the status until it connects.

Create the first instance and connect by QR code

Create the account, verify your phone and receive the welcome credit with no deposit (one per phone, subject to the current campaign). Then scale number by number, with one webhook for each.