# Outbound SMS API reference

Use this reference to look up how to authenticate Outbound SMS API requests,
which endpoints and headers to use, and the attributes of single and bulk
SMS requests and their responses.

## Authentication, IP restrictions and headers

API requests are secured with two layers: IP address restriction and HTTP
Basic Authentication. Both must be valid for a request to succeed.

### IP address restriction

The **Allowed IP addresses** setting of the [HTTP OUT trunk](../sms-trunks/http-out/http-out-trunk.html) defines the IP
addresses from
which the API accepts requests. The API rejects requests from any other
source. When the setting is empty, requests from all IP addresses are
allowed. See [General
settings](../sms-trunks/http-out/http-out-trunk-settings-reference.html#user-panel-sms-http-out-general-settings).

### Basic Authentication

After IP validation, the API checks your credentials with **HTTP Basic
Authentication**. Use the **Username** and **Password** from the trunk's
[credentials](../sms-trunks/http-out/how-to-guides/view-http-out-trunk-credentials.html).
The following tabs show two ways to provide credentials in a cURL command.

*Simple example (cURL shortcut)*

The `-u` flag combines your username and password, encodes them in
Base64, and adds the required `Authorization` header.

```
curl -u username:password \
  -X POST \
  -H "Content-Type: application/vnd.api+json" \
  https://sms-out.didww.com/outbound_messages \
  -d '{
    "data": {
      "type": "outbound_messages",
      "attributes": {
        "destination": "15551234567",
        "source": "12125551234",
        "content": "Hello World!"
      }
    }
  }'
```


*Manual header construction*

This method shows what the `-u` flag does behind the scenes.

1. Combine the credentials: `username:password`
2. Encode the string in Base64: `dXNlcm5hbWU6cGFzc3dvcmQ=`
3. Add the result as an `Authorization` header:
   `Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=`

```
curl -X POST \
  -H "Content-Type: application/vnd.api+json" \
  -H "Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=" \
  https://sms-out.didww.com/outbound_messages \
  -d '{
    "data": {
      "type": "outbound_messages",
      "attributes": {
        "destination": "15551234567",
        "source": "12125551234",
        "content": "Hello World!"
      }
    }
  }'
```

Replace `username` and `password` with the credentials of your
HTTP OUT trunk before you encode them.

### Request headers

| Header | Value |
| --- | --- |
| `Content-Type` | `application/vnd.api+json`. Requests with another media type return `415 Unsupported Media Type`. |
| `Authorization` | `Basic <b64_value>`, where `<b64_value>` is the Base64-encoded `username:password` string of the trunk credentials. |

## Endpoints

All API requests use the `POST` method and must be sent to a valid API
endpoint with the required headers.

| Component | Value |
| --- | --- |
| Global endpoint | `https://sms-out.didww.com`. Use it for general-purpose requests. |
| Regional endpoints | Use a regional endpoint for potentially lower latency:   - `https://us.sms-out.didww.com` (US, NY) - `https://eu.sms-out.didww.com` (NL, AMS) - `https://nyc.us.sms-out.didww.com` (US, NY) - `https://mia.us.sms-out.didww.com` (US, MIA) - `https://lac.us.sms-out.didww.com` (US, LA) - `https://sg.sms-out.didww.com` (SG) |
| Request paths | Append to your chosen endpoint:   - Single SMS: `/outbound_messages` - Bulk SMS: `/bulk_outbound_messages` |

HTTP OUT trunks have no location setting. The trunk's
[credentials](../sms-trunks/http-out/how-to-guides/view-http-out-trunk-credentials.html)
list the endpoints for each DIDWW location:
`https://us.sms-out.didww.com/outbound_messages` for **US, NY** and
`https://eu.sms-out.didww.com/outbound_messages` for **NL, AMS**. To use a
location, send your requests to its endpoint.

## Single-message requests

Send one message with `POST /outbound_messages` and the
`outbound_messages` resource type. A successful request returns
`201 Created` with the ID of the message.

*Single SMS*

Note

When `source` contains a Sender ID from the registered Sender ID
Verification, `campaign_id` is not required.

http

```
 1POST /outbound_messages HTTP/1.1
 2Host: sms-out.didww.com
 3Content-Type: application/vnd.api+json
 4Authorization: Basic
 5
 6{
 7  "data": {
 8    "type": "outbound_messages",
 9    "attributes": {
10      "destination": "37041654321",
11      "source": "37041123456",
12      "content": "Hello World!"
13    }
14  }
15}
```

curl

```
1curl -i -X POST https://sms-out.didww.com/outbound_messages -H "Content-Type: application/vnd.api+json" -H "Authorization: Basic" --data-raw '{"data": {"attributes": {"content": "Hello World!", "destination": "37041654321", "source": "37041123456"}, "type": "outbound_messages"}}'
```

response

```
1HTTP/1.1 201 Created
2Content-Type: application/vnd.api+json
3
4{
5  "data": {
6    "type": "outbound_messages",
7    "id": "550e8400-e29b-41d4-a716-446655440000"
8  }
9}
```


*Single SMS without source*

Note

When `campaign_id` is provided and `source` is omitted, DIDWW
randomly selects one of the Sender IDs registered under that Sender
ID Verification. In the DIDWW User Panel, the value used for
`campaign_id` is displayed as **Campaign ID** on the verification
details page. See [Sender ID Verification
fields](../sender-id-verifications/sender-id-verification-reference.html#sender-id-verification-fields).

http

```
 1POST /outbound_messages HTTP/1.1
 2Host: sms-out.didww.com
 3Content-Type: application/vnd.api+json
 4Authorization: Basic
 5
 6{
 7  "data": {
 8    "type": "outbound_messages",
 9    "attributes": {
10      "destination": "37041654321",
11      "content": "Hello World!",
12      "campaign_id": "1111aaaa-1a1a-41a1-aaaa-11aaaaa11111"
13    }
14  }
15}
```

curl

```
1curl -i -X POST https://sms-out.didww.com/outbound_messages -H "Content-Type: application/vnd.api+json" -H "Authorization: Basic" --data-raw '{"data": {"attributes": {"campaign_id": "1111aaaa-1a1a-41a1-aaaa-11aaaaa11111", "content": "Hello World!", "destination": "37041654321"}, "type": "outbound_messages"}}'
```

response

```
1HTTP/1.1 201 Created
2Content-Type: application/vnd.api+json
3
4{
5  "data": {
6    "type": "outbound_messages",
7    "id": "550e8400-e29b-41d4-a716-446655440000"
8  }
9}
```

## Bulk-message requests

Send the same message to several destination numbers with
`POST /bulk_outbound_messages` and the `bulk_outbound_messages` resource
type. The response contains the ID of the bulk request and one
`outbound_messages` ID for each destination.

http

```
 1POST /bulk_outbound_messages HTTP/1.1
 2Host: sms-out.didww.com
 3Content-Type: application/vnd.api+json
 4Authorization: Basic
 5
 6{
 7  "data": {
 8    "type": "bulk_outbound_messages",
 9    "attributes": {
10      "destination": ["37041654321", "37041654322"],
11      "source": "37041123456",
12      "content": "Hello World!"
13    }
14  }
15}
```

curl

```
1curl -i -X POST https://sms-out.didww.com/bulk_outbound_messages -H "Content-Type: application/vnd.api+json" -H "Authorization: Basic" --data-raw '{"data": {"attributes": {"content": "Hello World!", "destination": ["37041654321", "37041654322"], "source": "37041123456"}, "type": "bulk_outbound_messages"}}'
```

response

```
 1HTTP/1.1 201 Created
 2Content-Type: application/vnd.api+json
 3
 4{
 5  "data": {
 6    "type": "bulk_outbound_messages",
 7    "id": "2C4807D1-74E4-4639-BBC4-057402F052FF",
 8    "relationships": {
 9      "outbound_messages": {
10        "data": [
11          {"type": "outbound_messages", "id": "E34C1810-434B-4E64-AFD9-EC0568F324A9"},
12          {"type": "outbound_messages", "id": "B6A48E34-3219-407D-99E6-770CF524F611"}
13        ]
14      }
15    }
16  }
17}
```

## Request attributes and response fields

### Request attributes

If a required attribute is missing or has an invalid format, the API returns
`400 Bad Request`. See [HTTP and API errors](outbound-sms-errors-and-status-codes.html#sms-out-spec-errors).

| Attribute | Availability | Description |
| --- | --- | --- |
| `destination` | Required | The recipient's number in E.164 format, digits only, without the leading `+`. For example, `15551234567`. For bulk requests, use an array of numbers. A bulk request can contain up to 1000 numbers.  Note  If the destination region is not in your pricelist, you receive a callback with [code\_id 2](outbound-sms-errors-and-status-codes.html#callback-error-codes-http). |
| `source` | Conditional | The DID number or Sender ID to use as the sender. Required unless `campaign_id` is provided.  Note  The API accepts the request before it checks the sender. If the trunk cannot use the sender, the message is not sent and you receive a callback with [code\_id 8](outbound-sms-errors-and-status-codes.html#callback-error-codes-http). A DID number must be allowed in the trunk's [Source Address Settings](../sms-trunks/http-out/http-out-trunk-settings-reference.html#user-panel-sms-http-out-trunk-source-address-settings). A Sender ID must be covered by an active Sender ID Verification associated with the trunk. |
| `content` | Required | The message text in UTF-8. It cannot be empty. A single GSM-7 SMS holds up to 160 characters. Longer messages are sent as several fragments. See [SMS encoding reference](../sms-trunks/technical-data/sms-encoding-reference.html). |
| `campaign_id` | Conditional | The Campaign ID of an active [Sender ID Verification](../sender-id-verifications/index.html#user-panel-sms-campaign). Required when `source` is omitted. DIDWW then selects one of the Sender IDs registered under that verification. An unknown Campaign ID is reported in the callback with [code\_id 10](outbound-sms-errors-and-status-codes.html#callback-error-codes-http). |

### Response fields

| Field | Description |
| --- | --- |
| `data.type` | The resource type: `outbound_messages` for a single message or `bulk_outbound_messages` for a bulk request. |
| `data.id` | The ID of the message or the bulk request. The status callback for a message uses the same message ID. |
| `data.relationships.outbound_messages.data` | Bulk requests only. The list of the `outbound_messages` created for the request, each with its own `id`. |

## Limits and formats

| Limit or format | Value |
| --- | --- |
| Rate limit | The maximum request rate for HTTP OUT trunks is 10 requests per second (RPS). If this limit is exceeded, the API returns a [429 Too Many Requests](outbound-sms-errors-and-status-codes.html#sms-out-spec-errors) error. |
| Destinations per bulk request | Up to 1000 numbers. A request with more numbers returns `400 Bad Request`. |
| Number format | E.164, digits only, without the leading `+`. For example, `15551234567`. |
| Message text | UTF-8. The number of fragments depends on the encoding and length. See [SMS encoding reference](../sms-trunks/technical-data/sms-encoding-reference.html). |
| Request format | [JSON:API](https://jsonapi.org/format/) with the `application/vnd.api+json` media type. |

## Related resources

- [Send your first SMS with the API](send-your-first-sms-with-api.html) - Send a single message with cURL.
- [Send bulk SMS with the API](send-bulk-sms-with-api.html) - Send one message to many destination
  numbers.
- [Status callbacks and delivery receipts](status-callbacks-and-delivery-receipts.html) - Receive the processing
  result and delivery status of each message.
- [Outbound SMS errors and status codes](outbound-sms-errors-and-status-codes.html) - Look up API errors and
  processing error codes.
- [HTTP OUT trunk settings reference](../sms-trunks/http-out/http-out-trunk-settings-reference.html) - Review
  the HTTP OUT trunk settings that control API access.
