Developer
NextMSG API Docs
Use your tenant token with the instance endpoints below to list instances, inspect status, and send WhatsApp messages from connected devices.
List Instances
GET
/v1/instances
token: wa_live_your_token
Check Instance Status
GET
/v1/instances/:instanceId/status
token: wa_live_your_token
Send Text Message
POST
/{INSTANCE_ID}/messages/chat
Content-Type: application/x-www-form-urlencoded token=wa_live_your_token&to=254712345678&body=Hello from client system
Python
import requests
base_url = "http://localhost:3000"
instance_id = "wacc_your_instance_id"
url = f"{base_url}/{instance_id}/messages/chat"
response = requests.post(
url,
data={
"token": "wa_live_your_token",
"to": "254712345678",
"body": "Hello from Python"
},
timeout=30,
)
print(response.status_code)
print(response.text)
JavaScript / TypeScript (fetch)
const baseUrl = "http://localhost:3000";
const instanceId = "wacc_your_instance_id";
const payload = new URLSearchParams({
token: "wa_live_your_token",
to: "254712345678",
body: "Hello from JavaScript/TypeScript"
});
const res = await fetch(`${baseUrl}/${instanceId}/messages/chat`, {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: payload.toString()
});
console.log(res.status, await res.text());
C# (.NET)
using System.Net.Http;
using var client = new HttpClient();
using var form = new FormUrlEncodedContent(new Dictionary<string, string>
{
["token"] = "wa_live_your_token",
["to"] = "254712345678",
["body"] = "Hello from .NET"
});
var response = await client.PostAsync(
"http://localhost:3000/wacc_your_instance_id/messages/chat",
form
);
Console.WriteLine((int)response.StatusCode);
Console.WriteLine(await response.Content.ReadAsStringAsync());
List Incoming Messages
GET
/v1/messages/inbound
token: wa_live_your_token Optional query params: instanceId=wacc_your_instance_id limit=50
JavaScript / TypeScript (fetch)
const res = await fetch("http://localhost:3000/v1/messages/inbound?limit=50", {
headers: { token: "wa_live_your_token" }
});
const data = await res.json();
console.log(data.messages);
Incoming Message Webhooks
Configure the webhook URL from the dashboard. When a connected WhatsApp instance receives a message, NextMSG stores it and sends a JSON POST to your URL.
POST https://yourserver.com/whatsapp/webhook Content-Type: application/json X-NextMSG-Event: message.received X-NextMSG-Signature: sha256=<hmac_sha256_body_signature>
Payload
{
"event": "message.received",
"tenantId": "tenant_...",
"accountId": "wacc_...",
"message": {
"id": "inmsg_...",
"from": "252612345678",
"to": "252600000000",
"type": "chat",
"body": "Hello",
"externalId": "...",
"hasMedia": false,
"receivedAt": "2026-06-28T12:00:00.000Z"
}
}
Verify Signature in Node.js
import crypto from "node:crypto";
function verifyNextMsgWebhook(rawBody, signatureHeader, secret) {
const expected = "sha256=" + crypto
.createHmac("sha256", secret)
.update(rawBody)
.digest("hex");
const actual = Buffer.from(signatureHeader || "");
const wanted = Buffer.from(expected);
return actual.length === wanted.length && crypto.timingSafeEqual(actual, wanted);
}
Send Document
POST
/{INSTANCE_ID}/messages/document
Content-Type: multipart/form-data token=wa_live_your_token to=254712345678 caption=Monthly invoice attached document=@invoice.pdf
Python
import requests
base_url = "http://localhost:3000"
instance_id = "wacc_your_instance_id"
url = f"{base_url}/{instance_id}/messages/document"
with open("invoice.pdf", "rb") as f:
response = requests.post(
url,
data={
"token": "wa_live_your_token",
"to": "254712345678",
"caption": "Monthly invoice attached",
},
files={"document": ("invoice.pdf", f, "application/pdf")},
timeout=60,
)
print(response.status_code)
print(response.text)
JavaScript / TypeScript (Node.js 18+)
import fs from "node:fs";
const baseUrl = "http://localhost:3000";
const instanceId = "wacc_your_instance_id";
const form = new FormData();
form.append("token", "wa_live_your_token");
form.append("to", "254712345678");
form.append("caption", "Monthly invoice attached");
form.append(
"document",
new Blob([fs.readFileSync("invoice.pdf")], { type: "application/pdf" }),
"invoice.pdf"
);
const res = await fetch(`${baseUrl}/${instanceId}/messages/document`, {
method: "POST",
body: form
});
console.log(res.status, await res.text());
Go
package main
import (
"bytes"
"io"
"mime/multipart"
"net/http"
"os"
)
func main() {
var body bytes.Buffer
writer := multipart.NewWriter(&body)
_ = writer.WriteField("token", "wa_live_your_token")
_ = writer.WriteField("to", "254712345678")
_ = writer.WriteField("caption", "Monthly invoice attached")
part, _ := writer.CreateFormFile("document", "invoice.pdf")
file, _ := os.Open("invoice.pdf")
defer file.Close()
_, _ = io.Copy(part, file)
_ = writer.Close()
req, _ := http.NewRequest(
http.MethodPost,
"http://localhost:3000/wacc_your_instance_id/messages/document",
&body,
)
req.Header.Set("Content-Type", writer.FormDataContentType())
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
b, _ := io.ReadAll(resp.Body)
println(resp.StatusCode, string(b))
}