Twilio

Send text messages through the Twilio Programmable Messaging API from an outgoing REST connection.

This page will show you how to send text messages through Twilio from Python:

  • What to collect from the Twilio console
  • Which security definition and outgoing REST connection to create
  • How to send a message from a service and read Twilio's response

Collecting Twilio config

You'll need three details from the Twilio console:

  • The Account SID, which is AC followed by 32 hexadecimal characters, in the Account Info section of the console's home page
  • The auth token, in the same section
  • The sender, which is a phone number of the account in E.164 form, such as +12025550100, or the SID of a Messaging Service, which begins with MG

Creating Zato connections

First, create a Basic Auth definition under Security → Basic Auth - Twilio signs in each request with the Account SID as the username and the auth token as the password:

FieldValue
NameTwilio SMS
UsernameThe Account SID
PasswordThe auth token
Basic Auth for Twilio

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

FieldValueNotes
NameTwilio SMS---
Hosthttps://api.twilio.com---
URL path/2010-04-01/Accounts/<Account SID>/Messages.jsonWith the Account SID copied earlier
Data formatForm data---
Content typeapplication/x-www-form-urlencoded---
SecurityBasic Auth/Twilio SMSThe definition just created
REST connection to Twilio

Sending a message

The service below will:

  • Build the message from the input it received
  • Send it to Twilio
  • Return the ID Twilio gave the message and its status
# -*- coding: utf-8 -*-

# Zato
from zato.server.service import Service

class SendTwilioSMS(Service):

    name = 'sms.twilio.send'
    input = 'to', 'text'

    def handle(self):

        input = self.request.input

        # The message in Twilio's format ..
        message = {
            'To': input.to,
            'From': '+12025550100',
            'Body': input.text,
        }

        # .. get the connection to Twilio ..
        conn = self.rest['Twilio SMS']

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

        # .. make sure Twilio accepted it ..
        if not response.ok:
            code = response.data['code']
            reason = response.data['message']
            raise Exception(f'Twilio error {code}: {reason}')

        # .. and tell our caller what Twilio said.
        self.response.payload = {
            'message_id': response.data['sid'],
            'status': response.data['status'],
        }

After invoking the service you'll see:

{"message_id": "SM9f2c5a1e8b7d4c3a2f1e0d9c8b7a6f5e", "status": "queued"}

Twilio answers with 201 Created and the message in the queued status, which means it has been accepted and is waiting to go out to the carrier.

Sending through a Messaging Service

A Messaging Service holds a pool of the account's numbers and chooses the one each message goes out from. To send through it, replace From with MessagingServiceSid:

message = {
    'To': input.to,
    'MessagingServiceSid': 'MG2d8f4b6a1c3e5f7a9b0c2d4e6f8a1b3c',
    'Body': input.text,
}

Errors

When Twilio does not accept a message, it answers with a 4xx status and a JSON body whose code and message say why, e.g.:

{
  "code": 21211,
  "message": "Invalid 'To' Phone Number: +1202555",
  "status": 400
}

The service above turns such a response into an exception with the code and the message, and the code is described in Twilio's error dictionary.

Test credentials

The Twilio console also has a test Account SID and a test auth token, under Account → API keys and tokens. Messages sent with them are accepted or rejected as with real credentials, but they are not delivered and they are not charged for.

To use them, create a second Basic Auth definition and REST connection with the test credentials, and send from +15005550006. The recipient decides the outcome:

RecipientOutcome
+15005550006Accepted, with a message ID returned
+15005550001Rejected with error 21211, an invalid number
+15005550009Rejected with error 21614, a number that cannot receive SMS

See also

PageWhat it covers
Your first SMSOne service that every other service sends text messages through
Basic AuthEvery field of a Basic Auth definition
Calling external REST APIsParameters, headers and the response object of a REST call

Learn more