Skip to main content
The Zexa REST API gives you programmatic access to every feature available in the Zexa dashboard — send messages across SMS, WhatsApp, Telegram, email, and Slack; manage contacts and contact lists; launch broadcast campaigns; and track delivery status in real time. Every request follows a consistent JSON-based format, making it straightforward to integrate Zexa into any backend stack or automation workflow.

Base URL

All API requests target the following base URL:
https://api.zexa.ao/v1
Every endpoint path is appended to this base. For example, to check your account’s credit balance:
curl https://api.zexa.ao/v1/credits \
  -H "Authorization: Bearer YOUR_API_KEY"

Request Format

Send all request bodies as JSON and include the Content-Type: application/json header on every POST and PATCH request. The API always responds with JSON, regardless of whether the request succeeds or fails.
curl -X POST https://api.zexa.ao/v1/messages \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"channel": "sms", "to": "+244912345678", "from": "ZEXA", "body": "Hello!"}'

Authentication

Every request must include your API key as a Bearer token in the Authorization header:
Authorization: Bearer YOUR_API_KEY
Generate API keys in your dashboard under Settings → API Keys. See the Authentication page for full details, key rotation guidance, and security best practices.

Rate Limits

The API enforces per-account rate limits to ensure fair usage across all customers. When you exceed your limit, the API returns a 429 Too Many Requests response. Implement exponential backoff in your retry logic — wait a short interval after the first failure, then double the wait time on each subsequent retry before trying again.
The Retry-After response header on a 429 response indicates the number of seconds to wait before retrying.

Error Responses

All errors return a consistent JSON body so you can handle them uniformly in your code:
{
  "error": "invalid_request",
  "message": "The 'to' field must be in E.164 format.",
  "details": { "field": "to", "value": "912345678" },
  "request_id": "req_abc123"
}
FieldDescription
errorA machine-readable error code string
messageA human-readable description of what went wrong
detailsAdditional context, such as the invalid field and value
request_idUnique identifier for the request — include this when contacting support

HTTP Status Codes

The API uses standard HTTP status codes to indicate the outcome of each request.
CodeMeaning
200Success
201Resource created
204Success — no content (e.g. DELETE requests)
400Bad request — malformed syntax or missing required fields
401Unauthorized — API key is missing or invalid
404Resource not found
422Unprocessable entity — request was well-formed but failed validation
429Rate limit exceeded
500Internal server error — try again later

Pagination

All list endpoints support cursor-based pagination via the page and per_page query parameters. The default page size is 50; the maximum is 100.
curl "https://api.zexa.ao/v1/contacts?page=2&per_page=25" \
  -H "Authorization: Bearer YOUR_API_KEY"
Every paginated response wraps results in a data array alongside a meta object:
{
  "data": [ ],
  "meta": {
    "total": 340,
    "page": 2,
    "per_page": 25
  }
}
Use meta.total together with per_page to calculate the number of pages and determine when you have retrieved all records.

Endpoint Reference

The table below lists every public endpoint in the Zexa REST API and where it is documented.
MethodEndpointDescriptionReference
POST/messagesSend a single message on any channelMessages
GET/messages/{id}Retrieve a message and its delivery statusMessages
GET/sender-idsList your registered Sender IDsMessages
POST/campaignsCreate and launch a broadcast campaignCampaigns
GET/campaignsList all campaignsCampaigns
GET/campaigns/{id}Retrieve campaign status and delivery statsCampaigns
POST/contactsAdd or import a contactContacts
GET/contactsList and search contactsContacts
DELETE/contacts/{id}Permanently remove a contactContacts
POST/webhooksRegister a delivery-status webhookWebhooks
GET/creditsCheck your current credit balanceAuthentication

Next Steps

Authentication

Generate your API key and learn how to pass it securely in every request.

Send a Message

Send your first message across any supported channel with a single API call.

Campaigns

Broadcast messages to entire contact lists using the Campaigns API.

Contacts

Build and manage your recipient database programmatically.

Webhooks

Receive real-time delivery status events pushed directly to your server.

Sender IDs

Register and manage the Sender IDs used to identify your messages.