Vonage

Send text messages through the Vonage Messages API from an outgoing REST connection.

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 countries 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 turns such a response into an exception with the title and the detail.

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