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:
| Field | Value |
|---|---|
| Name | Vonage SMS |
| Username | The API key |
| Password | The API secret |

Next, create an outgoing REST connection under Connections → Outgoing → REST:
| Field | Value | Notes |
|---|---|---|
| Name | Vonage SMS | --- |
| Host | https://api.nexmo.com | --- |
| URL path | /v1/messages | --- |
| Data format | JSON | --- |
| Security | Basic Auth/Vonage SMS | The definition just created |

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:
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
| Page | What it covers |
|---|---|
| Your first SMS | One service that every other service sends text messages through |
| Basic Auth | Every field of a Basic Auth definition |
| Calling external REST APIs | Parameters, headers and the response object of a REST call |