Vonage

Send text messages (SMS) with Vonage

infobip.svg

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

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

Collecting Vonage config

You'll need three details from the Vonage API dashboard:

  • The API key, on the dashboard's home page
  • The API secret, on the same page
  • The sender, which is a virtual number of the account, such as 12025550100, or an alphanumeric sender ID in the lands that permit one

Creating Zato connections

First, create a Basic Auth definition under Security → Basic Auth - the Messages API signs in each request with the API key as the username and the API secret as the password:

FieldValue
NameVonage SMS
UsernameThe API key
PasswordThe API secret
Basic Auth for Vonage

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

FieldValueNotes
NameVonage SMS---
Hosthttps://api.nexmo.com---
URL path/v1/messages---
Data formatJSON---
SecurityBasic Auth/Vonage SMSThe definition just created
REST connection to Vonage

Sending a message

The service below will:

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

# Zato
from zato.server.service import Service

class SendVonageSMS(Service):

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

    def handle(self):

        input = self.request.input

        # The message in Vonage's format ..
        message = {
            'message_type': 'text',
            'channel': 'sms',
            'to': input.to,
            'from': '12025550100',
            'text': input.text,
        }

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

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

        # .. make sure Vonage accepted it ..
        if not response.ok:
            title = response.data['title']
            detail = response.data['detail']
            raise Exception(f'Vonage error {title}: {detail}')

        # .. and tell our caller the ID of the message.
        message_id = response.data['message_uuid']
        self.response.payload = {'message_id': message_id}

Numbers go to Vonage in E.164 form without the leading +, so the service is invoked with {"to": "12025550123", "text": "Your appointment is tomorrow at 9:00"}.

After invoking the service you'll see:

{"message_id": "aaaaaaaa-bbbb-4ccc-8ddd-0123456789ab"}

Vonage answers with 202 Accepted and the UUID of the message, which means it has been accepted for delivery.

Errors

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

{
  "type": "https://developer.vonage.com/api-errors#unauthorized",
  "title": "Unauthorized",
  "detail": "You did not provide correct credentials.",
  "instance": "bf0ca0bf927b3b52e3cb03217e1a1ddf"
}

The service above converts such a response to an exception containing the title and the detail.

See also

PageWhat it covers
How to send text messages (SMS)Send every text from one service, so a change of provider later means editing that service alone
TwilioSend through Twilio and test for free with credentials that never deliver or charge for a message
InfobipTell everyone at once - one request sends the same text to any number of recipients
Africa's TalkingTry every message for free in a sandbox that shows it on a simulated phone instead of delivering it
Basic AuthKeep the username and password out of your code - Zato adds them to every request the connection makes
Calling external REST APIsCall any other REST API the same way, with parameters, headers and status checks

Learn more