Skip to main content
Get started with Africa’s Talking AI integration by sending an SMS and making a voice call. This guide assumes you’ve already completed the setup.

Prerequisites

Before you begin, make sure you have:
  • Completed the environment setup
  • Flask server running on http://localhost:9000
  • Valid Africa’s Talking credentials in your .env file
  • A phone number to test with (in international format: +254XXXXXXXXX)

Send Your First SMS

The SMS API allows you to send bulk SMS messages to one or more recipients using a simple GET request.
1

Start your Flask server

Make sure your Flask application is running:
make dev
You should see output confirming the server is running:
✅ Registered sms at /api/sms
✅ Registered voice at /api/voice
* Running on http://127.0.0.1:9000
2

Send an SMS via the API

Use curl or your browser to send an SMS. Replace YOUR_PHONE_NUMBER with your actual phone number:
curl "http://localhost:9000/api/sms/invoke-bulk-sms?phone=254712345678&message=Hello%20from%20Africa%27s%20Talking!"
The phone parameter should be in international format without the + symbol (e.g., 254712345678 for Kenya).
3

Check the response

You should receive a JSON response confirming the SMS was sent:
{
  "message": "SMS sent to +254712345678",
  "response": {
    "SMSMessageData": {
      "Message": "Sent to 1/1 Total Cost: KES 0.8000",
      "Recipients": [
        {
          "statusCode": 101,
          "number": "+254712345678",
          "status": "Success",
          "cost": "KES 0.8000",
          "messageId": "ATXid_abc123def456ghi789"
        }
      ]
    }
  }
}
A status code of 101 means the message was sent successfully. Check your phone for the SMS!

How it Works

The SMS endpoint is defined in routes/sms.py:13-31:
@sms_bp.route("/invoke-bulk-sms", methods=["GET"])
def invoke_bulk_sms():
    phone = "+" + request.args.get("phone", "").strip()
    message = request.args.get("message", "Hello from Africa's Talking!").strip()

    if not phone:
        return {"error": "Missing 'phone' query parameter"}, 400

    try:
        response = send_bulk_sms(message, [phone])
        return {"message": f"SMS sent to {phone}", "response": response}
    except Exception as e:
        return {"error": str(e)}, 500
The send_bulk_sms() function from utils/sms_utils.py:55-75 handles the actual API call:
def send_bulk_sms(message: str, recipients: List[str]) -> Dict[str, Any]:
    if not recipients:
        raise ValueError("Recipients list cannot be empty")

    try:
        response = _sms.send(message, recipients)
        print(f"📩 Bulk SMS sent to {len(recipients)} recipients")
        return response
    except Exception as e:
        print(f"❌ Bulk SMS failed: {e}")
        raise

Make Your First Voice Call

The Voice API allows you to initiate outbound calls programmatically.
1

Ensure your voice number is configured

Verify that AT_VOICE_NUMBER is set in your .env file:
AT_VOICE_NUMBER=+254XXXXXXXXX
Voice calls require a production Africa’s Talking account with a voice-enabled number. The sandbox does not support voice calls.
2

Initiate a voice call

Use curl or your browser to make a call. Replace YOUR_PHONE_NUMBER with the recipient’s number:
curl "http://localhost:9000/api/voice/invoke-call?phone=254712345678"
3

Check the response

You should receive a confirmation that the call was initiated:
{
  "message": "Call initiated to +254712345678",
  "response": {
    "entries": [
      {
        "status": "Queued",
        "phoneNumber": "+254712345678"
      }
    ],
    "errorMessage": "None"
  }
}
The recipient should receive a call shortly. When they answer, they’ll hear the message configured in your /api/voice/instruct webhook.
4

Answer the call

When the call is answered, Africa’s Talking will POST to your /api/voice/instruct endpoint to get instructions. The default implementation plays a greeting:
<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Say>Welcome to the service. This is a demo voice application. Goodbye.</Say>
</Response>
You can customize the voice instructions in routes/voice.py:32-56 to create interactive voice menus, collect DTMF input, or play audio files.

How it Works

The voice call endpoint is defined in routes/voice.py:12-29:
@voice_bp.route("/invoke-call", methods=["GET"])
def make_voice_call():
    phone = "+" + request.args.get("phone", "").strip()

    if not phone:
        return {"error": "Missing 'phone' query parameter"}, 400

    try:
        response = make_call(phone)
        return {"message": f"Call initiated to {phone}", "response": response}
    except Exception as e:
        return {"error": str(e)}, 500
The make_call() function from utils/voice_utils.py:20-45 handles the API call:
def make_call(
    phone_number: str, from_number: Optional[str] = AT_VOICE_NUMBER
) -> Dict[str, Any]:
    if not phone_number.startswith("+"):
        raise ValueError(
            f"Invalid phone number format: {phone_number}. Must be in +2547... format"
        )

    try:
        response = _voice.call(callTo=[phone_number], callFrom=from_number)
        print(f"📞 Call initiated to {phone_number}")
        return response
    except Exception as e:
        print(f"❌ Call failed to {phone_number}: {e}")
        raise

Understanding Webhooks

Both SMS and Voice APIs use webhooks to send you real-time notifications about events:

SMS Webhooks

  • Delivery Reports (POST /api/sms/delivery-reports) - Notifies you when an SMS is delivered or fails
  • Two-Way SMS (POST /api/sms/twoway) - Receives incoming SMS messages sent to your shortcode

Voice Webhooks

  • Call Instructions (POST /api/voice/instruct) - Provides XML instructions when a call is answered
  • Call Events (POST /api/voice/events) - Receives events like call started, ended, failed, etc.
To receive webhooks locally, you need to expose your Flask server to the internet using a tunneling tool like ngrok. See the Setup Guide for details.

Next Steps

Now that you’ve sent your first SMS and made your first call, you can:

Explore SMS Features

Learn about two-way SMS, delivery reports, and premium SMS subscriptions

Build Voice Apps

Create interactive voice menus, record calls, and handle DTMF input

Integrate AI

Use Google Gemini to add AI-powered responses to SMS and voice interactions

Troubleshooting

Resolve common issues and errors

Common Issues

Make sure you’re passing the phone parameter in the URL:
# ✅ Correct
curl "http://localhost:9000/api/sms/invoke-bulk-sms?phone=254712345678&message=Hello"

# ❌ Incorrect (missing phone parameter)
curl "http://localhost:9000/api/sms/invoke-bulk-sms?message=Hello"
Ensure your .env file contains valid credentials:
AT_USERNAME=sandbox  # or your production username
AT_API_KEY=your_actual_api_key_here
AT_VOICE_NUMBER=+254XXXXXXXXX  # for voice calls only
Restart your Flask server after updating the .env file.
  • Check that the phone number is in the correct format (254XXXXXXXXX without the +)
  • Verify you have sufficient credits in your Africa’s Talking account
  • Check the API response for error messages
  • Ensure you’re using a valid destination number (some countries/networks may be restricted)
  • Voice calls require a production account (sandbox doesn’t support voice)
  • Verify AT_VOICE_NUMBER is set and is a valid voice-enabled number
  • Check that you have sufficient credits for voice calls
  • Ensure your webhook URLs are configured in the Africa’s Talking dashboard

Build docs developers (and LLMs) love