Africa's Talking

Send text messages through the Africa's Talking SMS API from an outgoing REST connection, in the sandbox or live.

This page will show you how to send text messages through Africa's Talking from Python:

  • What to collect from the Africa's Talking dashboard
  • Which security definition and outgoing REST connection to create
  • How to send a message from a service and read the response
  • How to test in the sandbox

Collecting Africa's Talking config

You'll need three details from the Africa's Talking dashboard:

  • The username of the app, which is sandbox in the sandbox
  • An API key, generated in the app's Settings → API Key
  • Optionally, the sender, which is a sender ID or a short code registered with the account - without one, messages go out from the default sender of the account

Creating Zato connections

First, create an API key definition under Security → API keys. Africa's Talking expects the key in the apiKey header:

FieldValue
NameAfrica's Talking SMS
HeaderapiKey
API keyThe API key
API key for Africa's Talking

Next, create an outgoing REST connection under Connections → Outgoing → REST:

FieldValueNotes
NameAfrica's Talking SMS---
Hosthttps://api.africastalking.comhttps://api.sandbox.africastalking.com in the sandbox
URL path/version1/messaging---
Data formatForm data---
Content typeapplication/x-www-form-urlencoded---
SecurityAPI key/Africa's Talking SMSThe definition just created
REST connection to Africa's Talking

Sending a message

The service below will:

  • Build the message from the input it received
  • Send it to Africa's Talking, asking for a JSON response
  • Return the ID the message received and its status
# -*- coding: utf-8 -*-

# stdlib
from http import HTTPStatus

# Zato
from zato.server.service import Service

class SendAfricasTalkingSMS(Service):

    name = 'sms.africas-talking.send'
    input = 'to', 'text'

    def handle(self):

        input = self.request.input

        # The message in the format of Africa's Talking ..
        message = {
            'username': 'riverside',
            'to': input.to,
            'message': input.text,
            'from': 'RIVERSIDE',
        }

        # .. without this header, the response is XML ..
        headers = {'Accept': 'application/json'}

        # .. get the connection to Africa's Talking ..
        conn = self.rest["Africa's Talking SMS"]

        # .. send the message ..
        response = conn.post(message, headers=headers)

        # .. make sure the request was accepted ..
        if not response.ok:
            reason = response.text
            raise Exception(f"Africa's Talking error: {reason}")

        # .. there is one result for each recipient ..
        message_data = response.data['SMSMessageData']
        recipients = message_data['Recipients']
        recipient = recipients[0]

        # .. a rejected recipient has a code of the 4xx or 5xx class ..
        if recipient['statusCode'] >= HTTPStatus.BAD_REQUEST:
            number = recipient['number']
            status = recipient['status']
            raise Exception(f'Rejected {number}: {status}')

        # .. and tell our caller what Africa's Talking said.
        self.response.payload = {
            'message_id': recipient['messageId'],
            'status': recipient['status'],
            'cost': recipient['cost'],
        }

After invoking the service you'll see:

{
  "message_id": "ATXid_4f7a2c9e1b3d5f6a8c0e2b4d6f8a1c3e",
  "status": "Success",
  "cost": "KES 0.8000"
}

The to field can also be several numbers separated by commas, in which case Recipients has one result for each of them.

Status codes

Each recipient in the response has a statusCode and a status:

Status codeStatusMeaning
100ProcessedAccepted
101SuccessAccepted and sent
102QueuedAccepted and waiting to go out
401RiskHoldHeld for review
402InvalidSenderIdThe sender is not registered with the account
403InvalidPhoneNumberThe number is not valid
405InsufficientBalanceThe account has no credit left
406UserInBlacklistThe recipient has opted out of messages

Testing in the sandbox

The sandbox accepts messages as the live API does, but it does not deliver them, and nothing is charged for. The messages sent appear in the simulator of the Africa's Talking dashboard, which acts as a phone with the number the message was sent to.

To use it, create a second API key definition and REST connection, with:

  • The API key generated in the sandbox app
  • The host set to https://api.sandbox.africastalking.com
  • sandbox as the username in the message

See also

PageWhat it covers
Your first SMSOne service that every other service sends text messages through
API keysEvery field of an API key definition, including the header it is sent in
Calling external REST APIsParameters, headers and the response object of a REST call

Learn more