Base URL:
https://developers-api.chatmaid.net
Integration host: https://developers-api.chatmaid.net.
Create a new outbound message.
Parameter In Type Required Rules fromPhoneIdBody stringYes Sender phone, given as its E.164 number (recommended) or its dashboard ID. toBody stringYes E.164 format (example: +15551234567). contentBody stringNo Max length 4096. Required if mediaUrls is empty. mediaUrlsBody string[]No Public HTTPS URLs only. Required if content is empty. idempotencyKeyBody stringNo Max length 64. Reuse returns the original message.
Requirement Value Auth header Authorization: Bearer sk_test_* | sk_live_*Any required scope messages:sendAlternative accepted scope messages:write
Code Meaning 201Message accepted. 400Validation error or phone not connected for live key. 401Missing/invalid/expired API key. 403API key does not include required scope. 404fromPhoneId not found in account. 429Rate limit exceeded for this API key.
Field Type Notes data.idstringMessage ID (msg_*). data.statuspending|sent|delivered|read|failedStatus after a successful send is sent; transitions to delivered/read as WhatsApp receipts arrive. Failed sends are marked failed. data.sentAtstring | nullSet when message is marked sent. data.deliveredAtstring | nullSet when WhatsApp confirms delivery to the recipient. data.readAtstring | nullSet when the recipient reads the message (requires read receipts). data.errorCodestring | nullPopulated when status is failed.
cURL Node.js Python
curl -X POST https://developers-api.chatmaid.net/v1/messages/send \
-H "Authorization: Bearer sk_test_xxx" \
-H "Content-Type: application/json" \
-d '{"fromPhoneId":"+15551234567","to":"+15557654321","content":"Hello"}' const response = await fetch ( "https://developers-api.chatmaid.net/v1/messages/send" , {
method: "POST" ,
headers: {
Authorization: "Bearer " + process.env. CHATMAID_API_KEY ,
"Content-Type" : "application/json" ,
},
body: JSON . stringify ({
fromPhoneId: "+15551234567" ,
to: "+15557654321" ,
content: "Hello" ,
}),
});
const payload = await response. json (); import os
import requests
response = requests.post(
"https://developers-api.chatmaid.net/v1/messages/send" ,
headers = {
"Authorization" : f "Bearer { os.environ[ 'CHATMAID_API_KEY' ] } " ,
"Content-Type" : "application/json" ,
},
json = {
"fromPhoneId" : "+15551234567" ,
"to" : "+15557654321" ,
"content" : "Hello" ,
},
)
payload = response.json()
{
"success" : true ,
"data" : {
"id" : "msg_abc123def456" ,
"from" : "+15551234567" ,
"to" : "+15557654321" ,
"content" : "Hello" ,
"mediaUrls" : [],
"status" : "sent" ,
"createdAt" : "2026-02-06T14:18:33.000Z" ,
"sentAt" : "2026-02-06T14:18:33.120Z" ,
"failedAt" : null ,
"errorCode" : null ,
"errorMessage" : null
}
}
For live keys, the response is returned with status: "pending" and is updated to sent or failed once the WhatsApp microservice confirms delivery, then to delivered / read as recipient receipts arrive (track via webhooks or by polling GET /v1/messages/:messageId).
Paginated list of messages for the authenticated account.
Parameter In Type Required Rules phoneNumberIdQuery stringNo Filter by sender phone ID. statusQuery stringNo One of pending, sent, delivered, read, failed. pageQuery numberNo Integer >= 1. Default 1. limitQuery numberNo Integer 1..100. Default 20.
Results are scoped to the API key's environment (sk_live_ or sk_test_) automatically.
Requirement Value Auth header Authorization: Bearer sk_test_* | sk_live_*Required scope messages:read
Code Meaning 200Page returned. 401Missing/invalid/expired API key. 403API key does not include required scope. 429Rate limit exceeded for this API key.
Field Type Notes data.data[]Message[]Array sorted by createdAt desc. data.pagination.pagenumberCurrent page index (1-based). data.pagination.limitnumberRequested page size. data.pagination.totalnumberTotal matching messages. data.pagination.totalPagesnumberComputed page count.
cURL Node.js Python
curl -X GET "https://developers-api.chatmaid.net/v1/messages?status=sent&page=1&limit=20" \
-H "Authorization: Bearer sk_test_xxx" const query = new URLSearchParams ({
status: "sent" ,
page: "1" ,
limit: "20" ,
});
const response = await fetch (
"https://developers-api.chatmaid.net/v1/messages?" + query. toString (),
{ headers: { Authorization: "Bearer " + process.env. CHATMAID_API_KEY } }
);
const payload = await response. json (); import os
import requests
response = requests.get(
"https://developers-api.chatmaid.net/v1/messages" ,
headers = { "Authorization" : f "Bearer { os.environ[ 'CHATMAID_API_KEY' ] } " },
params = { "status" : "sent" , "page" : 1 , "limit" : 20 },
)
payload = response.json()
{
"success" : true ,
"data" : {
"data" : [
{
"id" : "msg_abc123def456" ,
"from" : "+15551234567" ,
"to" : "+15557654321" ,
"content" : "Hello" ,
"status" : "sent" ,
"createdAt" : "2026-02-06T14:18:33.000Z"
}
],
"pagination" : {
"page" : 1 ,
"limit" : 20 ,
"total" : 1 ,
"totalPages" : 1
}
}
}
Get one message and its lifecycle timestamps.
Parameter In Type Required Rules messageIdPath stringYes Message ID returned by send endpoint (msg_*).
Requirement Value Auth header Authorization: Bearer sk_test_* | sk_live_*Required scope messages:read
Code Meaning 200Message returned. 401Missing/invalid/expired API key. 403API key does not include required scope. 404Message ID not found in this account. 429Rate limit exceeded for this API key.
cURL Node.js Python
curl -X GET https://developers-api.chatmaid.net/v1/messages/msg_abc123def456 \
-H "Authorization: Bearer sk_test_xxx" const response = await fetch (
"https://developers-api.chatmaid.net/v1/messages/msg_abc123def456" ,
{ headers: { Authorization: "Bearer " + process.env. CHATMAID_API_KEY } }
);
const payload = await response. json (); import os
import requests
response = requests.get(
"https://developers-api.chatmaid.net/v1/messages/msg_abc123def456" ,
headers = { "Authorization" : f "Bearer { os.environ[ 'CHATMAID_API_KEY' ] } " },
)
payload = response.json()
{
"success" : true ,
"data" : {
"id" : "msg_abc123def456" ,
"from" : "+15551234567" ,
"to" : "+15557654321" ,
"content" : "Hello" ,
"mediaUrls" : [],
"status" : "delivered" ,
"errorCode" : null ,
"errorMessage" : null ,
"createdAt" : "2026-02-06T14:18:33.000Z" ,
"sentAt" : "2026-02-06T14:18:33.120Z" ,
"deliveredAt" : "2026-02-06T14:18:35.000Z" ,
"readAt" : null ,
"failedAt" : null
}
}
Paginated list of messages received by the account's connected phone numbers. Inbound messages exist for live connections only — sandbox (sk_test_*) keys always receive an empty list.
Parameter In Type Required Rules phoneNumberIdQuery stringNo Filter by receiving phone ID. pageQuery numberNo Integer >= 1. Default 1. limitQuery numberNo Integer 1..100. Default 20.
Requirement Value Auth header Authorization: Bearer sk_live_*Required scope messages:read
Code Meaning 200Page returned. 401Missing/invalid/expired API key. 403API key does not include required scope. 429Rate limit exceeded for this API key.
curl -X GET "https://developers-api.chatmaid.net/v1/messages/inbound?page=1&limit=20" \
-H "Authorization: Bearer sk_live_xxx"
{
"success" : true ,
"data" : {
"data" : [
{
"id" : "inmsg_abc123def456" ,
"from" : "+15557654321" ,
"to" : "+15551234567" ,
"content" : "Thanks, got it!" ,
"type" : "text" ,
"isGroup" : false ,
"groupId" : null ,
"receivedAt" : "2026-02-06T14:21:08.000Z" ,
"createdAt" : "2026-02-06T14:21:09.000Z"
}
],
"pagination" : {
"page" : 1 ,
"limit" : 20 ,
"total" : 1 ,
"totalPages" : 1
}
}
}
Get one inbound message by its identifier.
Parameter In Type Required Rules messageIdPath stringYes Inbound message ID (inmsg_*).
Code Meaning 200Inbound message returned. 401Missing/invalid/expired API key. 403API key does not include required scope. 404Inbound message ID not found in this account. 429Rate limit exceeded for this API key.
curl -X GET https://developers-api.chatmaid.net/v1/messages/inbound/inmsg_abc123def456 \
-H "Authorization: Bearer sk_live_xxx"
List phone numbers available to this account.
Requirement Value Auth header Authorization: Bearer sk_test_* | sk_live_*Recommended scope phone_numbers:readBackward-compatible scope accepted phone-numbers:read
Code Meaning 200Phone list returned. 401Missing/invalid/expired API key. 403API key does not include required scope. 429Rate limit exceeded for this API key.
cURL Node.js Python
curl -X GET https://developers-api.chatmaid.net/v1/phone-numbers \
-H "Authorization: Bearer sk_test_xxx" const response = await fetch ( "https://developers-api.chatmaid.net/v1/phone-numbers" , {
headers: { Authorization: "Bearer " + process.env. CHATMAID_API_KEY },
});
const payload = await response. json (); import os
import requests
response = requests.get(
"https://developers-api.chatmaid.net/v1/phone-numbers" ,
headers = { "Authorization" : f "Bearer { os.environ[ 'CHATMAID_API_KEY' ] } " },
)
payload = response.json()
{
"success" : true ,
"data" : [
{
"id" : "507f1f77bcf86cd799439011" ,
"phoneNumber" : "+15551234567" ,
"displayName" : "Primary Sender" ,
"connectionStatus" : "connected" ,
"lastConnectedAt" : "2026-02-06T14:10:00.000Z" ,
"lastDisconnectedAt" : null ,
"createdAt" : "2026-02-01T10:20:00.000Z" ,
"updatedAt" : "2026-02-06T14:10:00.000Z"
}
]
}
Get one phone number by internal ID or URL-encoded E.164 value.
Parameter In Type Required Rules idPath stringYes Accepts phone ID or URL-encoded E.164 value (example: %2B15551234567).
Code Meaning 200Phone returned. 401Missing/invalid/expired API key. 403API key does not include required scope. 404Phone reference not found in this account. 429Rate limit exceeded for this API key.
cURL Node.js Python
curl -X GET "https://developers-api.chatmaid.net/v1/phone-numbers/%2B15551234567" \
-H "Authorization: Bearer sk_test_xxx" const phoneRef = encodeURIComponent ( "+15551234567" );
const response = await fetch ( `https://developers-api.chatmaid.net/v1/phone-numbers/${ phoneRef }` , {
headers: { Authorization: "Bearer " + process.env. CHATMAID_API_KEY },
});
const payload = await response. json (); import os
import requests
from urllib.parse import quote
phone_ref = quote( "+15551234567" , safe = "" )
response = requests.get(
f "https://developers-api.chatmaid.net/v1/phone-numbers/ { phone_ref } " ,
headers = { "Authorization" : f "Bearer { os.environ[ 'CHATMAID_API_KEY' ] } " },
)
payload = response.json()
{
"success" : true ,
"data" : {
"id" : "507f1f77bcf86cd799439011" ,
"phoneNumber" : "+15551234567" ,
"displayName" : "Primary Sender" ,
"connectionStatus" : "connected" ,
"lastConnectedAt" : "2026-02-06T14:10:00.000Z" ,
"lastDisconnectedAt" : null ,
"createdAt" : "2026-02-01T10:20:00.000Z" ,
"updatedAt" : "2026-02-06T14:10:00.000Z"
}
}
Get live connection state by internal ID or URL-encoded E.164 value.
Parameter In Type Required Rules idPath stringYes Accepts phone ID or URL-encoded E.164 value (example: %2B15551234567).
Code Meaning 200Status returned. 401Missing/invalid/expired API key. 403API key does not include required scope. 404Phone reference not found in this account. 429Rate limit exceeded for this API key.
cURL Node.js Python
curl -X GET "https://developers-api.chatmaid.net/v1/phone-numbers/%2B15551234567/status" \
-H "Authorization: Bearer sk_test_xxx" const phoneRef = encodeURIComponent ( "+15551234567" );
const response = await fetch ( `https://developers-api.chatmaid.net/v1/phone-numbers/${ phoneRef }/status` , {
headers: { Authorization: "Bearer " + process.env. CHATMAID_API_KEY },
});
const payload = await response. json (); import os
import requests
from urllib.parse import quote
phone_ref = quote( "+15551234567" , safe = "" )
response = requests.get(
f "https://developers-api.chatmaid.net/v1/phone-numbers/ { phone_ref } /status" ,
headers = { "Authorization" : f "Bearer { os.environ[ 'CHATMAID_API_KEY' ] } " },
)
payload = response.json()
{
"success" : true ,
"data" : {
"id" : "507f1f77bcf86cd799439011" ,
"phoneNumber" : "+15551234567" ,
"connectionStatus" : "connected" ,
"lastConnectedAt" : "2026-02-06T14:10:00.000Z" ,
"lastDisconnectedAt" : null ,
"updatedAt" : "2026-02-06T14:10:00.000Z"
}
}
Read account profile and aggregate counters.
Requirement Value Auth header Authorization: Bearer sk_test_* | sk_live_*Recommended scope account:readOther accepted scopes messages:read, messages:send, messages:write
Code Meaning 200Account data returned. 401Missing/invalid/expired API key. 403API key does not include required scope. 429Rate limit exceeded for this API key.
cURL Node.js Python
curl -X GET https://developers-api.chatmaid.net/v1/account \
-H "Authorization: Bearer sk_test_xxx" const response = await fetch ( "https://developers-api.chatmaid.net/v1/account" , {
headers: { Authorization: "Bearer " + process.env. CHATMAID_API_KEY },
});
const payload = await response. json (); import os
import requests
response = requests.get(
"https://developers-api.chatmaid.net/v1/account" ,
headers = { "Authorization" : f "Bearer { os.environ[ 'CHATMAID_API_KEY' ] } " },
)
payload = response.json()
{
"success" : true ,
"data" : {
"accountId" : "acc_abc123def456" ,
"name" : "Acme Inc" ,
"email" : "developer@acme.com" ,
"subscriptionStatus" : "active" ,
"stats" : {
"apiKeys" : 2 ,
"phoneNumbers" : 1 ,
"messages" : 328
}
}
}
Read account usage metrics for day, week, or month.
Parameter In Type Required Rules periodQuery stringNo One of day, week, month. Default month.
Code Meaning 200Usage returned. 401Missing/invalid/expired API key. 403API key does not include required scope. 429Rate limit exceeded for this API key.
cURL Node.js Python
curl -X GET "https://developers-api.chatmaid.net/v1/account/usage?period=month" \
-H "Authorization: Bearer sk_test_xxx" const response = await fetch ( "https://developers-api.chatmaid.net/v1/account/usage?period=month" , {
headers: { Authorization: "Bearer " + process.env. CHATMAID_API_KEY },
});
const payload = await response. json (); import os
import requests
response = requests.get(
"https://developers-api.chatmaid.net/v1/account/usage" ,
headers = { "Authorization" : f "Bearer { os.environ[ 'CHATMAID_API_KEY' ] } " },
params = { "period" : "month" },
)
payload = response.json()
{
"success" : true ,
"data" : {
"period" : "month" ,
"startDate" : "2026-01-07T14:20:00.000Z" ,
"endDate" : "2026-02-06T14:20:00.000Z" ,
"messages" : {
"total" : 328 ,
"pending" : 0 ,
"sent" : 314 ,
"failed" : 14
},
"apiRequests" : {
"total" : 1242 ,
"successful" : 1221 ,
"failed" : 21
}
}
}
{
"success" : true ,
"data" : {}
}
{
"success" : false ,
"error" : "Unauthorized" ,
"message" : [ "Invalid API key" ],
"statusCode" : 401 ,
"timestamp" : "2026-02-06T14:22:30.000Z" ,
"path" : "/v1/messages"
}
{
"success" : false ,
"error" : "Rate limit exceeded" ,
"message" : [ "Rate limit exceeded" ],
"statusCode" : 429 ,
"timestamp" : "2026-02-06T14:22:30.000Z" ,
"path" : "/v1/messages/send" ,
"retryAfter" : 60
}