Satas Developer API

Send SMS, make calls, and manage phone numbers in Kenya and Africa — with KES billing, M-Pesa top-up, and simple REST APIs. Built for developers, priced for Africa.

Authentication

All API requests require an API key. Generate one from the Satas Portal under Developer → API Keys.

Pass your key in the Authorization header:

Authorization: Bearer sk_live_YOUR_API_KEY

Alternatively, use the X-API-Key header:

X-API-Key: sk_live_YOUR_API_KEY
⚠️ Keep your API key secret. Never expose it in frontend code or public repos. Rotate it immediately if compromised.

Base URL & Errors

https://calls.satas.co.ke/api/v1

All responses are JSON. Successful requests return 2xx. Errors return a JSON object with an error field:

{
  "error": "Insufficient wallet balance",
  "balance_kes": 0.00,
  "required_kes": 1.50
}

Quick Start

1. Get your API key

Log in to the portal, go to Developer → API Keys, click Generate Key. Copy and save it — it won't be shown again.

2. Send your first SMS

curl -X POST https://calls.satas.co.ke/api/v1/messages \
  -H "Authorization: Bearer sk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+254712345678",
    "body": "Hello from Satas!"
  }'
Response
{
  "message_id": "SM1A2B3C4D...",
  "to": "+254712345678",
  "body": "Hello from Satas!",
  "status": "sent",
  "cost_kes": 1.50,
  "balance_kes": 98.50
}

3. Make a call

curl -X POST https://calls.satas.co.ke/api/v1/calls \
  -H "Authorization: Bearer sk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"to": "+254712345678"}'

Messages (SMS)

Send SMS messages to any Kenyan or international number.

POST /messages Send an SMS
ParameterTypeDescription
torequiredstringRecipient phone number. E.164 format (+254712345678) or local (0712345678).
bodyrequiredstringMessage text. Max 918 chars (6 SMS segments).
sender_idoptionalstringSender name shown to recipient (e.g. "SATAS"). Must be registered and approved.
curl -X POST https://calls.satas.co.ke/api/v1/messages \
  -H "Authorization: Bearer sk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+254712345678",
    "body": "Your OTP is 4829. Valid for 5 minutes.",
    "sender_id": "MYAPP"
  }'
Response 201
{
  "message_id": "SM9F2A1B3C4D5E6F7A8B9C0D1E2F3A4B",
  "to": "+254712345678",
  "body": "Your OTP is 4829. Valid for 5 minutes.",
  "status": "sent",
  "cost_kes": 1.50,
  "balance_kes": 498.50
}

Calls (Voice)

Initiate outbound voice calls programmatically.

POST /calls Initiate an outbound call
ParameterTypeDescription
torequiredstringNumber to call. E.164 or local format.
fromoptionalstringCaller ID to display. Defaults to your assigned DID.
webhook_urloptionalstringURL to receive call status events.
curl -X POST https://calls.satas.co.ke/api/v1/calls \
  -H "Authorization: Bearer sk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+254712345678",
    "from": "+254709726801"
  }'
Response 201
{
  "call_id": "CA1A2B3C4D5E6F7A8B9C0D1E2F3A4B5C",
  "to": "+254712345678",
  "from": "+254709726801",
  "status": "initiated",
  "direction": "outbound"
}

Phone Numbers

List and manage your assigned Kenyan phone numbers (DIDs).

GET /numbers List your phone numbers
curl https://calls.satas.co.ke/api/v1/numbers \
  -H "Authorization: Bearer sk_live_YOUR_KEY"
Response 200
{
  "numbers": [
    {
      "number_id": 6,
      "number": "+254709726801",
      "type": "mobile",
      "country": "KE",
      "monthly_cost_kes": 500,
      "assigned_at": "2026-04-10T16:21:35.948Z"
    }
  ],
  "count": 1
}

Balance

Check your wallet balance. Top up anytime from the portal via M-Pesa.

GET /balance Get wallet balance
curl https://calls.satas.co.ke/api/v1/balance \
  -H "Authorization: Bearer sk_live_YOUR_KEY"
Response 200
{
  "balance_kes": 2984.16,
  "total_spent_kes": 2515.84,
  "currency": "KES"
}

Usage Logs

View recent API activity and costs.

GET /usage List recent API calls
Query paramTypeDescription
limitoptionalintegerMax results (default 50, max 200)
offsetoptionalintegerPagination offset
curl "https://calls.satas.co.ke/api/v1/usage?limit=10" \
  -H "Authorization: Bearer sk_live_YOUR_KEY"
Response 200
{
  "usage": [
    {
      "endpoint": "/messages",
      "method": "POST",
      "status_code": 201,
      "duration_ms": 312,
      "cost_kes": "1.5000",
      "request_id": "abc123...",
      "created_at": "2026-04-25T23:00:00.000Z"
    }
  ],
  "count": 1
}

Webhooks

Subscribe to real-time events. Satas will POST to your URL when events occur.

💡 Available events: call.initiated, call.completed, sms.sent, sms.delivered, sms.failed
POST /webhooks Register a webhook
ParameterTypeDescription
urlrequiredstringHTTPS endpoint to receive events.
eventsoptionalarrayEvent types to subscribe. Defaults to all events.
curl -X POST https://calls.satas.co.ke/api/v1/webhooks \
  -H "Authorization: Bearer sk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://yourapp.com/satas-webhook",
    "events": ["sms.delivered", "call.completed"]
  }'
Response 201
{
  "webhook": {
    "id": 1,
    "url": "https://yourapp.com/satas-webhook",
    "events": ["sms.delivered","call.completed"],
    "is_active": true
  },
  "secret_hint": "Store this secret — used to verify X-Satas-Signature header on callbacks"
}
GET /webhooks List webhooks
curl https://calls.satas.co.ke/api/v1/webhooks \
  -H "Authorization: Bearer sk_live_YOUR_KEY"
DELETE /webhooks/:id Remove a webhook
curl -X DELETE https://calls.satas.co.ke/api/v1/webhooks/1 \
  -H "Authorization: Bearer sk_live_YOUR_KEY"

Verifying Webhook Signatures

Every webhook request includes an X-Satas-Signature header — an HMAC-SHA256 of the raw request body signed with your webhook secret. Always verify this before processing.

Node.js

const crypto = require('crypto');

function verifyWebhook(rawBody, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(rawBody)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signature)
  );
}

// Express example
app.post('/satas-webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const sig = req.headers['x-satas-signature'];
  if (!verifyWebhook(req.body, sig, process.env.SATAS_WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }
  const event = JSON.parse(req.body);
  console.log(event.event, event.data);
  res.sendStatus(200);
});

Account

GET /account Get account summary
curl https://calls.satas.co.ke/api/v1/account \
  -H "Authorization: Bearer sk_live_YOUR_KEY"
Response 200
{
  "account_id": 4,
  "company": "Acme Ltd",
  "plan": "starter",
  "balance_kes": 2984.16,
  "numbers_count": 1,
  "api_key_id": "sk_live_f24ae673..."
}

Pricing

Pay as you go. No monthly minimums. Top up via M-Pesa or card.

ProductPriceNotes
SMS (Kenya)KES 1.50 / messagePer 160-char segment
Voice callKES 4.00 / minuteBilled per second after connection
Phone number (DID)KES 500 / monthKenyan mobile number
Inbound callsFreeReceive calls to your DID at no charge
Inbound SMSFreeReceive SMS on your DID
✅ New accounts start with KES 50 free credit — no card required to test.

Top up from the portal under Wallet → Top Up. Minimum top-up is KES 100.

Error Codes

HTTP StatusMeaning
200 / 201Success
400Bad request — missing or invalid parameters
401Unauthorized — invalid or missing API key
402Payment required — insufficient wallet balance
404Resource not found
429Rate limit exceeded — slow down
500Server error — contact support

Questions? Email dev@satas.co.ke or visit calls.satas.co.ke