Connecting a Device
Create a WUTS device, pair it by QR code or pair code, check its state, reconnect after a restart, and disconnect.
A device is a WhatsApp session managed by WUTS on behalf of your tenant. Before you can send or receive messages, you create a device record and pair it with a real WhatsApp account on a phone. This guide walks the full lifecycle.
Every request below is authenticated with your tenant token (Authorization: Bearer <token>).
See Authentication for how to obtain it.
Device lifecycle at a glance
- Create a logical device —
POST /devices. - Pair it with WhatsApp — either scan a QR (
GET /qr) or type a pair code (POST /paircode). - Verify the session is live —
GET /status. - Reconnect later without re-pairing —
POST /connect. - Disconnect when you are done —
POST /disconnect.
1. Create a device
POST /devices registers a new device for your tenant. The only field is a human-readable
name. Creating a device only registers it — the session is not active until you complete
pairing, so a fresh device is returned with connected: false.
curl -X POST "https://api.wuts.com.br/devices" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"name":"WhatsApp Loja 01"}'{
"success": true,
"device": {
"id": "4d0add2c-fdd1-4ee0-9d33-6a8898ce30e3",
"name": "WhatsApp Loja 01",
"connected": false,
"created_at": "2025-03-02T14:15:17Z"
}
}Keep the returned id. The pairing, status, connect, and QR-status endpoints accept it as a
device_id so you can target a specific device when your tenant has more than one.
2a. Pair by scanning a QR code
GET /qr generates a QR for the device, starts connecting in the background, and caches the
payload for polling. It returns both a raw qr_code string and a base64 PNG image.
curl -X GET "https://api.wuts.com.br/qr" \
-H "Authorization: Bearer <token>"{
"success": true,
"data": {
"qr_code": "AAEBEiFo...",
"image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..."
}
}Render image and have the user scan it from their phone:
WhatsApp → Settings → Linked devices → Link a device.
QR codes expire quickly (around 30 seconds). Render and scan immediately. If GET /qr returns
a 504/timeout, simply request a fresh one and retry.
Poll the QR status
While the user scans, poll GET /qr/status to learn whether the cached QR is still valid. Pass
the device_id of the device you are pairing.
curl -X GET "https://api.wuts.com.br/qr/status?device_id=4d0add2c-fdd1-4ee0-9d33-6a8898ce30e3" \
-H "Authorization: Bearer <token>"{
"success": true,
"data": {
"exists": true,
"generated_at": "2025-03-02T13:55:12Z"
}
}When the QR has expired (or was never generated for that device_id), exists is false.
After a successful scan, confirm pairing with GET /status.
If the device is already paired and connected, GET /qr returns 400 already connected —
disconnect first to generate a new QR.
2b. Pair with a pair code
If scanning is impractical, use POST /paircode. WUTS asks WhatsApp for a code the user types
on their phone under Settings → Linked devices → Link a device → Link with phone number
instead. Send the WhatsApp number in international format (digits only; +, spaces, and
punctuation are stripped automatically).
curl -X POST "https://api.wuts.com.br/paircode" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"phone":"5511999999999","device_id":"4d0add2c-fdd1-4ee0-9d33-6a8898ce30e3"}'{
"success": true,
"data": {
"code": "ABCD-1234",
"phone": "5511999999999",
"expires_in": 300,
"cached": true,
"instructions": "Digite este código no WhatsApp: ..."
}
}The code is valid for expires_in seconds (5 minutes), and instructions carries a
ready-to-show hint. A repeated call returns the same code with cached: true while it is still
alive. To force a new code, send the X-WUTS-Refresh-Paircode: true header or add
?refresh=true.
| Error | Meaning |
|---|---|
400 phone number is required | The phone field was missing. |
400 invalid phone number format | Phone must be 10–15 digits, country code included. |
400 already connected | Device is already paired and live — disconnect first. |
device already paired | Stored credentials already exist; use POST /connect instead. |
QR vs pair code
Both methods produce the same paired session — pick whichever fits your UX:
- QR code — fastest when the user has the screen and phone side by side. Short ~30s window, so render it on demand.
- Pair code — better for remote setups, phone screenshots, or when the customer cannot scan. Longer 5-minute window and copy-pasteable. Show the QR first, the pair code as fallback.
3. Check the connection state
GET /status reports the live state of the device. Pass device_id to target a specific one.
curl -X GET "https://api.wuts.com.br/status?device_id=4d0add2c-fdd1-4ee0-9d33-6a8898ce30e3" \
-H "Authorization: Bearer <token>"{
"success": true,
"data": {
"connected": true,
"status": "connected",
"device_id": "4d0add2c-fdd1-4ee0-9d33-6a8898ce30e3",
"jid": "5511999999999@s.whatsapp.net",
"phone_number": "5511999999999",
"is_logged_in": true
}
}status is one of: connected (online and logged in), connecting (socket up, login still
settling), or disconnected. Treat connected: true as the signal that the device is ready
to send and receive messages.
4. Reconnect after a restart
After a gateway or host restart an in-memory session can drop while the stored WhatsApp
credentials remain valid. POST /connect reloads those credentials and reconnects without a
new QR scan — the recommended self-heal primitive (GET /qr would refuse an already-paired
device).
curl -X POST "https://api.wuts.com.br/connect?device_id=4d0add2c-fdd1-4ee0-9d33-6a8898ce30e3" \
-H "Authorization: Bearer <token>"| Response | Meaning | What to do |
|---|---|---|
200 status: connected, needs_qr: false | Reconnected (or already live). | Nothing — device is ready. |
200 status: logged_out, needs_qr: true | Credentials are gone. | Re-pair via GET /qr or POST /paircode. |
503 | Transient failure. | Retry with backoff. |
404 | Device not found or not owned by this tenant. | Verify the device_id. |
5. Disconnect
POST /disconnect tears down the live session, removes the in-memory client, and fires the
device.disconnected webhook. No body is required.
curl -X POST "https://api.wuts.com.br/disconnect" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json"{
"success": true,
"data": {
"message": "device disconnected successfully",
"device_id": "4d0add2c-fdd1-4ee0-9d33-6a8898ce30e3"
}
}A 404 device not found or not connected means the session is already down. After
disconnecting you can pair again with a fresh GET /qr or POST /paircode, or — if the stored
credentials survive — bring it back with POST /connect. The device record itself is not
deleted; it stays listed under GET /devices and can be reconnected later.
Multiple devices per tenant
A single tenant can run several devices at once (for example, one WhatsApp number per store).
Create each with POST /devices, then pass its device_id to the pairing, status, connect,
and disconnect calls to act on exactly the device you mean. GET /devices lists every device
your tenant owns with each one's connected flag and whatsapp_jid.
Devices are isolated per tenant. A token can only operate on devices owned by its own tenant;
targeting another tenant's device_id is rejected. See Conventions for shared
request and response rules.
Next steps
- Receiving messages — wire up inbound events.
- Webhooks — subscribe to
device.disconnectedand message events. - Errors and Rate limits — handle failures gracefully.