SMS
Send to Address Book

Send to Address Book

Send an SMS campaign to all contacts in one or more address books. TalkNTalk resolves every contact's phone number, deduplicates across books, and dispatches the campaign asynchronously.


Endpoint

POST /v1/sms/send-group/

Authentication: Bearer API key


Request Body

{
  "group_ids": ["3f8e2d1a-...", "7b4c9e0f-..."],
  "message":   "Hi! Your statement is ready. Log in at app.example.com",
  "sender_id": "TALKNTALK"
}
FieldTypeRequiredDescription
group_idsstring[]YesAddress book UUIDs — from List Address Books. One or more.
messagestringYesSMS body sent to every contact in the selected books
sender_idstringNoSender name shown on device. Defaults to your organisation's default sender ID.

Get your address book IDs from GET /v1/address-books/ — use the id field of each book.


Request

curl -X POST https://api.talkntalk.africa/v1/sms/send-group/ \
  -H "Authorization: Bearer tk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "group_ids": ["3f8e2d1a-7c4d-4e1a-b3f2-9d8e2c1a4b5f"],
    "message":   "Your monthly statement is ready.",
    "sender_id": "TALKNTALK"
  }'

Response

202 Accepted — campaign queued for delivery

{
  "campaign_id":      84,
  "status":           "queued",
  "recipients_count": 1248,
  "group_names":      ["Premium Customers"],
  "sender_id":        "TALKNTALK",
  "estimated_cost":   "KES 1248.00"
}
FieldDescription
campaign_idInternal campaign ID — for tracking via the dashboard
statusqueued — contacts are being dispatched
recipients_countTotal unique contacts resolved across all selected books
group_namesNames of the address books included in this send
estimated_costPre-calculated cost based on recipient count and current SMS pricing

Code Examples

Node.js

// 1. Get address book IDs
const books = await fetch('https://api.talkntalk.africa/v1/address-books/', {
  headers: { Authorization: 'Bearer tk_live_xxxx' },
}).then(r => r.json());
 
const groupIds = books.results.map(b => b.id); // or pick specific ones
 
// 2. Send to all books
const res = await fetch('https://api.talkntalk.africa/v1/sms/send-group/', {
  method:  'POST',
  headers: { Authorization: 'Bearer tk_live_xxxx', 'Content-Type': 'application/json' },
  body:    JSON.stringify({
    group_ids: groupIds,
    message:   'Hello! Your invoice is ready.',
    sender_id: 'TALKNTALK',
  }),
});
const campaign = await res.json();
console.log(`Queued ${campaign.recipients_count} messages — cost ${campaign.estimated_cost}`);

Python

import requests
 
API_KEY = 'tk_live_xxxx'
HEADERS = {'Authorization': f'Bearer {API_KEY}'}
 
# 1. Get address book IDs
books = requests.get('https://api.talkntalk.africa/v1/address-books/', headers=HEADERS).json()
group_ids = [b['id'] for b in books['results']]  # or filter by name
 
# 2. Send campaign
r = requests.post(
    'https://api.talkntalk.africa/v1/sms/send-group/',
    headers=HEADERS,
    json={
        'group_ids': group_ids,
        'message':   'Hello! Your invoice is ready.',
        'sender_id': 'TALKNTALK',
    },
)
campaign = r.json()
print(f"Queued {campaign['recipients_count']} messages | {campaign['estimated_cost']}")

PHP

$apiKey = 'tk_live_xxxx';
 
// 1. Get address book IDs
$ch = curl_init('https://api.talkntalk.africa/v1/address-books/');
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ["Authorization: Bearer {$apiKey}"]]);
$books    = json_decode(curl_exec($ch), true);
$groupIds = array_column($books['results'], 'id');
curl_close($ch);
 
// 2. Send campaign
$ch = curl_init('https://api.talkntalk.africa/v1/sms/send-group/');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => ["Authorization: Bearer {$apiKey}", 'Content-Type: application/json'],
    CURLOPT_POSTFIELDS     => json_encode([
        'group_ids' => $groupIds,
        'message'   => 'Hello! Your invoice is ready.',
        'sender_id' => 'TALKNTALK',
    ]),
]);
$campaign = json_decode(curl_exec($ch), true);
echo "Queued {$campaign['recipients_count']} messages | {$campaign['estimated_cost']}";

Tracking your campaign

Use the campaign_id returned in the response to monitor delivery:

What you needEndpoint
Overall progress (sent, failed, delivery rate)Campaign Status
Per-recipient delivery statusCampaign Messages

Error Responses

StatusDescription
400 Bad Requestgroup_ids is empty, message is missing, no contacts with phone numbers, or scheduled_at is in the past
401 UnauthorizedMissing or invalid API key
402 Payment RequiredInsufficient wallet balance
404 Not FoundNo matching address books found for the provided IDs
429 Too Many RequestsRate limit exceeded — see Rate Limits