# Set up a transactional SMS or WhatsApp message

Transactional SMS or WhatsApp messages are text messages that your audience implicitly opts-into, like order confirmations, password reset codes, or account verification messages. You can send transactional SMS messages programmatically through Customer.io.

 New to transactional messaging?

Check out our [getting started](/journeys/transactional-api/) section to learn more about transactional concepts and how our transactional API works.

## Before you begin[](#before-you-begin)

Before you can send transactional SMS messages, you need to:

*   [Set up your Twilio account and enable SMS](/journeys/sms-get-started/#set-up-twilio) in your workspace.
*   Get your [app API key](https://fly.customer.io/settings/api_credentials?keyType=app). This is the bearer token that you’ll use when you call the transactional API to trigger a message.

**We also recommend that you use different phone numbers for transactional and marketing SMS messages**. This helps maintain deliverability and ensures your critical transactional messages aren’t affected by marketing message reputation.

## Create a transactional SMS[](#create-a-transactional-sms)

Unlike transactional emails and push notifications, you cannot send a transactional SMS or WhatsApp message without a template. You *must* use a `transactional_message_id` when you send an SMS and you cannot override the body or image URL of your message at send time.

1.  Go to the **Transactional** page and click **Send your first message** or **Create message**—depending on whether there are already transactional messages in your workspace.
    
2.  Give your message a **Name** and a **Description** and then click **Next: Add Content**. The name and description help your team members understand what kind of message this is (like “Two-Factor Authentication” or “Password Reset Code”).
    
    [![The transactional message's first screen, with fields for name, description, and tags](https://docs.customer.io/images/transactional-sms-name.png)](#5cb344af69f6822847ec2a3a54e87cc6-lightbox)
    
3.  Select **SMS** and click **Add Content**.
    
4.  Draft your message. If you see an error in the upper-right when you try to write your message, it’s likely that you need to select a person in your *Sample data* who has a `phone` [attributeA key-value pair that you associate with a person or an object—like a person’s name, the date they were created in your workspace, or a company’s billing date etc. Use attributes to target people and personalize messages.](/journeys/attributes/).
    
    Selecting a representative sample person also helps you personalize your message. You can personalize messages using attributes (`{{customer.<attribute>}}`) or data from your transactional message’s `message_data` key ( in the format `{{trigger.<data-object-property>}}`).
    
    [![Transactional message content screen, with a sample person selected, a text box for the message, and a preview of the message](https://docs.customer.io/images/transactional-sms-content.png)](#ae2b2f3810e97706e1d28558e3db7cf4-lightbox)
    
5.  When you’re done writing your message, click **Save Changes** and then click **Next: Configure Settings**.
    
6.  Configure your message settings. In general, we recommend that you use our defaults and that you **Set a trigger name** so that it’s easier to send your message later.
    
    *   **Send to unsubscribed people?** Unsubscribed people probably still want to receive your important transactional messages like order confirmations and password resets.
        
    *   **Enable link tracking?** By default, we’ll track clicks on links in your transactional SMS messages. Disable this setting if you don’t use our [link shortening feature](/journeys/sms-link-shortening/) or tracked links (which are longer than normal links) will likely exceed the 160 character limit for SMS messages.
        
    *   **Protect sensitive data by disabling message retention?** This setting prevents Customer.io from retaining your message content. You might want to do this to conceal sensitive messages, like password reset codes or verification tokens.
        
    *   **Queue messages as drafts?** This setting generates a draft for every message you trigger rather than sending them automatically. You can review these messages under the *Drafts* tab and decide whether to send or delete them.
        
    *   **Set a Trigger Name**: This is a friendly name for your message that you can use instead of the `transactional_message_id` when you send your message. It may help make your integration more human-readable if you use triggers that represent the kinds of messages you send—like `password_reset` or `order_confirmation`.
        
    
    [![SMS settings, with toggles for basic settings and a text box for the trigger name](https://docs.customer.io/images/transactional-sms-settings.png)](#1c32de2d8530a61a89e1ae3b03b96366-lightbox)
    
7.  Now you’re ready to send your message. You can adapt the code sample on the **Send Message** screen to your code—wherever you intend to trigger transactional messages—or use our API directly.
    

(Optional) Even if you don’t want to wire up your integration completely, we recommend that you call our API and send a test message to make sure that your message works the way you expect. You can even use an HTTP client like [Postman](https://getpostman.com) or send a cURL request from your terminal to test your message and complete the setup process.

 Try our Postman collection!

You can use our [Postman](https://www.getpostman.com) collection and associated environment to get started with the Customer.io API. Our environment is based on our US endpoints; if you’re in our EU region, you’ll need to add `-eu` to `track_api_url` and `app_api_url` variables.

(function(e,t,n,s,o,i,a){!e\[n\]&&(e\[n\]=function(){(e\[s\]||(e\[s\]=\[\])).push(arguments)}),!t.getElementById(n+s)&&t.getElementsByTagName("head")\[0\].appendChild((a=t.createElement("script"),a.id=n+s,a.async=1,a.src=o,a))})(window,document,"\_pm","PostmanRunObject","https://run.pstmn.io/button.js")

## The `to` parameter: sending your message[](#the-to-parameter-sending-your-message)

When you send a transactional SMS or WhatsApp message, you must pass the `to` parameter in your request so we know who to send the message to.

This value can be either a phone number in E.164 format (e.g., +15551234567) or a customer [attributeA key-value pair that you associate with a person or an object—like a person’s name, the date they were created in your workspace, or a company’s billing date etc. Use attributes to target people and personalize messages.](/journeys/attributes/) in [liquidA syntax that supports variables, letting you personalize messages for your audience. For example, if you want to reference a person’s first name, you might use the variable `{{customer.first_name}}`.](/using-liquid) syntax, like `{{customer.phone}}`.

## Examples and API parameters[](#examples-and-api-parameters)

Below are examples of transactional SMS messages. We’ve provided a basic payload and examples for cURL, our Node.JS SDK, and our Python SDK.

We’ve also provided a list of parameters for transactional SMS payloads. Your payload changes based on whether you reference a `transactional_message_id` (a template) or not. See our [REST API](/integrations/api/app/#operation/sendSMS) documentation for more information.

 Basic Payload

#### Basic Payload[](#Basic Payload)

```json
{
  "transactional_message_id": "confirmation_code",
  "identifiers": {
    "id": "123456"
  },
  "message_data": {
    "confirmation_code": "123456",
    "account_name": "Jane Doe"
  }
}
```

 Node.js

#### Node.js[](#Node.js)

```javascript
const { APIClient, SendSMSRequest } = require("customerio-node");
const api = new APIClient('app-key');

const request = new SendSMSRequest({
  transactional_message_id: "confirmation_code",
  identifiers: {
    id: "123456"
  },
  message_data: {
    confirmation_code: "123456",
    account_name: "Jane Doe"
  },
});

api.sendSMS(request)
  .then(res => console.log(res))
  .catch(err => console.log(err.statusCode, err.message))
```

 Python

#### Python[](#Python)

```python
from customerio import APIClient, SendSMSRequest, CustomerIOException
client = APIClient("your API key")

request = SendSMSRequest(
  transactional_message_id="confirmation_code",
  identifiers={
    "id": "123456"
  },
  message_data={
    "confirmation_code": "123456",
    "account_name": "Jane Doe"
  }
)

try:
  api.send_sms(request)
except CustomerIOException as e:
  print("error: ", e)
```

 Go

#### Go[](#Go)

```go
import "github.com/customerio/go-customerio"

client := customerio.NewAPIClient("");

request := customerio.SendSmsRequest{
  TransactionalMessageID: "sms_test",
  Identifiers: map[string]string{
    "id": "123456",
  },
}

body, err := client.SendSms(context.Background(), &request)
if err != nil {
  fmt.Println(err)
}

fmt.Println(body)
```

 Ruby

#### Ruby[](#Ruby)

```ruby
require "customerio"

client = Customerio::APIClient.new("")

request = Customerio::SendSmsRequest.new(
  transactional_message_id: "sms_test",
  identifiers: {
    id: "123456",
  },
)

begin
  response = client.send_sms(request)
  puts response
rescue Customerio::InvalidResponse => e
  puts e.message, e.code, e.response
end
```

 cURL

#### cURL[](#cURL)

```bash
curl --request POST \
  --url https://api.customer.io/v1/send/sms \
  --header 'Authorization: Bearer <YOUR-APP-API-KEY>' \
  --header 'content-type: application/json' \
  --data '{
    "transactional_message_id": "confirmation_code",
    "identifiers": {
        "id": "123456"
    },
    "message_data": {
        "confirmation_code": "123456",
        "account_name": "Jane Doe"
    }
}'
```

*   transactional\_message\_id 
    
    Required The transactional message template that you want to use for your message. You can call the template by its numerical ID or by the *Trigger Name* that you assigned the template (case insensitive).
    
    integer
    
    The ID of the transactional message you want to send.
    
    string
    
    The name of trigger for the transactional message you want to send; you set the trigger name in the *Configure Settings* step when setting up your message. This is case insensitive.
    
*   from string
    
    The phone number or sender ID that your SMS is from. This must be a verified phone number in your Twilio account. This overrides the from address set within the transactional template (referenced by `transactional_message_id`). Phone numbers must be in E.164 format (e.g., +15551234567).
    
*   language string
    
    Overrides language preferences for the person you want to send your transactional message to. Use one of our [supported two- or four-letter language codes](/localization-getting-started/#supported-languages).
    
*   to string
    
    Required The phone number you want to send your SMS to. Phone numbers must be in E.164 format (e.g., +15551234567), but you can also use liquid syntax if you store users phone numbers as attributes; you don’t have to pass an E.164 formatted phone number in the call.