ChatmaidDevelopers

API Reference

Endpoint-level parameters and response fields for integration APIs.

Base URL:

  • https://developers-api.chatmaid.net

Integration host: https://developers-api.chatmaid.net.

POST /v1/messages/send

POST /v1/messages/send

Create a new outbound message.

Request Contract

ParameterInTypeRequiredRules
fromPhoneIdBodystringYesSender phone, given as its E.164 number (recommended) or its dashboard ID.
toBodystringYesE.164 phone number (example: +15551234567), or a group JID (example: 120363043211234567@g.us) from GET /v1/groups.
contentBodystringNoMax length 4096. Required if mediaUrls is empty.
mediaUrlsBodystring[]NoPublic HTTPS URLs only. Required if content is empty.
idempotencyKeyBodystringNoMax length 64. Reuse returns the original message.

Authorization and Scopes

RequirementValue
Auth headerAuthorization: Bearer sk_test_* | sk_live_*
Any required scopemessages:send
Alternative accepted scopemessages:write

Status Codes

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

Response Fields

FieldTypeNotes
data.idstringMessage ID (msg_*).
data.isGroupbooleanTrue when the recipient is a WhatsApp group.
data.groupIdstring | nullFull group JID when isGroup is true.
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 | nullStable error code, populated when status is failed. See Error codes.
data.errorMessagestring | nullHuman-readable explanation, populated when status is failed.

Error codes

When a message ends in failed, errorCode is one of the following stable values. errorMessage provides a human-readable explanation. These are the only values that will ever appear — internal service details are never surfaced.

errorCodeMeaning
NOT_CONNECTEDThe sending phone number is not connected to WhatsApp.
INVALID_RECIPIENTThe recipient is not a valid WhatsApp user or group.
RECIPIENT_NOT_REACHABLEThe message could not be delivered. The recipient may need to message you first, or may not be reachable on WhatsApp.
NOT_GROUP_MEMBERThe sender is not a member of the group or is not allowed to post in it.
RATE_LIMITEDSending is temporarily rate-limited by WhatsApp. Retry later.
NOT_AUTHORIZEDThe WhatsApp session is no longer authorized. Reconnect the phone number.
MEDIA_ERRORThe media could not be fetched or is not a supported type.
TIMEOUTWhatsApp did not respond in time; delivery is indeterminate.
SERVICE_UNAVAILABLEThe WhatsApp service is temporarily unavailable. Retry shortly.
INTERNAL_ERRORAn unexpected error occurred.
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"}'
{
  "success": true,
  "data": {
    "id": "msg_abc123def456",
    "from": "+15551234567",
    "to": "+15557654321",
    "isGroup": false,
    "groupId": null,
    "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).

GET /v1/messages

GET /v1/messages

Paginated list of messages for the authenticated account.

Request Contract

ParameterInTypeRequiredRules
phoneNumberIdQuerystringNoFilter by sender phone ID.
statusQuerystringNoOne of pending, sent, delivered, read, failed.
pageQuerynumberNoInteger >= 1. Default 1.
limitQuerynumberNoInteger 1..100. Default 20.

Results are scoped to the API key's environment (sk_live_ or sk_test_) automatically.

Authorization and Scopes

RequirementValue
Auth headerAuthorization: Bearer sk_test_* | sk_live_*
Required scopemessages:read

Status Codes

CodeMeaning
200Page returned.
401Missing/invalid/expired API key.
403API key does not include required scope.
429Rate limit exceeded for this API key.

Response Fields

FieldTypeNotes
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 -X GET "https://developers-api.chatmaid.net/v1/messages?status=sent&page=1&limit=20" \
  -H "Authorization: Bearer sk_test_xxx"
{
  "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 /v1/messages/:messageId

GET /v1/messages/:messageId

Get one message and its lifecycle timestamps.

Request Contract

ParameterInTypeRequiredRules
messageIdPathstringYesMessage ID returned by send endpoint (msg_*).

Authorization and Scopes

RequirementValue
Auth headerAuthorization: Bearer sk_test_* | sk_live_*
Required scopemessages:read

Status Codes

CodeMeaning
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 -X GET https://developers-api.chatmaid.net/v1/messages/msg_abc123def456 \
  -H "Authorization: Bearer sk_test_xxx"
{
  "success": true,
  "data": {
    "id": "msg_abc123def456",
    "from": "+15551234567",
    "to": "+15557654321",
    "isGroup": false,
    "groupId": null,
    "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
  }
}

GET /v1/messages/inbound

GET /v1/messages/inbound

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.

Request Contract

ParameterInTypeRequiredRules
phoneNumberIdQuerystringNoFilter by receiving phone ID.
pageQuerynumberNoInteger >= 1. Default 1.
limitQuerynumberNoInteger 1..100. Default 20.

Authorization and Scopes

RequirementValue
Auth headerAuthorization: Bearer sk_live_*
Required scopemessages:read

Status Codes

CodeMeaning
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 /v1/messages/inbound/:messageId

GET /v1/messages/inbound/:messageId

Get one inbound message by its identifier.

Request Contract

ParameterInTypeRequiredRules
messageIdPathstringYesInbound message ID (inmsg_*).

Status Codes

CodeMeaning
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"

GET /v1/groups

GET /v1/groups

List the WhatsApp groups a sender phone can post to. Each id is a full group JID, valid as to in POST /v1/messages/send. See Groups for details.

Request Contract

ParameterInTypeRequiredRules
fromPhoneIdQuerystringYesSender phone, given as its E.164 number (recommended) or its dashboard ID.

Authorization and Scopes

RequirementValue
Auth headerAuthorization: Bearer sk_test_* | sk_live_*
Any required scopegroups:read
Alternative accepted scopesmessages:read, messages:send, messages:write

Status Codes

CodeMeaning
200Group list returned.
400Phone 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.
502WhatsApp group fetch failed — retry after a moment.
curl -X GET "https://developers-api.chatmaid.net/v1/groups?fromPhoneId=%2B15551234567" \
  -H "Authorization: Bearer sk_live_xxx"
{
  "success": true,
  "data": [
    {
      "id": "120363043211234567@g.us",
      "name": "Team Updates",
      "isCommunityAnnounce": false
    }
  ]
}

GET /v1/phone-numbers

GET /v1/phone-numbers

List phone numbers available to this account.

Authorization and Scopes

RequirementValue
Auth headerAuthorization: Bearer sk_test_* | sk_live_*
Recommended scopephone_numbers:read
Backward-compatible scope acceptedphone-numbers:read

Status Codes

CodeMeaning
200Phone list 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/phone-numbers \
  -H "Authorization: Bearer sk_test_xxx"
{
  "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 /v1/phone-numbers/:id

GET /v1/phone-numbers/:id

Get one phone number by internal ID or URL-encoded E.164 value.

Request Contract

ParameterInTypeRequiredRules
idPathstringYesAccepts phone ID or URL-encoded E.164 value (example: %2B15551234567).

Status Codes

CodeMeaning
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 -X GET "https://developers-api.chatmaid.net/v1/phone-numbers/%2B15551234567" \
  -H "Authorization: Bearer sk_test_xxx"
{
  "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 /v1/phone-numbers/:id/status

GET /v1/phone-numbers/:id/status

Get live connection state by internal ID or URL-encoded E.164 value.

Request Contract

ParameterInTypeRequiredRules
idPathstringYesAccepts phone ID or URL-encoded E.164 value (example: %2B15551234567).

Status Codes

CodeMeaning
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 -X GET "https://developers-api.chatmaid.net/v1/phone-numbers/%2B15551234567/status" \
  -H "Authorization: Bearer sk_test_xxx"
{
  "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"
  }
}

GET /v1/account

GET /v1/account

Read account profile and aggregate counters.

Authorization and Scopes

RequirementValue
Auth headerAuthorization: Bearer sk_test_* | sk_live_*
Recommended scopeaccount:read
Other accepted scopesmessages:read, messages:send, messages:write

Status Codes

CodeMeaning
200Account data 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/account \
  -H "Authorization: Bearer sk_test_xxx"
{
  "success": true,
  "data": {
    "accountId": "acc_abc123def456",
    "name": "Acme Inc",
    "email": "developer@acme.com",
    "subscriptionStatus": "active",
    "stats": {
      "apiKeys": 2,
      "phoneNumbers": 1,
      "messages": 328
    }
  }
}

GET /v1/account/usage

GET /v1/account/usage

Read account usage metrics for day, week, or month.

Request Contract

ParameterInTypeRequiredRules
periodQuerystringNoOne of day, week, month. Default month.

Status Codes

CodeMeaning
200Usage 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/account/usage?period=month" \
  -H "Authorization: Bearer sk_test_xxx"
{
  "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
    }
  }
}

Response Schema

{
  "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
}

On this page