Send Message

POST

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

  1. Validation — The API authenticates your key, verifies the messages:send scope, and validates all fields.
  2. Routing — The recipient's number is analysed to identify the target carrier network and country.
  3. Pricing — The cost for the specific route and channel is calculated against your plan.
  4. Funds Check — The system verifies your balance is sufficient. If not, the request is rejected with 402.
  5. Queuing — The message is placed in a high-priority delivery queue and dispatched to the carrier or Meta's Cloud API.
  6. Response202 Accepted is returned immediately with a message_id to track the lifecycle.

202 Accepted — not 200 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

FieldTypeRequiredDescription
remitter_iduuidUUID of the Sender ID configured in your organization. Determines the sender name or number displayed to the recipient.
channel_typeenumDelivery channel. Accepted values: SMS.
target_e164stringRecipient phone number in E.164 format (e.g., +244990090990). Must include the country code.
contentstringMessage body. For SMS, max 1600 characters — multi-part messages are concatenated automatically.
save_contactobjectIf 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.

FieldTypeRequiredDescription
namestringFull name of the contact.
emailstringEmail address. Must be a valid format.
tagsarray[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()}")

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"
}
FieldTypeDescription
message_iduuidUnique 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.


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