Send Message
api.ziett.co/c/v1 /messages
Submit a request to send a single transactional message to a specific recipient. Designed for high-reliability, low-latency programmatic notifications — OTPs, delivery alerts, account events, and other time-sensitive communications that must reach one user immediately.
For sending messages to large audiences, see Send Batch Campaign.
How It Works
- Validation — The API authenticates your key, verifies the
messages:sendscope, and validates all fields. - Routing — The recipient's number is analysed to identify the target carrier network and country.
- Pricing — The cost for the specific route and channel is calculated against your plan.
- Funds Check — The system verifies your balance is sufficient. If not, the request is rejected with
402. - Queuing — The message is placed in a high-priority delivery queue and dispatched to the carrier or Meta's Cloud API.
- Response —
202 Acceptedis returned immediately with amessage_idto track the lifecycle.
202 Accepted— not200 OK— is intentional. It means your message has been accepted and queued, not yet delivered. Track final status via webhook or Retrieve Message.
Request
Required scope: apikey:messages:send
Body
Content-Type: application/json
| Field | Type | Required | Description |
|---|---|---|---|
remitter_id | uuid | ✅ | UUID of the Sender ID configured in your organization. Determines the sender name or number displayed to the recipient. |
channel_type | enum | ✅ | Delivery channel. Accepted values: SMS. |
target_e164 | string | ✅ | Recipient phone number in E.164 format (e.g., +244990090990). Must include the country code. |
content | string | ✅ | Message body. For SMS, max 1600 characters — multi-part messages are concatenated automatically. |
save_contact | object | ❌ | If provided, upserts the recipient into your contact list. See Save Contact Object. |
Save Contact Object
When included, the recipient is created or updated in your contacts list at send time — useful for building your audience organically from transactional traffic.
| Field | Type | Required | Description |
|---|---|---|---|
name | string | ✅ | Full name of the contact. |
email | string | ❌ | Email address. Must be a valid format. |
tags | array[string] | ❌ | Tags to assign (e.g., ["Premium", "Angola"]). Created automatically if they don't exist. |
Examples
import httpx
response = httpx.post(
"https://api.ziett.co/c/v1/messages",
headers={
"X-API-KEY": "zk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"Content-Type": "application/json",
},
json={
"remitter_id": "019b4b56-e704-7c30-83a0-527df63c3e00",
"channel_type": "SMS",
"target_e164": "+244990090990",
"content": "Your verification code is 482910. It expires in 5 minutes.",
},
)
if response.status_code == 202:
message_id = response.json()["message_id"]
print(f"Message accepted. Tracking ID: {message_id}")
else:
print(f"Error: {response.json()}")
curl -X POST https://api.ziett.co/c/v1/messages \
-H "Content-Type: application/json" \
-H "X-API-KEY: zk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-d '{
"remitter_id": "019b4b56-e704-7c30-83a0-527df63c3e00",
"channel_type": "SMS",
"target_e164": "+244990090990",
"content": "Your verification code is 482910. It expires in 5 minutes."
}'
const response = await fetch("https://api.ziett.co/c/v1/messages", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-KEY": "zk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
},
body: JSON.stringify({
remitter_id: "019b4b56-e704-7c30-83a0-527df63c3e00",
channel_type: "SMS",
target_e164: "+244990090990",
content: "Your verification code is 482910. It expires in 5 minutes.",
}),
});
const data = await response.json();
if (response.status === 202) {
console.log("Message accepted. Tracking ID:", data.message_id);
} else {
console.error("Error:", data);
}
curl -X POST https://api.ziett.co/c/v1/messages \
-H "Content-Type: application/json" \
-H "X-API-KEY: zk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-d '{
"remitter_id": "019b4b56-e704-7c30-83a0-527df63c3e00",
"channel_type": "SMS",
"target_e164": "+244990090990",
"content": "Welcome to Ziett. Your account is now active.",
"save_contact": {
"name": "Carlos David",
"email": "carlos.david@example.com",
"tags": ["New Customer", "Angola"]
}
}'
Responses
202 Accepted — Message Queued
The message has been validated, your account debited, and the message placed in the delivery queue.
{
"message_id": "019b4b56-e704-7c30-83a0-527df63c3e00"
}
| Field | Type | Description |
|---|---|---|
message_id | uuid | Unique identifier for this message. Store it to retrieve delivery status or correlate with webhook events. |
401 Unauthorized — Invalid API Key
The X-API-KEY header is missing, malformed, or the key has been revoked.
{
"code": "AUTH_INVALID_API_KEY",
"message": "The provided API key is invalid or has been revoked.",
"status": 401,
"trace_id": "a1b2c3d4e5f644358a9e7011c123c831",
"timestamp": "2025-07-14T10:30:00.000000+00:00",
"service": "core"
}
402 Payment Required — Insufficient Funds
Your organization's credit balance is below the cost of this message route.
{
"code": "BILLING_INSUFFICIENT_FUNDS",
"message": "Your account balance is too low to process this request. Please top up your credits.",
"status": 402,
"trace_id": "c109f78ae57744358a9e7011c123c831",
"timestamp": "2025-07-14T10:30:00.000000+00:00",
"service": "billing"
}
422 Unprocessable Entity — Validation Error
One or more fields are missing or contain invalid values. The fields object maps each failing field to a specific message.
{
"code": "VALIDATION_ERROR",
"message": "One or more fields failed validation.",
"status": 422,
"trace_id": "f812a3bc91e044358a9e7011c456d901",
"timestamp": "2025-07-14T10:30:00.000000+00:00",
"service": "core",
"fields": {
"target_e164": "Must be a valid E.164 formatted phone number (e.g., +244990090990).",
"channel_type": "Accepted values are: SMS, WHATSAPP."
}
}
Rate Limits
This endpoint is limited to 120 requests per minute per API Key. See Rate Limits & Reliability for backoff strategies and retry guidance.
Related Endpoints
- Get Message — Get the delivery status of a specific message by
message_id. - List Messages — Retrieve paginated history of all messages sent by your organization.
- Send Batch Campaign — Send to a large audience in a single request.