WhatsApp accounts API
Connect a WhatsApp number (API)
Start connecting a WhatsApp number to your workspace from your own app. Wbiztool opens a new WhatsApp session and sends a QR code, or with login_method=phone an 8-character code, to your webhook URL. Show it to the owner of the phone, they scan the QR code or type the code in WhatsApp, and the number is ready to send messages. With a QR code you don't need to know the number in advance: Wbiztool reads it from WhatsApp after the scan and sends it to your webhook.
Linking your own number by hand? Follow Connect your WhatsApp number.
https://wbiztool.com/api/v1/whatsapp/connect/Body: JSON or form fields
POST /api/v1/whatsapp-client/create/ is an identical alias: it runs the same code and returns the same responses. Both paths keep working.
How connecting works#
The API call only starts the connection. The QR code or phone code arrives later, at your webhook URL.
Call the connect API
Send your
webhook_url, pluswhatsapp_numberwithlogin_method=phone. To reconnect a number you added before, also send itswhatsapp_client_id. The response gives you awhatsapp_client_id. Save it.Receive the QR code or phone code
With the default
login_method=qr, your webhook receivesstatus=qr_generatedwith the QR image inqr_image. The QR code is sent again every several seconds while Wbiztool waits for a scan, so always show the latest one. The person has about two minutes to scan.With
login_method=phone, your webhook receivesstatus=pairing_codewith an 8-character code inpairing_code, such asK5EWPGY5. It's sent once and is valid for about three minutes.Show the image or code to the person who owns the phone. If it isn't used in time, or WhatsApp asks to reload the code, you receive
not_connected; call the API again to get a new one.Link the phone
On the phone, open WhatsApp → Linked devices → Link a device. Scan the QR code, or tap Link with phone number instead and type the 8-character code.
Get the result
Your webhook receives
status=connectedwith the linked number inwhatsapp_numberwhen the number is linked, orstatus=not_connectedif the code wasn't scanned in time or the connection failed. Theconnectedevent can arrive a few seconds before Connection status returnsConnected. Reply to the webhook first, then poll Connection status every few seconds for up to a minute. Don't check it once from inside your webhook handler.
Quick example#
curl -X POST https://wbiztool.com/api/v1/whatsapp/connect/ \
-H "Content-Type: application/json" \
-d '{
"client_id": 12345,
"api_key": "YOUR_API_KEY",
"webhook_url": "https://example.com/wbiztool/connect-events?token=LONG_RANDOM_SECRET"
}'import requests
response = requests.post(
"https://wbiztool.com/api/v1/whatsapp/connect/",
json={
"client_id": 12345,
"api_key": "YOUR_API_KEY",
"webhook_url": "https://example.com/wbiztool/connect-events?token=LONG_RANDOM_SECRET",
},
timeout=30,
)
result = response.json() # read the body even when the HTTP code is 400 or 403
if result.get("status") == 1:
print("Waiting for QR code, whatsapp_client_id", result["whatsapp_client_id"])
else:
print("Failed:", result.get("message"))// Node.js 18+ (built-in fetch). Save as .mjs to use top-level await.
const response = await fetch("https://wbiztool.com/api/v1/whatsapp/connect/", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
client_id: 12345,
api_key: "YOUR_API_KEY",
webhook_url: "https://example.com/wbiztool/connect-events?token=LONG_RANDOM_SECRET",
}),
});
const result = await response.json(); // read the body even when the HTTP code is 400 or 403
if (result.status === 1) {
console.log("Waiting for QR code, whatsapp_client_id", result.whatsapp_client_id);
} else {
console.error("Failed:", result.message);
}<?php
$payload = [
'client_id' => 12345,
'api_key' => 'YOUR_API_KEY',
'webhook_url' => 'https://example.com/wbiztool/connect-events?token=LONG_RANDOM_SECRET',
];
$ch = curl_init('https://wbiztool.com/api/v1/whatsapp/connect/');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode($payload),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
if (($result['status'] ?? 0) === 1) {
echo 'Waiting for QR code, whatsapp_client_id ' . $result['whatsapp_client_id'];
} else {
echo 'Failed: ' . ($result['message'] ?? 'no response');
}Replace 12345 and YOUR_API_KEY with your own values. See Authentication for where to find them. To get a phone code instead, add "login_method": "phone" and "whatsapp_number": "919876543210".
Request parameters#
client_idintegerrequiredYour API Client ID from Settings → API keys.
api_keystringrequiredYour API key from the same page. The number is added to the workspace this key was created in.
whatsapp_numberstringOnly with login_method=phoneWith
login_method=phone, the full international number to send the code to, because WhatsApp sends it to exactly that number: country code first, no leading0, such as919876543210.+, spaces and dashes are removed for you.With
login_method=qrit's ignored, and you can leave it out. Wbiztool saves the number WhatsApp reports after the scan and sends it in theconnectedwebhook.login_methodstringoptionalqr(default) to receive a QR code, orphoneto receive an 8-character code that the owner types in WhatsApp under Link with phone number instead. Useful when the phone can't scan a QR code, for example when it's the only device.whatsapp_client_idintegeroptionalTo reconnect a number that's in your workspace but not connected, send its
whatsapp_client_id. The same ID is kept, so your other API calls keep working. Leave it out to add a new number.The row takes whichever number is linked. If a different phone scans the QR code, or you send a different
whatsapp_numberwithlogin_method=phone, thatwhatsapp_client_idsends from the new number from then on, including the messages already queued for it.webhook_urlstringRequired to receive the QR codeYour
httporhttpsURL that receives the QR code and connection updates, up to 250 characters (longer URLs fail with HTTP500). The API accepts a request without it, but then nothing is sent to you and you have no way to get the QR code through the API. See Webhook events.
Using the official clients#
The Python client calls /api/v1/whatsapp-client/create/ for you. It asks for whatsapp_number; with a QR code the value is ignored.
from wbiztool_client import WbizToolClient
client = WbizToolClient(api_key="YOUR_API_KEY", client_id=12345)
result = client.create_whatsapp_client(
whatsapp_number="919876543210",
webhook_url="https://example.com/wbiztool/connect-events?token=LONG_RANDOM_SECRET",
)
print(result)The Python client raises requests.exceptions.HTTPError when the API returns HTTP 400 or 403, so wrap the call in try/except.
Response#
When the connection request is created, the API returns HTTP 200:
{
"message": "Whatsapp Client Created",
"whatsapp_client_id": 678,
"login_method": "qr",
"status": 1
}
| Field | Type | Description |
|---|---|---|
status | integer | 1 if the connection request was created, 0 if it failed. |
message | string | Whatsapp Client Created on success, otherwise the error. |
whatsapp_client_id | integer | ID of the WhatsApp number. Use it as whatsapp_client in other API calls. Only present on success. |
login_method | string | qr or phone, as used for this attempt. Only present on success. |
"status": 1 means the request was created, not that the number is connected. Calling the API again doesn't pile up numbers:
- With a QR code and no
whatsapp_client_id, you get the samewhatsapp_client_idback until one of its QR codes is scanned. - With
login_method=phone, a number that was added before but isn't connected gets its existingwhatsapp_client_idback. - With
whatsapp_client_id, that number is reconnected.
Until its first QR code is scanned, the number has no phone number yet: List connected numbers and Connection status return an empty number for it.
Errors#
| Message | HTTP | How to fix it |
|---|---|---|
login_method must be 'qr' or 'phone' | 400 | Send qr, phone or leave it out. |
For login_method phone, whatsapp_number must be the full international number with country code and no leading 0, e.g. 919876543210 | 400 | Send the number with its country code, such as 919876543210, not 09876543210 or 9876543210. |
Auth Error | 200 | Send both client_id and api_key. Also returned when the JSON body is invalid. |
Invalid Client Id | 403 | Send client_id as a whole number, such as 12345. |
Auth Error: invalid api key | 400 | Check the key exists, hasn't been deleted and belongs to this client_id. |
Higher Subscription Required | 200 | Your plan doesn't include this API. Upgrade your plan. |
WhatsApp Account Limit Reached. Upgrade your account to get more whatsapp limit | 200 | You already have as many connected numbers as your plan allows. Disconnect one or upgrade. |
Already Connected With Given Number | 200 | With login_method=phone, this number is already connected in this workspace. With whatsapp_client_id, that number is already connected. Nothing to do. If you're already at your plan's number limit, you get WhatsApp Account Limit Reached instead. |
Invalid WhatsApp client | 400 | The whatsapp_client_id doesn't exist, was deleted or belongs to another workspace. Leave it out to add a new number. |
A request that isn't a POST returns an empty object {} with HTTP 200.
Webhook events#
Wbiztool sends a POST to your webhook_url at each step. The body is form-encoded (application/x-www-form-urlencoded), not JSON.
QR code ready (sent again every several seconds while waiting for a scan, often with the same image):
status=qr_generated&whatsapp_client_id=678&qr_image=...
Phone code ready (with login_method=phone, sent once):
status=pairing_code&whatsapp_client_id=678&pairing_code=K5EWPGY5
Number connected, with the number that's logged in, as WhatsApp reports it:
status=connected&whatsapp_client_id=678&whatsapp_number=919876543210
Connection failed, for example because the QR code wasn't scanned or the phone code wasn't entered in time:
status=not_connected&whatsapp_client_id=678
| Field | Values |
|---|---|
status | qr_generated, pairing_code, connected or not_connected |
whatsapp_client_id | The whatsapp_client_id returned by the API. |
whatsapp_number | Only with connected. The linked number with its country code, such as 919876543210. Use it to learn which number was scanned. Empty in the rare case WhatsApp didn't report it. |
pairing_code | Only with pairing_code. The 8-character code to type in WhatsApp. Show it as-is; spaces or a dash between the halves are fine. |
qr_image | Only with qr_generated. A data: URL containing the PNG image as base64 (data:image/png;base64,…). Use it as an image source as it is; every event carries the latest code. Until October 2026 it could also be an https link to the image; those links no longer work, so if your code handles them, nothing else changes. |
Your URL must be publicly reachable and should answer within a few seconds. Wbiztool waits up to 10 seconds for your reply; if your server is slow or can't be reached, that event is lost but the connection attempt carries on. Any HTTP status code is accepted. Failed deliveries aren't retried, and nothing is sent if the number disconnects later on. To follow a number after it's connected, poll Connection status.
Polling instead of webhooks#
If your server can't receive webhooks, you still need the webhook to get the QR code, but you don't have to rely on it for the result. After the QR code is scanned, call Connection status with the whatsapp_client_id every few seconds until it returns Connected. List accounts shows the same thing for all your numbers.
Tips#
- Handle duplicate events: make your handler safe to run more than once, in case an event is delivered twice.
- Show the newest QR code: replace the image each time a new
qr_generatedevent arrives, adding a cache-busting query to anhttpsURL. Older codes stop working. - Scan within about two minutes: after that you get
not_connected. Call the API again for a new code. - Check the number after a QR scan: the
connectedevent'swhatsapp_numberis the number that was really linked, which may differ from the one you expected. - Enter the phone code within about three minutes: each attempt gives one code. If it expires you get
not_connected; call the API again. - No QR code or phone code after 10 minutes? The request expired. Call the API again.
- Connecting from the dashboard is simpler when you're linking your own number. Use WhatsApp settings and scan the code there.
