Connecting WhatsApp, QR & status
An instance is one linked WhatsApp account. Instances belong to a project and can carry your own identifier in
externalReference (unique within the project, e.g. your tenant ID).
Endpoints
| Method | Path | Scope | Purpose |
|---|---|---|---|
POST | /v1/instances | instances:write | Create (optionally with Idempotency-Key) |
GET | /v1/instances | instances:read | List; filter externalReference, status; paginated |
GET | /v1/instances/{id} | instances:read | Get |
PATCH | /v1/instances/{id} | instances:write | Rename / replace metadata |
DELETE | /v1/instances/{id} | instances:write | Unlink, wipe credentials, delete |
POST | /v1/instances/{id}/connect | instances:write | Start connecting / pairing |
GET | /v1/instances/{id}/status | instances:read | Connection status |
GET | /v1/instances/{id}/qr | instances:read | Current QR or pairing code |
POST | /v1/instances/{id}/reconnect | instances:write | Restart the connection with stored credentials |
POST | /v1/instances/{id}/disconnect | instances:write | Close the connection, keep the link |
POST | /v1/instances/{id}/logout | instances:write | Unlink the device and wipe credentials |
POST | /v1/instances/{id}/connect-sessions | instances:write | Create a hosted connect link |
Status values
status | Meaning |
|---|---|
DISCONNECTED | Not connected. See reasonCode. |
CONNECTING | Opening a connection. |
QR_REQUIRED | Waiting for the QR to be scanned. GET /qr returns it. |
PAIRING_CODE_REQUIRED | Waiting for the pairing code to be entered on the phone. |
CONNECTED | WhatsApp confirmed the connection. Only now can messages be sent. |
RECONNECTING | Connection dropped; reconnecting automatically with backoff. Queued messages wait. |
LOGGED_OUT | The link was removed (from the phone or via logout). A new QR scan is needed. |
RESTRICTED | WhatsApp restricted or banned the account. It cannot be used. |
ERROR | Automatic reconnection gave up. Call reconnect to try again. |
desiredState (CONNECTED / DISCONNECTED) is what you asked for; status is what the session worker last confirmed.
WhatsTIG never reports CONNECTED before WhatsApp's servers confirm the connection.
reasonCode explains non-connected states: NEVER_CONNECTED, QR_TIMEOUT, LOGGED_OUT_FROM_PHONE,
CONNECTION_REPLACED, ACCOUNT_RESTRICTED, BAD_SESSION, NETWORK_ERROR, RECONNECT_EXHAUSTED,
MANUAL_DISCONNECT, MANUAL_LOGOUT, PROVIDER_ERROR.
connect scan QR / enter code
DISCONNECTED ──────► CONNECTING ──► QR_REQUIRED ─────────────────► CONNECTED
▲ │ not scanned in ~3 min │ network drop
│ ▼ ▼
└──── QR_TIMEOUT ◄──────────── DISCONNECTED RECONNECTING ──► CONNECTED
│ gave up
LOGGED_OUT ◄── removed on phone / logout ▼
RESTRICTED ◄── banned by WhatsApp ERROR
Connecting
POST /v1/instances/wa_123/connect
Content-Type: application/json
{ "method": "qr" }
Response 202 with the current status. Pairing is asynchronous: the session worker opens a connection and publishes a
QR within a second or two. Then:
GET /v1/instances/wa_123/qr
{
"instanceId": "wa_123",
"method": "qr",
"qr": "2@AbC...",
"qrDataUrl": "data:image/png;base64,iVBOR...",
"pairingCode": null,
"expiresAt": "2026-10-09T10:15:20.000Z"
}
- QR codes rotate (about every 20 seconds). Fetch again after
expiresAt. - QR payloads live only in memory (encrypted, expiring); they are never stored permanently and are only served to authenticated callers.
- If the QR is not scanned within about 3 minutes, pairing stops:
statusbecomesDISCONNECTEDwithreasonCode: QR_TIMEOUT. Callconnectagain to retry. WhatsTIG never loops on pairing by itself. - When no QR is pending (still starting, already connected, or expired),
GET /qrreturns409 QR_NOT_AVAILABLE.
Pairing code instead of QR (useful when the phone and the screen are the same device):
{ "method": "pairing_code", "phoneNumber": "+92 300 1234567" }
GET /qr then returns pairingCode (8 characters) to enter in WhatsApp → Linked devices → Link with phone number
instead.
Calling connect on a connected instance is a no-op. A RESTRICTED instance cannot be connected
(409 INSTANCE_STATE_CONFLICT).
Session persistence
Once linked, credentials are stored encrypted in PostgreSQL. Restarts and deployments of WhatsTIG restore the
connection automatically (no new QR). A QR is needed again only after LOGGED_OUT (device removed on the phone,
logout, or invalid session).
Reconnect, disconnect, logout, delete
| Action | Keeps the link? | Effect |
|---|---|---|
reconnect | yes | Restarts the connection. Fails with 409 if the instance was never linked. |
disconnect | yes | Closes the connection; messages stay queued until reconnected or expired. |
logout | no | Unlinks the device from the WhatsApp account and wipes credentials (LOGGED_OUT). |
DELETE | no | Logout + delete. Queued messages fail with INSTANCE_DELETED. Other instances are untouched. |
Hosted connect links
If you do not want to render QR codes in your product, create a short-lived link to a WhatsTIG-hosted page that shows only this instance's QR and status:
POST /v1/instances/wa_123/connect-sessions
Content-Type: application/json
{ "ttlSeconds": 900, "returnUrl": "https://app.example.com/settings/whatsapp" }
{ "id": "cs_...", "instanceId": "wa_123", "url": "https://app.whatstig.com/connect/AbCd...", "expiresAt": "..." }
Send the URL to the account owner (for example a school administrator). They need no WhatsTIG account. The link:
expires after ttlSeconds (60–1800), only shows this one instance, stops serving QR codes once the instance is
connected, and must be treated as a secret (it is the only credential).
Looking up an instance by your own ID
GET /v1/instances?externalReference=tenant-101
Returns at most one instance (references are unique per project). Creating a second instance with the same
externalReference fails with 409 EXTERNAL_REFERENCE_TAKEN; use an Idempotency-Key to make creation retry-safe.
Events
instance.connected, instance.disconnected, instance.qr_required, instance.logged_out and instance.error
(for ERROR and RESTRICTED) are emitted when status changes. See Webhooks.
Limits
The number of instances per organization depends on the plan (403 INSTANCE_LIMIT_REACHED).