Advanced: build your own inbox
UpdatedThe notification inbox lets you send messages to your audience that they can access at their leisure.
This page covers the advanced, build-your-own approach. In this approach, you write code: you fetch raw JSON payloads with the SDK and render and style the inbox UI yourself. It’s the most flexible option, but it requires development work and you maintain the inbox in your own app.
If you’d rather have Customer.io render and style the inbox for you—with no front-end code—set up a notification inbox and build messages in the visual editor instead. The rest of this section is for developers building a custom inbox.
How it works
Inbox messages aren’t displayed immediately (or along our normal prioritization settings for in-app messages), but rather are displayed through a custom inbox UI. Your audience typically sees them when they open the inbox in your app or on your website. Check out Colby’s video below for a quick overview and demonstration of the feature.
Inbox messages differ from other messages in two important ways:
- Unlike other message channels, messages aren’t “delivered” in the traditional sense. Instead, you’ll fetch them when people visit your site.
- Inbox messages aren’t delivered as rendered messages. They’re delivered as JSON payloads.
So when people visit your site, you’ll fetch messages. Then when people open the inbox, they’ll see and interact with messages.


General setup process
Before you can send inbox messages, you’ll need to do a few things first:
- Make sure you’re set up with our JavaScript SDK on your website. See our in-app messaging documentation for more information.
- Set up your inbox in your app.
- Tell your team members what payloads, types, and topics to use in messages: because inbox messages are delivered as JSON payloads, your coworkers—anybody who uses Customer.io to send inbox messages—needs to know what to send in messages.
When you’re done, you’re ready to send messages!
JS SDK to your site?} a-->|yes|b(Set up your inbox) a-.->|no|f(Add the JS SDK
to your website)-.->b b-->c{Does your inbox
expect anything more
than title and body?} c-->|yes|d(Tell your team
about payloads) c-.->|no|e d-->e(Send inbox messages)
Minimum supported versions
To build your own inbox, you need one of our client SDKs. See the table below for minimum version requirements.
If you use our JavaScript snippet, you don’t need to worry about version requirements—we automatically use the latest version of the SDK when people visit your website. Any other import method needs a version of the SDK that supports the inbox feature.
| SDK | Minimum required version |
|---|---|
| JavaScript Snippet | N/A; automatically get latest version on page load |
| JavaScript import cdp-analytics-browser | 0.3.11 |
| iOS | 4.2 |
| Android | 4.16 |
| React Native | 6.2 |
| Flutter | 3.3 |
| Expo | 3.1 |
The message payload
Inbox messages are delivered as a JSON payload. Our SDKs help you listen for the payload and render messages in your inbox.
By default, messages contain a properties object with a title and body, but you can send arbitrary JSON—whatever you set up your inbox to expect. So, when you set up your inbox, make sure that your team members understand the structure of the payload—which fields are required, and which topics or types of messages your inbox expects.
{
"messageId": "1234567890",
"sentAt": "2026-02-05T12:00:00Z",
"opened": false,
"topics": ["orders", "shipping"],
"type": "order_shipped",
"properties": {
"title": "Hey, {{customer.first_name}}, your order shipped!",
"body": "You can track your order #{{event.order_number}} here:",
"link": "https://example.com/orders/{{event.order_number}}"
}
}
| Field | Type | Required? | Description |
|---|---|---|---|
messageId | string | true | Unique identifier for the message. |
sentAt | string | true | When the message was sent. |
expiresAt | string | true | When the message will expire. |
opened | boolean | true | If true, the message has been opened. |
topics | array | false | The topics that the message belongs to. |
type | string | false | The type of message. |
properties | object | true | Your custom data payload representing the content you want to render. The payload cannot be empty. |
Topics and types
You can use the topic and type fields when you call the inbox() method to filter the inbox and render messages differently. You’ll define these values when you compose your message. You can set any kind of topic or type you want, but you’ll want to set up your inbox to expect them.
For example, you might have orders and sale topics, where you want to let the user sort notifications for orders they’ve placed or for sales that are active on your site.
Within the orders topic, you might have order_placed and order_shipped types, where order_placed lists order details and images of purchased products and order_shipped provides a link to the tracking information for the order that opens in a new tab.
Next steps
- Display inbox messages in your app — use the SDK to fetch and render messages.
- Compose messages in the advanced editor — author the JSON payload you send to the inbox.
