Skip to content

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

MethodPathScopePurpose
POST/v1/instancesinstances:writeCreate (optionally with Idempotency-Key)
GET/v1/instancesinstances:readList; filter externalReference, status; paginated
GET/v1/instances/{id}instances:readGet
PATCH/v1/instances/{id}instances:writeRename / replace metadata
DELETE/v1/instances/{id}instances:writeUnlink, wipe credentials, delete
POST/v1/instances/{id}/connectinstances:writeStart connecting / pairing
GET/v1/instances/{id}/statusinstances:readConnection status
GET/v1/instances/{id}/qrinstances:readCurrent QR or pairing code
POST/v1/instances/{id}/reconnectinstances:writeRestart the connection with stored credentials
POST/v1/instances/{id}/disconnectinstances:writeClose the connection, keep the link
POST/v1/instances/{id}/logoutinstances:writeUnlink the device and wipe credentials
POST/v1/instances/{id}/connect-sessionsinstances:writeCreate a hosted connect link

Status values

statusMeaning
DISCONNECTEDNot connected. See reasonCode.
CONNECTINGOpening a connection.
QR_REQUIREDWaiting for the QR to be scanned. GET /qr returns it.
PAIRING_CODE_REQUIREDWaiting for the pairing code to be entered on the phone.
CONNECTEDWhatsApp confirmed the connection. Only now can messages be sent.
RECONNECTINGConnection dropped; reconnecting automatically with backoff. Queued messages wait.
LOGGED_OUTThe link was removed (from the phone or via logout). A new QR scan is needed.
RESTRICTEDWhatsApp restricted or banned the account. It cannot be used.
ERRORAutomatic 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: status becomes DISCONNECTED with reasonCode: QR_TIMEOUT. Call connect again to retry. WhatsTIG never loops on pairing by itself.
  • When no QR is pending (still starting, already connected, or expired), GET /qr returns 409 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

ActionKeeps the link?Effect
reconnectyesRestarts the connection. Fails with 409 if the instance was never linked.
disconnectyesCloses the connection; messages stay queued until reconnected or expired.
logoutnoUnlinks the device from the WhatsApp account and wipes credentials (LOGGED_OUT).
DELETEnoLogout + delete. Queued messages fail with INSTANCE_DELETED. Other instances are untouched.

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).