SMS
Campaign Messages

Campaign Messages

Fetch the per-recipient delivery status for every message in a bulk SMS campaign. Use this to see exactly which numbers were delivered, failed, or are still pending.


Endpoint

POST /v1/sms/campaigns/messages/

Authentication: Bearer API key


Request Body

{
  "campaign_id": "44210c48-5ba9-4784-b434-dd57bf1d2b46",
  "status":      "failed",
  "page":        1,
  "page_size":   100
}
FieldTypeRequiredDescription
campaign_idUUID stringYesThe campaign_id returned when you sent the bulk campaign
statusstringNoFilter by recipient status: queued, sent, failed. Omit to return all.
pageintegerNoPage number (default: 1)
page_sizeintegerNoResults per page (default: 100, max: 1000)

Request

curl -X POST https://api.talkntalk.africa/v1/sms/campaigns/messages/ \
  -H "Authorization: Bearer tk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "campaign_id": "44210c48-5ba9-4784-b434-dd57bf1d2b46",
    "page_size": 50
  }'

Response

200 OK

{
  "campaign_id":      "44210c48-5ba9-4784-b434-dd57bf1d2b46",
  "campaign_status":  "completed",
  "recipients_count": 1248,
  "sent_count":       1245,
  "failed_count":     3,
  "delivery_rate":    99.8,
  "total":            1248,
  "page":             1,
  "page_size":        50,
  "total_pages":      25,
  "next":             "https://api.talkntalk.africa/v1/sms/campaigns/messages/?page=2&page_size=50",
  "previous":         null,
  "results": [
    {
      "mobile":         "254712345678",
      "status":         "sent",
      "message_id":     "018f3a2b-7c4d-7e1a-b3f2-9d8e2c1a4b5f",
      "message_status": "delivered",
      "error":          null,
      "sent_at":        "2026-05-20T11:01:14+03:00"
    },
    {
      "mobile":         "254799999999",
      "status":         "failed",
      "message_id":     "019a4b3c-8d5e-8f2b-c4a3-0e9f3d2b5c6g",
      "message_status": "failed",
      "error":          "Number not reachable",
      "sent_at":        "2026-05-20T11:01:15+03:00"
    }
  ]
}

Top-level fields

FieldDescription
campaign_idUUID of the campaign
campaign_statusOverall campaign state (queued, running, completed, failed)
recipients_countTotal recipients
sent_countSuccessfully dispatched
failed_countFailed to send
delivery_ratePercentage delivered
totalTotal rows matching the filter
next / previousPagination URLs

Per-recipient fields (results[])

FieldDescription
mobileRecipient phone number
statusCampaign dispatch status: queued / sent / failed
message_idUUID of the individual SMS — use with Fetch Messages for more detail
message_statusProvider delivery status: queuedsentdelivered / failed / undelivered
errorError description if message_status is failed, otherwise null
sent_atTimestamp of the last status update

status vs message_status: status tells you whether the campaign worker dispatched the number. message_status is the real delivery confirmation from the network — this is the field to watch.


Code Examples

Fetch all failed recipients

// Node.js
const res = await fetch('https://api.talkntalk.africa/v1/sms/campaigns/messages/', {
  method:  'POST',
  headers: { 'Authorization': 'Bearer tk_live_xxxx', 'Content-Type': 'application/json' },
  body:    JSON.stringify({
    campaign_id: '44210c48-5ba9-4784-b434-dd57bf1d2b46',
    status:      'failed',
    page_size:   1000,
  }),
});
const data = await res.json();
console.log(`Failed: ${data.failed_count}`);
data.results.forEach(r => console.log(r.mobile, '—', r.error));
# Python — iterate all pages
import requests
 
API_KEY     = 'tk_live_xxxx'
CAMPAIGN_ID = '44210c48-5ba9-4784-b434-dd57bf1d2b46'
 
page = 1
while True:
    r = requests.post(
        'https://api.talkntalk.africa/v1/sms/campaigns/messages/',
        headers={'Authorization': f'Bearer {API_KEY}'},
        json={'campaign_id': CAMPAIGN_ID, 'page': page, 'page_size': 500},
    )
    data = r.json()
    for recipient in data['results']:
        print(recipient['mobile'], recipient['message_status'])
    if not data['next']:
        break
    page += 1

Error Responses

StatusDescription
400 Bad Requestcampaign_id missing
401 UnauthorizedMissing or invalid API key
404 Not FoundCampaign not found or does not belong to your organisation