Sending
Send a message
The headline endpoint. Pick a channel, point at a recipient, write a body, hit POST. Most integrations are five lines of code.
LIVE NOW
SMS (Africa's Talking) and Email (7 providers) are fully live. Push and WhatsApp adapters are next — see the roadmap.
Two paths to send
Either way calls the same backend, lands the same way in your message log, hits the same provider. Pick whichever fits the moment.
| Path | Auth | Use when |
|---|---|---|
POST /v1/messages | API key | Your back-end service is sending on behalf of a user |
POST /v1/admin/messages | Sign-in session | Someone on your team is sending from the dashboard |
From the API
POST/v1/messages
SMS example
curl
curl -X POST https://api-raven-cloud.autotribes.app/v1/messages \
-H "X-Raven-Key: rk_live_a3f7b2c1_..." \
-H "Content-Type: application/json" \
-d '{
"channel": "sms",
"to": "+254722000000",
"body": "Hi Ada, your order #AC-1042 is on its way."
}'Email example
curl
curl -X POST https://api-raven-cloud.autotribes.app/v1/messages \
-H "X-Raven-Key: rk_live_a3f7b2c1_..." \
-H "Content-Type: application/json" \
-d '{
"channel": "email",
"to": "ada@acme.co.ke",
"from": "orders@mail.acme.co.ke",
"subject": "Your order #AC-1042 is on its way",
"bodyHtml": "<p>Hi Ada, your order is on its way. Track it <a href=\"...\" >here</a>.</p>",
"bodyText": "Hi Ada, your order is on its way."
}'Response — 202 Accepted
json
{
"id": "8ad4f7c2-9e3b-4a1c-bc2f-1d8e3a9b7c4d",
"status": "queued",
"channel": "email",
"to": "ada@acme.co.ke",
"enqueuedAt": "2026-05-01T10:23:18.114Z"
}Body parameters
| Field | Type | Notes |
|---|---|---|
channel | string · required | sms · email · push · whatsapp |
to | string · required | E.164 phone (+254...) for SMS, or email address for email |
body | string · required for SMS | 1–4096 chars. SMS auto-segments at 160. |
from | string · required for email | RFC5322 email address, e.g. orders@mail.acme.co.ke |
subject | string · required for email | Email subject line |
bodyHtml | string · email | HTML body. Recommended alongside bodyText. |
bodyText | string · email | Plain-text fallback. Always include — some clients and spam filters require it. |
externalId | string · optional | Your own ID — useful for reconciliation |
From the dashboard
Go to Compose, pick a channel, type a recipient and a body, hit Send. The same payload is built for you and POSTed to /v1/admin/messages. Useful for one-off ops sends, customer-support replies, or testing a new template before wiring it into your back-end.
What happens after you POST
- We persist a row in
messageswith statusqueuedand return the id immediately. - A background worker picks it up within ~50ms.
- The worker resolves your provider credentials, calls the provider (e.g. Africa's Talking).
- Status becomes
sentwith the provider's message id and cost. - Provider webhooks update status to
delivered,bounced, orreadas the lifecycle progresses. - Every step is logged to
delivery_events— visible in your dashboard timeline.
Idempotency
ALWAYS SET ONE
Pass
idempotency_keyfor every send. If your service retries a timed-out request, you don't want two SMS landing on the customer's phone. Use your own internal IDs (e.g. order-AC-1042).Repeat calls with the same idempotency key + same payload return the original response without re-sending. Different payload? You get a 409 telling you the key is already used.