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 the QR code to your webhook URL. Show it to the owner of the phone, they scan it from WhatsApp, and the number is ready to send messages.
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 arrives later, at your webhook URL.
Call the connect API
Send the phone number and your
webhook_url. The response gives you awhatsapp_client_id. Save it.Receive the QR code
Your webhook receives
status=qr_generatedwith the QR image inqr_image. Show that image to the person who owns the phone. 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. After that, or if WhatsApp asks to reload the code, you receivenot_connected; call the API again to get a new code.Scan it from WhatsApp
On the phone, open WhatsApp → Linked devices → Link a device and scan the code.
Get the result
Your webhook receives
status=connectedwhen 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",
"whatsapp_number": "919876543210",
"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",
"whatsapp_number": "919876543210",
"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",
whatsapp_number: "919876543210",
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',
'whatsapp_number' => '919876543210',
'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.
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_numberstringrequiredThe WhatsApp number to connect, with country code, such as
919876543210. It's saved exactly as you send it (up to 20 characters), so send digits only, without+, spaces or dashes. Longer values fail with HTTP500. The same number written differently counts as a different number.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.
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,
"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. |
"status": 1 means the request was created, not that the number is connected. If you call the API again for a number that was added before but isn't connected, you get the same whatsapp_client_id back and a new connection attempt starts.
Errors#
| Message | HTTP | How to fix it |
|---|---|---|
whatsapp_number cant be null | 200 | Send whatsapp_number. This is checked first, so it also appears when the JSON body is invalid. |
Auth Error | 200 | Send both client_id and api_key. |
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 | This number is already connected in this workspace. Nothing to do. If you're already at your plan's number limit, you get WhatsApp Account Limit Reached instead, even for a number that's already connected. |
A request that isn't a POST returns an empty object {} with HTTP 200.
If the same account owner already added this number in a different workspace, the request can fail with HTTP 500. Connect the number from WhatsApp settings in the workspace you want, or contact support.
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 URL):
status=qr_generated&whatsapp_client_id=678&qr_image=...
Number connected (can be sent more than once for the same connection):
status=connected&whatsapp_client_id=678
Connection failed, for example because the QR code wasn't scanned in time:
status=not_connected&whatsapp_client_id=678
| Field | Values |
|---|---|
status | qr_generated, connected or not_connected |
whatsapp_client_id | The whatsapp_client_id returned by the API. |
qr_image | Only with qr_generated. Either a data: URL containing the image as base64, or an https URL of the image. Handle both. The https URL stays the same for every refresh of the same number, while the image behind it changes. Add a cache-busting query when you display it (for example ?t=<timestamp>), or the browser may keep showing an expired code. |
Your URL must be publicly reachable and should answer within a few seconds. Wbiztool waits for your reply with no timeout. If your server can't be reached, the connection attempt can stop before the number is saved as connected. 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:
connectedcan arrive twice. Make your handler safe to run more than once. - 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. - No QR 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.
