Core API
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/sendAuth: API key
Create a new outbound message.
Request Contract
| Parameter | In | Type | Required | Rules |
|---|---|---|---|---|
fromPhoneId | Body | string | Yes | Must be a phone ID in your account. |
to | Body | string | Yes | E.164 format (example: +15551234567). |
content | Body | string | No | Max length 4096. Required if mediaUrls is empty. |
mediaUrls | Body | string[] | No | Public HTTPS URLs only. Required if content is empty. |
idempotencyKey | Body | string | No | Max length 64. Reuse returns the original message. |
Authorization and Scopes
| Requirement | Value |
|---|---|
| Auth header | Authorization: Bearer sk_test_* | sk_live_* |
| Any required scope | messages:send |
| Alternative accepted scope | messages:write |
Status Codes
| Code | Meaning |
|---|---|
201 | Message accepted. |
400 | Validation error or phone not connected for live key. |
401 | Missing/invalid/expired API key. |
403 | API key does not include required scope. |
404 | fromPhoneId not found in account. |
429 | Rate limit exceeded for this API key. |
Response Fields
| Field | Type | Notes |
|---|---|---|
data.id | string | Message ID (msg_*). |
data.environment | "test" | "live" | Inferred from API key prefix. |
data.status | pending|sent|delivered|read|failed | Initial status is typically sent, then progresses asynchronously. |
data.sentAt | string | null | Set when message is marked sent. |
data.errorCode | string | null | Populated when status is failed. |
Request Example
curl -X POST https://developers-api.chatmaid.net/v1/messages/send \
-H "Authorization: Bearer sk_test_xxx" \
-H "Content-Type: application/json" \
-d '{"fromPhoneId":"507f1f77bcf86cd799439011","to":"+15557654321","content":"Hello"}'Expected 201 Response
{
"success": true,
"data": {
"id": "msg_abc123def456",
"from": "+15551234567",
"to": "+15557654321",
"content": "Hello",
"mediaUrls": [],
"environment": "test",
"status": "sent",
"createdAt": "2026-02-06T14:18:33.000Z",
"sentAt": "2026-02-06T14:18:33.120Z",
"deliveredAt": null,
"readAt": null,
"failedAt": null,
"errorCode": null,
"errorMessage": null
}
}GET /v1/messages
GET/v1/messagesAuth: API key
Paginated list of messages for the authenticated account.
Request Contract
| Parameter | In | Type | Required | Rules |
|---|---|---|---|---|
phoneNumberId | Query | string | No | Filter by sender phone ID. |
status | Query | string | No | One of pending, sent, delivered, read, failed. |
environment | Query | string | No | One of live, test. Defaults to API key environment. |
page | Query | number | No | Integer >= 1. Default 1. |
limit | Query | number | No | Integer 1..100. Default 20. |
Authorization and Scopes
| Requirement | Value |
|---|---|
| Auth header | Authorization: Bearer sk_test_* | sk_live_* |
| Required scope | messages:read |
Status Codes
| Code | Meaning |
|---|---|
200 | Page returned. |
401 | Missing/invalid/expired API key. |
403 | API key does not include required scope. |
429 | Rate limit exceeded for this API key. |
Response Fields
| Field | Type | Notes |
|---|---|---|
data.data[] | Message[] | Array sorted by createdAt desc. |
data.pagination.page | number | Current page index (1-based). |
data.pagination.limit | number | Requested page size. |
data.pagination.total | number | Total matching messages. |
data.pagination.totalPages | number | Computed page count. |
Request Example
curl -X GET "https://developers-api.chatmaid.net/v1/messages?status=delivered&page=1&limit=20" \
-H "Authorization: Bearer sk_test_xxx"Expected 200 Response
{
"success": true,
"data": {
"data": [
{
"id": "msg_abc123def456",
"from": "+15551234567",
"to": "+15557654321",
"content": "Hello",
"status": "delivered",
"createdAt": "2026-02-06T14:18:33.000Z"
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 1,
"totalPages": 1
}
}
}GET /v1/messages/:messageId
GET/v1/messages/:messageIdAuth: API key
Get one message and its lifecycle timestamps.
Request Contract
| Parameter | In | Type | Required | Rules |
|---|---|---|---|---|
messageId | Path | string | Yes | Message ID returned by send endpoint (msg_*). |
Authorization and Scopes
| Requirement | Value |
|---|---|
| Auth header | Authorization: Bearer sk_test_* | sk_live_* |
| Required scope | messages:read |
Status Codes
| Code | Meaning |
|---|---|
200 | Message returned. |
401 | Missing/invalid/expired API key. |
403 | API key does not include required scope. |
404 | Message ID not found in this account. |
429 | Rate limit exceeded for this API key. |
Request Example
curl -X GET https://developers-api.chatmaid.net/v1/messages/msg_abc123def456 \
-H "Authorization: Bearer sk_test_xxx"Expected 200 Response
{
"success": true,
"data": {
"id": "msg_abc123def456",
"from": "+15551234567",
"to": "+15557654321",
"content": "Hello",
"mediaUrls": [],
"environment": "test",
"status": "read",
"errorCode": null,
"errorMessage": null,
"createdAt": "2026-02-06T14:18:33.000Z",
"sentAt": "2026-02-06T14:18:33.120Z",
"deliveredAt": "2026-02-06T14:18:34.200Z",
"readAt": "2026-02-06T14:18:36.000Z",
"failedAt": null
}
}GET /v1/phone-numbers
GET/v1/phone-numbersAuth: API key
List phone numbers available to this account.
Authorization and Scopes
| Requirement | Value |
|---|---|
| Auth header | Authorization: Bearer sk_test_* | sk_live_* |
| Recommended scope | phone_numbers:read |
| Backward-compatible scope accepted | phone-numbers:read |
Status Codes
| Code | Meaning |
|---|---|
200 | Phone list returned. |
401 | Missing/invalid/expired API key. |
403 | API key does not include required scope. |
429 | Rate limit exceeded for this API key. |
Request Example
curl -X GET https://developers-api.chatmaid.net/v1/phone-numbers \
-H "Authorization: Bearer sk_test_xxx"Expected 200 Response
{
"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/:idAuth: API key
Get one phone number by internal ID or URL-encoded E.164 value.
Request Contract
| Parameter | In | Type | Required | Rules |
|---|---|---|---|---|
id | Path | string | Yes | Accepts phone ID or URL-encoded E.164 value (example: %2B15551234567). |
Status Codes
| Code | Meaning |
|---|---|
200 | Phone returned. |
401 | Missing/invalid/expired API key. |
403 | API key does not include required scope. |
404 | Phone reference not found in this account. |
429 | Rate limit exceeded for this API key. |
Request Example
curl -X GET "https://developers-api.chatmaid.net/v1/phone-numbers/%2B15551234567" \
-H "Authorization: Bearer sk_test_xxx"Expected 200 Response
{
"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/statusAuth: API key
Get live connection state by internal ID or URL-encoded E.164 value.
Request Contract
| Parameter | In | Type | Required | Rules |
|---|---|---|---|---|
id | Path | string | Yes | Accepts phone ID or URL-encoded E.164 value (example: %2B15551234567). |
Status Codes
| Code | Meaning |
|---|---|
200 | Status returned. |
401 | Missing/invalid/expired API key. |
403 | API key does not include required scope. |
404 | Phone reference not found in this account. |
429 | Rate limit exceeded for this API key. |
Request Example
curl -X GET "https://developers-api.chatmaid.net/v1/phone-numbers/%2B15551234567/status" \
-H "Authorization: Bearer sk_test_xxx"Expected 200 Response
{
"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/accountAuth: API key
Read account profile and aggregate counters.
Authorization and Scopes
| Requirement | Value |
|---|---|
| Auth header | Authorization: Bearer sk_test_* | sk_live_* |
| Recommended scope | account:read |
| Other accepted scopes | messages:read, messages:send, messages:write |
Status Codes
| Code | Meaning |
|---|---|
200 | Account data returned. |
401 | Missing/invalid/expired API key. |
403 | API key does not include required scope. |
429 | Rate limit exceeded for this API key. |
Request Example
curl -X GET https://developers-api.chatmaid.net/v1/account \
-H "Authorization: Bearer sk_test_xxx"Expected 200 Response
{
"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/usageAuth: API key
Read account usage metrics for day, week, or month.
Request Contract
| Parameter | In | Type | Required | Rules |
|---|---|---|---|---|
period | Query | string | No | One of day, week, month. Default month. |
Status Codes
| Code | Meaning |
|---|---|
200 | Usage returned. |
401 | Missing/invalid/expired API key. |
403 | API key does not include required scope. |
429 | Rate limit exceeded for this API key. |
Request Example
curl -X GET "https://developers-api.chatmaid.net/v1/account/usage?period=month" \
-H "Authorization: Bearer sk_test_xxx"Expected 200 Response
{
"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,
"delivered": 306,
"read": 298,
"failed": 14
},
"apiRequests": {
"total": 1242,
"successful": 1221,
"failed": 21
}
}
}Response Schema
Standard Success Envelope
{
"success": true,
"data": {}
}Standard Error Envelope
{
"success": false,
"error": "Unauthorized",
"message": ["Invalid API key"],
"statusCode": 401,
"timestamp": "2026-02-06T14:22:30.000Z",
"path": "/v1/messages"
}Rate Limit Error Envelope
{
"success": false,
"error": "Rate limit exceeded",
"retryAfter": 60
}