How QR code pairing works
When you create a session on the WhatsApp API, it starts disconnected, waiting for a device. The QR code carries the invitation for the phone to link that session as a device, the same way it happens when you open WhatsApp Web. After scanning, the number keeps working on the phone and the session gets access to the conversations.
On D-API, the cycle has four moments:
- Create the session with a
sessionIdof your choice. - Fetch the QR code and show it to whoever will connect.
- Track the status change until
connected. - Handle disconnections over time, reconnecting or asking for a new pairing.
Generating the QR code through the API
The route is GET /api/v1/sessions/{sessionId}/qr. With ?image=1, the response is a PNG ready to display or save:
curl "https://api.d-api.cloud/api/v1/sessions/clinic-north/qr?image=1" \
-H "Authorization: YOUR_API_KEY" \
--output qr.pngWithout the parameter, the response is JSON, useful when your frontend will draw the image:
{
"sessionId": "clinic-north",
"status": "connecting",
"qrCode": "2@ABC123DEF456...",
"qrCodeImage": "data:image/png;base64,iVBOR...",
"qrCodeUpdatedAt": "2024-01-15T10:30:00.000Z"
}The qrCodeImage field already comes as a data URL and can go straight into an image's src attribute. qrCodeUpdatedAt helps you tell whether the QR code on screen is still the current one.
QR code expiration and renewal
The QR code expires within seconds and is renewed automatically while the session is connecting. If your screen always shows the first QR code generated, scanning will fail. There are two ways to keep the image up to date:
- Fetch at a short interval while the status is
connecting, and stop as soon as it changes. It's the simplest path for a first version. - React to webhooks. The
connection.qrcodeevent tells you there's a new QR code, andconnection.statustells you when the number connected. With that, your backend pushes the update to the screen without polling.
One security detail: the call that fetches the QR code must come from your backend. The API key gives access to every session on the account and must not reach your customer's browser.
Pairing with a code, no camera needed
Scanning isn't always possible. If the person is viewing your screen on the phone itself, they can't point the camera at it. That's what the pairing code is for: you create the session with connectionMode set to pair and provide the number in pairPhone.
curl -X POST https://api.d-api.cloud/api/v1/sessions \
-H "Authorization: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "sessionId": "clinic-north", "connectionMode": "pair", "pairPhone": "14155550123" }'
curl https://api.d-api.cloud/api/v1/sessions/clinic-north/pair-code \
-H "Authorization: YOUR_API_KEY"The response includes the pairCode, in the format ABCD-1234, which the person types on the phone under the option to link with a phone number. When the code changes, the connection.paircode event arrives on the webhook. In the Node SDK, the equivalents are sessions.getQRCode and sessions.getPairCode; see the Node.js SDK.
Migrating a WhatsApp Web session that's already connected
When the number is already open in someone's WhatsApp Web, for example a support agent who uses the browser every day, you can move that session to D-API without a new QR code. The path uses the Integration Assistant, a Chrome extension:
- Your system generates a migration code with
POST /api/v1/sessions/{sessionId}/migration-otp. The code has 8 characters, is valid for 30 minutes and can only be used once. - The person installs the Integration Assistant in the Chrome browser where WhatsApp Web is open.
- They enter the code in the extension, which transfers the session to D-API.
- WhatsApp Web in that browser is disconnected and the number starts operating through the API.
This code isn't a verification code for end users; it exists only for this migration. It's a useful feature for anyone bringing customers over from another provider or from a manual operation, without asking each one to repeat the pairing.
Reconnection and when to ask for a new QR code
Once connected, the number can drop for different reasons, and each one calls for a different reaction from your system. The connection.status webhook carries the state in data.status:
| Status | What it means | What to do |
|---|---|---|
connected | Session active | Allow sends for that number |
disconnected | Connection lost, pairing kept | Wait for auto-reconnect or force it with GET /sessions/{id}/connect |
logged_out | Number unlinked | Warn the customer and show a new QR code |
What sets a good integration apart is the customer learning about the drop from your screen, not from messages that stopped arriving. If you'll connect numbers for many customers, see how to organize that in multiple numbers on the same API, and the full flow, from sign-up to webhook, in how the WhatsApp API works. QR code connection is the foundation of the D-API unofficial WhatsApp API.
