Nex Messages Hub Developer API

Welcome to the Nex Messages Hub API documentation. Developers can use these HTTP endpoints to query active sessions, inspect delivery statistics, and dispatch automated messages concurrently across isolated virtual sessions.

Authentication Note: All API requests require authentication. You must pass your Developer API Key in the headers as x-api-key: YOUR_KEY, as a Bearer Token (Authorization: Bearer YOUR_KEY), or as a query parameter (?apiKey=YOUR_KEY). You can generate or refresh your key directly in the sidebar of the main dashboard.
POST /api/auth/*

Create an account, log in to receive your Developer API Key, and regenerate the key whenever needed. Every API request is authenticated using one of the following methods:

Authentication Methods

Method Example Description
x-api-key header x-api-key: whub_... Preferred for server-to-server API integrations
Bearer token Authorization: Bearer whub_... Alternative header-based authentication
Query parameter ?apiKey=whub_... Useful for simple GET requests
UI user session x-user-id: username Used internally by the dashboard after login
Administrator access: Endpoints under /api/admin/* additionally require an account with the isAdmin flag set. Non-admin accounts receive 403 Access denied.
POST /api/auth/login

Authenticate with your username and password. On success you receive your user profile including the Developer API Key used to authorize all subsequent API calls.

Request Body (JSON)

Field Type Requirement Description
username string Required Your account username
password string Required Your account password

Response Example (200 OK)

{
  "success": true,
  "user": {
    "username": "client1",
    "name": "Alice Corp",
    "apiKey": "whub_8a0b48dd...",
    "isAdmin": false
  }
}
POST /api/auth/register

Create a new self-service account. A Developer API Key is generated automatically for the new account.

Request Body (JSON)

Field Type Requirement Description
username string Required Desired username (must be unique)
password string Required Desired password
name string Required Display name (e.g. Alice Corp)

Response Example (200 OK)

{
  "success": true,
  "message": "Account registered successfully!"
}

Error Responses

// 400 - Username already taken
{
  "success": false,
  "error": "Username is already taken."
}
POST /api/auth/apikey/generate

Generate (or regenerate) a fresh Developer API Key for your own account. The previous key is invalidated immediately.

Headers

Header Type Requirement Description
x-api-key string Required Your current developer API key (any valid auth method also works)

Response Example (200 OK)

{
  "success": true,
  "apiKey": "whub_1f2e3d4c5b6a..."
}
GET /api/stats

Retrieve user-level statistics (total sessions, connected sessions, total API messages sent, and total incoming messages received) along with an array of available (connected) sessions ready to dispatch messages.

Headers

Header Type Requirement Description
x-api-key string Required Your developer API key (e.g. whub_8a0b48...)

Response Example (200 OK)

{
  "success": true,
  "stats": {
    "totalSessionsCount": 1,
    "connectedSessionsCount": 1,
    "totalMessagesSent": 25,
    "totalMessagesReceived": 105
  },
  "availableSessions": [
    {
      "id": "client1_sales",
      "label": "sales",
      "phoneNumber": "201030101482",
      "messagesSent": 25,
      "messagesReceived": 105
    }
  ],
  "allSessions": [
    {
      "id": "client1_sales",
      "label": "sales",
      "state": "CONNECTED",
      "phoneNumber": "201030101482",
      "messagesSent": 25,
      "messagesReceived": 105,
      "isAvailable": true
    }
  ]
}
POST /api/send

Simpler global message sending API. Supports flexible account resolution (by Session ID, Custom Name Label, or Phone Number) and dispatches a text message. Stats are only incremented if sent successfully through this API.

Request Body (JSON)

Field Type Requirement Description
to string Required Recipient phone number with country code (e.g. 15550199). Also accepts number or phoneNumber.
message string Required Message body content. Also accepts text.
instanceName string Optional Nickname label of the sender session (e.g. sales or support). Also accepts instanceLabel.
senderPhone string Optional Phone number of the sender instance (e.g. 201030101482). Matches numeric digits.
sessionId string Optional Direct session identifier (e.g. client1_sales or just sales). Also accepts from.

Curl Example

curl -X POST http://localhost:3000/api/send \
     -H "Content-Type: application/json" \
     -H "x-api-key: YOUR_API_KEY_HERE" \
     -d '{
       "instanceName": "sales",
       "to": "15551234567",
       "message": "Hello from the developer API!"
     }'

Response Example (200 OK)

{
  "success": true,
  "message": "Message sent successfully!",
  "sessionId": "client1_sales",
  "messageId": "3EB0C61BA6553000AD279A"
}
GET /api/sessions

List all instance sessions associated with your user account, detailing connection states, pairing status, and message metrics.

Response Example (200 OK)

{
  "success": true,
  "sessions": [
    {
      "id": "client1_sales",
      "state": "CONNECTED",
      "phoneNumber": "201030101482",
      "pairingCode": null,
      "qr": null,
      "qrImageUrl": null,
      "error": null,
      "owner": "client1",
      "receiveFromIndividuals": true,
      "receiveFromGroups": false,
      "messagesSent": 25,
      "messagesReceived": 105
    }
  ]
}
POST /api/sessions

Initialize a new isolated session. If phoneNumber is supplied, it requests a pairing code instead of a QR code.

Request Body (JSON)

Field Type Requirement Description
instanceName string Optional Unique label suffix for this session (e.g. sales)
phoneNumber string Optional Phone number with country code if requesting a Pairing Code link method (e.g. 15551234567)

Response Example (200 OK)

{
  "success": true,
  "session": {
    "id": "client1_sales",
    "state": "PAIRING_CODE",
    "phoneNumber": "15551234567",
    "pairingCode": "ABCD1234",
    "error": null,
    "owner": "client1"
  }
}
GET /api/sessions/:id

Retrieve connection parameters, error alerts, QR code representations, pairing codes, and message metrics for a single specific session.

Response Example (200 OK)

{
  "success": true,
  "session": {
    "id": "client1_sales",
    "state": "CONNECTED",
    "phoneNumber": "201030101482",
    "pairingCode": null,
    "qr": null,
    "qrImageUrl": null,
    "error": null,
    "owner": "client1",
    "receiveFromIndividuals": true,
    "receiveFromGroups": false,
    "messagesSent": 25,
    "messagesReceived": 105
  }
}
GET /api/sessions/:id/qr

Returns the current WhatsApp QR code for the session as a self-contained base64-encoded PNG image. Use this endpoint to embed the QR code directly in a client website without external dependencies. The QR code rotates automatically; poll this endpoint every few seconds to get fresh codes.

How to display the QR on your website

The qrDataUrl field is a ready-to-use base64 data URL. Simply set it as the src of an tag:

Scan to link WhatsApp

Response Example (200 OK)

{
  "success": true,
  "sessionId": "client1_sales",
  "qr": "raw-qr-string-from-whatsapp",
  "qrDataUrl": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAYAAAB5...",
  "state": "QR_CODE",
  "pairingCode": null,
  "error": null
}

Response Fields

Field Type Description
qr string Raw QR code data string from WhatsApp (null if no QR pending)
qrDataUrl string Base64-encoded PNG data URL — use directly as state string Current session state (QR_CODE, PAIRING_CODE, CONNECTING, etc.)
pairingCode string Current pairing code if available, else null
error string Error message if any
POST /api/sessions/:id/pair

Generate or regenerate a link-device pairing code for an existing session. Use this when you want to link a device via phone number instead of QR code. The session must not already be connected/registered.

Request Body (JSON)

Field Type Requirement Description
phoneNumber string Required Phone number with country code (e.g. 15551234567)

Response Example (200 OK)

{
  "success": true,
  "sessionId": "client1_sales",
  "pairingCode": "ABCD-1234"
}

Error Responses

// 500 - Session already connected
{
  "success": false,
  "error": "Session 'client1_sales' is already connected. No pairing code is needed."
}

// 400 - Missing phone number
{
  "success": false,
  "error": "A phone number is required to generate a pairing code."
}
POST /api/sessions/:id/settings

Dynamically alter routing properties. Choose whether this instance processes single direct chats, group chats, or both.

Request Body (JSON)

Field Type Requirement Description
receiveFromIndividuals boolean Optional Toggle listening to single direct contacts (default: true)
receiveFromGroups boolean Optional Toggle listening inside group chats (default: true)

Response Example (200 OK)

{
  "success": true,
  "message": "Settings updated successfully.",
  "config": {
    "sessionId": "client1_sales",
    "owner": "client1",
    "receiveFromIndividuals": true,
    "receiveFromGroups": false,
    "messagesSent": 25,
    "messagesReceived": 105
  }
}
POST /api/sessions/:id/send

Direct endpoint to send a message via a specific targeted session. Updates stats for that session only.

Request Body (JSON)

Field Type Requirement Description
to string Required Recipient phone number with country code (e.g. 15551234567) or full JID
message string Required Message body content

Response Example (200 OK)

{
  "success": true,
  "message": "Message sent successfully!",
  "messageId": "3EB0C61BA6553000AD279A"
}
POST /api/sessions/:id/reconnect

Trigger a reconnection attempt for an existing session (e.g. after it drops offline). Re-initializes the socket using the stored credentials.

Response Example (200 OK)

{
  "success": true,
  "message": "Reconnection triggered.",
  "state": "CONNECTING"
}
POST /api/sessions/:id/logout

Disconnect a session, unlink the WhatsApp device, and permanently delete its stored credentials and configuration. This action cannot be undone — the device must be re-linked afterwards.

Response Example (200 OK)

{
  "success": true,
  "message": "Session 'client1_sales' logged out and deleted successfully."
}
GET /api/admin/users

List every user account with consolidated statistics and all sessions owned by each user. Administrator access required.

Headers

Header Type Requirement Description
x-api-key string Required API key of an account with isAdmin: true

Response Example (200 OK)

{
  "success": true,
  "users": [
    {
      "username": "client1",
      "name": "Alice Corp",
      "password": "password123",
      "apiKey": "whub_8a0b48dd...",
      "isAdmin": false,
      "stats": {
        "totalSessionsCount": 1,
        "connectedSessionsCount": 1,
        "totalMessagesSent": 25,
        "totalMessagesReceived": 105
      },
      "sessions": [
        {
          "id": "client1_sales",
          "label": "sales",
          "state": "CONNECTED",
          "phoneNumber": "201030101482",
          "messagesSent": 25,
          "messagesReceived": 105
        }
      ]
    }
  ]
}
POST /api/admin/users

Create a new user account on behalf of a client. Administrator access required.

Request Body (JSON)

Field Type Requirement Description
username string Required Unique username (lowercased automatically)
password string Required Account password
name string Required Display name
isAdmin boolean Optional Grant administrator privileges (default: false)

Response Example (200 OK)

{
  "success": true,
  "message": "Account for 'client3' registered successfully!"
}
POST /api/admin/users/:username/password

Update the password for a specific user account. Administrator access required.

Path Parameter

Parameter Type Requirement Description
username string Required Username of the target account

Request Body (JSON)

Field Type Requirement Description
password string Required New password for the account

Response Example (200 OK)

{
  "success": true,
  "message": "Password for user 'client1' updated successfully."
}
POST /api/admin/users/:username/apikey

Regenerate the API key for a specific user account. The previous key is invalidated immediately. Administrator access required.

Path Parameter

Parameter Type Requirement Description
username string Required Username of the target account

Response Example (200 OK)

{
  "success": true,
  "apiKey": "whub_9f8e7d6c5b4a..."
}
DELETE /api/admin/users/:username

Permanently delete a user account along with all of its WhatsApp sessions and stored credentials. Administrator access required. You cannot delete your own logged-in admin account.

Path Parameter

Parameter Type Requirement Description
username string Required Username of the account to delete

Response Example (200 OK)

{
  "success": true,
  "message": "User 'client3' and all associated sessions deleted successfully."
}
GET /api/admin/queue

Inspect the message dispatch queue, the active rate-limit/circuit-breaker configuration, and the number of messages currently pending per session. Administrator access required.

Response Example (200 OK)

{
  "success": true,
  "queue": {
    "disabled": false,
    "delayMin": 2000,
    "delayMax": 6000,
    "dailyLimit": 200,
    "maxRetries": 2,
    "pendingBySession": {
      "client1_sales": 3
    }
  }
}
INFO Rate Limiting & Anti-Ban

To protect your numbers from WhatsApp policy blocks when sending messages at scale, every message dispatched through POST /api/send and POST /api/sessions/:id/send is routed through a human-paced dispatch queue.

How it works

  • Paced delivery: messages for a given session are sent one at a time with a randomized delay between them (mimics human typing/reading) so sends never look robotic.
  • Daily send cap: each session has a daily limit (default 200 messages/day, persisted per session). Once reached, further sends are rejected with Daily send limit reached for session … until the next calendar day.
  • Circuit breaker: if a session returns repeated send failures, the queue pauses that session for a cooldown window instead of hammering WhatsApp.
  • Terminal disconnect protection: sessions WhatsApp blocks (e.g. status 405) are parked as DISCONNECTED and are not auto-reconnected, preventing infinite reconnect loops.

Configuration (environment variables)

Variable Type Default Description
SEND_QUEUE_DISABLED boolean false Set true to bypass the queue and send instantly (not recommended for bulk sends).
SEND_DELAY_MIN_MS number 2000 Minimum delay between messages on a session.
SEND_DELAY_MAX_MS number 6000 Maximum delay between messages on a session.
SEND_DAILY_LIMIT number 200 Maximum messages sent per session per day.
SEND_CIRCUIT_FAILURES number 5 Consecutive failures before the circuit opens.
SEND_CIRCUIT_COOLDOWN_MS number 600000 Cooldown (ms) while the circuit is open.
MAX_RECONNECT_ATTEMPTS number 5 Max automatic reconnect attempts before a session is parked as DISCONNECTED.
Safe sending tips: warm up new numbers gradually (start 20–50 messages/day and ramp over weeks), only message opted-in recipients, avoid identical templates, and prefer a dedicated number per campaign. These defaults reduce velocity signals but cannot fully eliminate ban risk on unofficial clients — for high-volume marketing at scale use the official WhatsApp Business Cloud API.