> This page is part of the [Customer.io documentation](https://docs-customerio.netlify.app). For the complete index, see [llms.txt](https://docs-customerio.netlify.app/llms.txt).
> Last updated: June 8, 2026

# Set up a transactional push

Transactional messages are email or push notifications that your audience implicitly opts-into, like a transaction receipt or a password reset request. You can send transactional messages programmatically through Customer.io.

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

Before you can send transactional push notifications you need to:

*   [Enable Push Notifications in your workspace](https://fly.customer.io/env/last/settings/actions/push/ios) for Android and/or iOS.
*   Set up your app to receive push notifications from Customer.io. We strongly recommend that you use [our SDKs](/integrations/sdk/). If this isn’t an option, you can follow the instructions here to [configure push without our SDKs](/journeys/channels/push/developer-guide/#configure-push).

## Create a transactional push notification[](#create-a-transactional-push-notification)

 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")

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.  Name your message and provide a description. These fields help your team members understand what kind of message this is (like “Password Reset Instructions”). You can also use the *Name* of your message instead of the `transactional_message_id` when you send your message.
    
    [![create_transactional_step1.png](https://docs.customer.io/images/image%28552%29.png)](#d043a05d0fb6a474cbb4d49700a56dca-lightbox)
    
3.  Click **Next: Add Content** to go to the next step. Select **Push** to create a transactional push notification.
    
    [![create_transactional_step2.png](https://docs.customer.io/images/create_transactional_push_step2.png)](#b385b18ec8d47a0eaddb303be22e9549-lightbox)
    
4.  Click **Add Content** and compose your push notification. Add images, deeplinks and custom data through the editor, or provide these values in the API request. You can also use attributes (`customer.<attribute>`) or trigger data (`trigger.<data-object-property>`) to customize your message.
    
    [![set up a transactional push notification](https://docs.customer.io/images/push-transactional-composer.png)](#859001d6f5e1aa311ba009e9930a685b-lightbox)
    
     Need to track personalized links?
    
    If you need to track personalized links, use the [`cio_link` liquid tag](/journeys/liquid/tag-list/?version=latest#cio_link-latest). This helps you group and gather metrics for links that are different for each person—like password reset links, customer dashboards, or product recommendations. Example: `{% cio_link url:"https://mydomain.com?token=123abc" %}`. If you *don’t* use this tag, we’ll track each URL independently, which might make it difficult to gather metrics for a links in your push notifications.
    
5.  Configure your message settings.
    
    *   **Send to unsubscribed people?** Unsubscribed people usually still want to receive your important transactional messages.
        
    *   **Protect sensitive data by disabling message retention?** This setting prevents Customer.io from retaining your message content in delivery history and associated API calls. You might want to do this to conceal sensitive content, like password reset 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`.
        
    
    [![configure your message's settings](https://docs.customer.io/images/transactional_push_configure_settings.png)](#094ec308c728736e046700da1be25bd0-lightbox)
    
6.  To complete the setup, you need to call the API and trigger a message. If you’re not yet ready to send a message directly from your code, you can 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.
    

 Did you just update a snippet?

If you just updated a [snippet](/journeys/liquid/snippets/) used in your messages, make sure you wait a couple of minutes before activating your workflow to ensure all updates appear in your delivered messages.

### Identify your recipient[](#identify-your-recipient)

You must include an `identifiers` object so we can attribute the message to the right person and resolve any [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}}`.](/journeys/liquid/using-liquid) in your message. We don’t treat device tokens as identifiers, so even when `to` is a token, you still need an `identifiers` block.

The `to` field is optional and selects which of the identified person’s devices to send to—`all`, `last_used`, or a specific device token belonging to that person. If you omit `to`, we default to `all`.

### Auto-create push records[](#auto-create-push-records)

If you’re working with [Our CLI tool](/ai/cli/) or otherwise building your message from code, you can include the `auto_create` parameter along with a `transactional_message_id` string the first time you send a message.

Then you’ll include the `transactional_message_id` in subsequent sends to attribute metrics to the same “message” in Customer.io.

If you don’t include a `transactional_message_id` in your request, Customer.io attributes metrics to `"transactional_message_id": 1`. And, if you send different kinds of messages with the same `transactional_message_id`, they’ll all roll up under that single ID in your metrics, making it difficult to see metrics for each type of message.

**Transactional messages created with `auto_create` don’t contain message content.** You’ll pass full message payload (the `body`, `subject`, and `from` fields) with *every* send. If you want to store message content in Customer.io, you’ll need to use our UI or work with [our command line interface (CLI)](/ai/cli/) to populate your template with message content.

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

Below is a basic transactional push payload, followed by the full list of parameters. Your payload changes based on whether you reference a `transactional_message_id` (a template) or not. See our [REST API](/integrations/api/app/#operation/sendPush) documentation for the full reference, including code samples in cURL and several languages.

```json
{
  "transactional_message_id": 44,
  "title": "Did you really login from a new location?",
  "identifiers": {
    "email": "person@example.com"
  },
  "message_data": {
    "password_reset_token": "abcde-12345-fghij-d888",
    "account_id": "123dj"
  }
}
```

*   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 to the template in the UI (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.