WhatsApp QR code not showing in the API: what to check
If the WhatsApp QR code does not show in the API, the most common cause is that the instance is already connected, in which case the API returns the status instead of a QR. The other causes are an instance suspended for low balance, a blocked instance, a QR generation already in progress and a momentary provider failure. Each one has a different response code, and that code tells you which it is. This guide follows that order and shows phone-number pairing as an alternative.
Published on · 6 min read
How does the API deliver the QR code?
The instance is created and stays in the PENDING state until it is paired. To pair, you request the QR at instance QR code and scan it with your phone under Linked devices, just like WhatsApp Web. When the instance is not connected yet, the response carries the QR in the instance.qrcode field. The QR is short-lived: if it times out, request a new one instead of insisting on the old one.
If the instance is already connected, the API does not generate a QR. It confirms the state and returns connected as true, with the instance status. This catches a lot of people: the dashboard or your code expects an image and gets a status object. Before debugging anything else, check the instance status.
Ver o status e pedir o QR code
BASE="https://api.zapzapapi.com/api/v1"
H1="x-api-key: $ZAPZAP_API_KEY"
H2="x-api-secret: $ZAPZAP_API_SECRET"
# 1) estado atual: disconnected, connecting ou connected
curl "$BASE/$INSTANCE_ID/instance/status" -H "$H1" -H "$H2"
# 2) QR code (só vem se a instância ainda não estiver conectada)
curl "$BASE/instances/$INSTANCE_ID/qrcode" -H "$H1" -H "$H2"Node.js 18+: salvar o QR como imagem
const fs = require("fs");
const BASE = "https://api.zapzapapi.com/api/v1";
const headers = {
"x-api-key": process.env.ZAPZAP_API_KEY,
"x-api-secret": process.env.ZAPZAP_API_SECRET,
};
async function main() {
const id = process.env.INSTANCE_ID;
const resp = await fetch(BASE + "/instances/" + id + "/qrcode", { headers });
const corpo = await resp.json();
if (!resp.ok) {
console.error("erro", resp.status, corpo.error, corpo.message);
return;
}
if (corpo.connected) {
console.log("já conectada:", corpo.instance && corpo.instance.status);
return;
}
const qr = corpo.instance && corpo.instance.qrcode;
if (!qr) {
console.log("sem QR ainda, tente de novo:", JSON.stringify(corpo));
return;
}
const base64 = qr.replace(/^data:image\/\w+;base64,/, "");
fs.writeFileSync("qr.png", Buffer.from(base64, "base64"));
console.log("QR salvo em qr.png, leia com o celular");
}
main();What does each response code mean?
A diagnostic table for the QR code call. The messages below are the ones the API returns in the response body.
| Response | Cause | What to do |
|---|---|---|
| 200 with connected true | The instance is already connected | Nothing to pair. Use the status to confirm the connected number |
| 402 PROXY_SUSPENDED | Instance suspended for low balance | Top up the balance and request the QR again |
| 403 INSTANCE_BLOCKED | Instance blocked | Contact support |
| 409 CONFLICT | A QR generation is already in progress for the instance | Wait a few seconds and try again. Avoid parallel clicks and calls |
| 502 PROVIDER_ERROR | Failure talking to the WhatsApp provider | Try again; if it persists, check the status and contact support |
| 503 SERVICE_UNAVAILABLE | Failure reactivating an instance that was hibernated | Try again shortly |
| 404 NOT_FOUND | Wrong ID or deleted instance | Check the ID in the instances list |
Two integration details. The ID in the path is the instance ID, not the name or the phone number. And the 409 shows up when your code calls the QR endpoint in a tight loop: the API locks generation per instance for a short period to avoid overlapping QR codes. Poll with a few seconds between calls, not in a burst.
The QR shows up, but the phone cannot scan it. Now what?
First, check that the QR rendered in full. The qrcode field is a base64 image, and if your front end strips the prefix or uses a tiny element, scanning fails. Display the image large, on a white background and with no dark-mode filter inverting the colors.
Second, the phone needs an updated WhatsApp and an internet connection. Open Settings, Linked devices, Link a device. If the phone has already hit its limit of linked devices, remove one first. Third, an expired QR: generate a new one and scan it right away. If the flow lives on a screen of yours, refresh the QR periodically until the status is connected.
If scanning still fails, use pairing by code, which does not depend on the camera.
How do you pair without a QR code, using a phone code?
The connect instance call accepts a phone field. With the phone number in international format (country code, area code and number, digits only), the API generates a pairing code instead of a QR. On the phone, go to Linked devices, Link a device, and choose to link with a phone number, typing in the code shown. Without the phone field, the call generates the QR.
The API validates the phone format and returns a validation error for numbers with symbols or no country code. The code comes back in instance.paircode in the response. Generate the code only when you are about to use it, because a new generation replaces the previous one.
Parear por código de telefone
curl -X POST "https://api.zapzapapi.com/api/v1/$INSTANCE_ID/instance/connect" \
-H "x-api-key: $ZAPZAP_API_KEY" \
-H "x-api-secret: $ZAPZAP_API_SECRET" \
-H "Content-Type: application/json" \
-d '{"phone":"5511999999999"}'
# digite no celular o código recebido em instance.paircodeWhen should you suspect a problem with the number or the account?
If scanning the QR works but the instance disconnects again right after, the problem is no longer the QR. See the guide on WhatsApp disconnecting on its own in the API. If WhatsApp refuses to pair the number, it may be restricted by WhatsApp itself; the path is in the guide on what to do about a banned number.
To create the instance and connect step by step, the quick start shows the full flow, and the WhatsApp API page lists the instance endpoints. The cost per active number is on the pricing page.
Quick checklist for pairing without a headache
[ ] I created the instance and have the right ID (not the name or the phone number)
[ ] The instance status is not connected when I request the QR
[ ] There is enough balance and the instance is not suspended or blocked
[ ] I make one QR call at a time and wait a few seconds between attempts
[ ] The QR is displayed in full, large and on a white background
[ ] WhatsApp on the phone is updated and online
[ ] If the camera fails, I use pairing by code with the phone number in international format
In interfaces for end customers, it helps to show step-by-step instructions next to the QR (open WhatsApp, Linked devices, Link a device) and a button to generate a new QR. Refresh the QR automatically until the status becomes connected, and show a clear message when the API returns 402 or 403, so the user knows the problem is not their camera.
Quick summary
- If the instance is already connected, the API returns the status, not a QR. Check the status first.
- 402 is balance, 403 is a block, 409 is a QR generation in progress, 502 and 503 are momentary provider failures.
- Poll for the QR with a few seconds between calls and render the whole image on a white background.
- With no camera or a failed scan, use phone-number pairing through instance connect.
- If pairing works and it disconnects later, the problem is something else: look at the disconnect causes.
Keep reading
Also read
Frequently asked questions
Why does the API not return the QR code?
The most common reason is that the instance is already connected: in that case the API responds with the status. It can also be low balance (402), a blocked instance (403), a generation in progress (409) or a provider failure (502/503).
Does the QR code expire?
Yes, it is short-lived. If time runs out, generate a new one with the same call and scan it right away.
Can I connect WhatsApp without scanning a QR code?
Yes. Send the phone number in international format to the connect instance endpoint and type the returned pairing code on the phone, under Linked devices.
What is the 409 error when requesting the QR?
It means a QR generation is already in progress for the instance. Wait a few seconds and try again, without parallel calls.
Do I need to pay to see the QR code?
The instance has to be active. If it was suspended for low balance, the API responds 402 until the balance is restored. Current prices are on the pricing page.
Connect a number by QR code or by code
Create your account, verify your phone and get the welcome credit, no deposit needed (one per phone, subject to the current campaign). Create the instance and do your first pairing.
