# 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 {#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 {#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 |

![Basic Auth for Vonage](https://zatosource-production.b-cdn.net/docs/gfx/sms/send/vonage-basic-auth-create.webp?v=1791646789)

Dashboard menu: Security > Basic Auth

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 |

![REST connection to Vonage](https://zatosource-production.b-cdn.net/docs/gfx/sms/send/vonage-rest-create.webp?v=1791646792)

Dashboard menu: Connections > Outgoing > REST

## Sending a message {#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

```python
# -*- 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:

```json
{"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 {#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.:

```json
{
  "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 {#see-also}

- [Your first SMS](https://zato.io/docs/dev/examples/sms/send/tutorial.html) - One service that every other service sends text messages through
- [Basic Auth](https://zato.io/docs/security/basic-auth.html) - Every field of a Basic Auth definition
- [Calling external REST APIs](https://zato.io/docs/dev/rest/calling-apis.html) - Parameters, headers and the response object of a REST call

## Learn more {#learn-more}

- [Development documentation](https://zato.io/docs/dev/) - Everything about writing services, in one place
- [Requests and responses](https://zato.io/docs/dev/request-response/) - What a service receives, what it returns and how to shape both
- [Integration examples](https://zato.io/docs/dev/examples/) - Ready-made code for the systems you are likely to connect to
- [IDE and debugging](https://zato.io/docs/dev/ide/) - Write services in the Dashboard or in your own editor
- [Data models](https://zato.io/docs/dev/model/) - Declare inputs and outputs and have them validated for you
- [In-depth API tutorial](https://zato.io/tutorials/main/01.html) - The full platform tutorial, from installation to production patterns
