To send and receive messages, a WhatsApp number has to be linked to WaConnect — the same way WhatsApp Web is linked: someone opens WhatsApp on the phone and scans a QR code.
With the API, your users can do this inside your own app. There are three ways to show them the QR code, from easiest to most custom.
Inbox or API numbers#
Every number is used one of two ways, never both:
| Inbox number | API number | |
|---|---|---|
| Used from | The WaConnect inbox, by your team | Your own software, through the API |
| Messages | Saved and shown in the inbox | Not saved in WaConnect: sent to your webhooks, and your software keeps its own copy |
| Photos and documents | Kept | Kept for about 24 hours, so you can download them |
| API keys and webhooks | Can't use it | Use it |
| Credits | Charged per message | Charged per message, the same |
Numbers created with POST /v1/numbers are API numbers. In the dashboard you choose when you connect a number, and you can switch later on the number's page. Switching starts fresh: an inbox number's saved chats are deleted when it becomes an API number.
1. Create the number#
POST /v1/numbers creates a number, starts pairing and returns a connectUrl — a private page that shows the live QR code.
curl https://api.waconnect.ai/v1/numbers \
-H "Authorization: Bearer wc_live_your_key" \
-H "Content-Type: application/json" \
-d '{"label":"Front desk"}'{
"id": "01a0f44d-c969-75b1-955d-3841d817f711",
"label": "Front desk",
"phoneNumber": null,
"status": "PENDING",
"mode": "API",
"connectedAt": null,
"lastDisconnectedAt": null,
"createdAt": "2026-10-01T10:00:00.000Z",
"connectUrl": "https://waconnect.ai/connect/9Ewps…Jr18"
}The link is private to that number: show it only to the user who is connecting it.
2. Show the QR code#
Option A — In your own pop-up (recommended)#
Put the connectUrl in an iframe inside your modal. Our page shows only the QR code, the instructions and the result — styled to fit any app — and tells your page when the number connects.
<div id="whatsapp-modal" class="modal">
<iframe
src="CONNECT_URL_FROM_YOUR_SERVER"
title="Connect WhatsApp"
style="width: 400px; height: 600px; border: 0; border-radius: 16px"
></iframe>
</div>
<script>
window.addEventListener("message", (event) => {
if (event.origin !== "https://waconnect.ai") return // only trust WaConnect
if (event.data.type === "waconnect.connected") {
console.log("Connected:", event.data.phoneNumber)
closeModal()
}
if (event.data.type === "waconnect.link_invalid") {
// The link was used or replaced: ask your server for a new one.
}
})
</script>Add ?theme=dark to the URL for a dark widget. See the widget reference for every event.
Option B — In a new tab or window#
Open the connectUrl with window.open(...). The same events are sent to your page (via window.opener), so you can close the window when the number connects.
Option C — Draw the QR yourself (white-label)#
Poll GET /v1/numbers/:id/qr every few seconds and render the qr string with any QR library. WaConnect never appears on screen.
{ "status": "CONNECTING", "qr": "2@AbC…", "generatedAt": "2026-10-01T10:00:05.000Z", "expired": false }qr: null, expired: false— a code is on its way, try again in a moment.expired: true— the code timed out; callPOST /v1/numbers/:id/connect-linkto start a new one.status: "CONNECTED"— done.
3. Know when it's connected#
Any of these tells you:
- the widget's
waconnect.connectedbrowser event (options A and B); - the
number.connectedwebhook on your server — the most reliable; GET /v1/numbers/:idreturning"status": "CONNECTED".
QR codes expire#
WhatsApp keeps a pairing session open for about a minute. If nobody scans in time, the widget shows Get a new code; in your own UI, call POST /v1/numbers/:id/connect-link, which starts a fresh code and returns a new link (the old one stops working).
Link lifetime#
A connect link works until it's used (the number connects), replaced by a newer link, or the number is removed. It doesn't expire by time.
Connecting a number needs a positive credit balance; at $0, POST /v1/numbers answers 402 CREDITS_REQUIRED.