Notification inbox
UpdatedHow it works
Unlike other messages, inbox messages don’t necessarily appear immediately to users, and they don’t disappear when the user dismisses them. Instead, you’ll display these messages through a notification inbox that your audience can access at their leisure.
Customer.io delivers inbox messages as JSON payloads, not fully-rendered messages. The SDK helps you listen for these payloads, but you’ll determine how to display them in your own inbox client.
You can send an inbox message as a part of a campaign, broadcast, or transactional message.
Get the inbox instance
You’ll access inbox functionality through the inbox() method on the in-app messaging module.
const inbox = CustomerIO.inAppMessaging.inbox();
Inbox methods
The inbox instance provides several methods to manage messages.
| Method | Description |
|---|---|
getMessages() | Fetch all messages from the inbox. Returns a Promise with the list of messages. |
getMessages(topic) | Fetch messages filtered by topic. Returns a Promise with the filtered list of messages. |
subscribeToMessages(callbacks) | Subscribe to inbox updates for all messages. Returns a subscription object. |
subscribeToMessages(callbacks, topic) | Subscribe to inbox updates filtered by topic. Returns a subscription object. |
markMessageOpened(message) | Mark a message as opened. |
markMessageUnopened(message) | Mark a message as unopened. |
markMessageDeleted(message) | Mark a message as deleted. |
trackMessageClicked(message) | Track a click on the message without an action name. |
trackMessageClicked(message, actionName) | Track a click on the message with an action name. |
Inbox message payloads
Inbox messages are delivered as a JSON payload. The SDK helps you listen for the payload, but you’ll render the content in your own inbox client.
The client payload includes the following fields, but you’re most concerned with the properties object, which represents your message content. By default, we’ll send a title and body field, but you can add other fields like an image or a link—whatever you set up your inbox to expect.
Make sure that your team members know what payloads to send—especially if you expect different payloads for different topics or types of messages.
| Field | Type | Description |
|---|---|---|
messageId | string | Unique identifier for the message. |
sentAt | string | When the message was sent. |
expiresAt | string | When the message will expire. |
opened | boolean | Whether the message has been opened. |
topics | array | The topics that the message belongs to. |
type | string | The type of message. |
properties | object | The properties of the message. |
{
"messageId": "1234567890",
"sentAt": "2026-02-05T12:00:00Z",
"expiresAt": "2026-02-05T12:00:00Z",
"opened": false,
"topics": ["orders", "shipping"],
"type": "order_shipped",
"properties": {
"title": "Hey Cool Person, your order shipped!",
"body": "You can track your order #1234567890 here:",
"link": "https://example.com/orders/1234567890"
}
}
Inbox topics and types
When you send an inbox message, you can assign it to one or more topics. You can use these topics to filter messages when you fetch them. You can also use the topics to determine how to render the messages in your notification inbox.
Messages also have a type. Think of this like a sub-category or topic for a message. For example, you might have orders and sale topics, where orders don’t have images but sale topics might. Or, 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.
Setup your notification inbox
Inbox messages are just JSON payloads. You’ll need to build your own inbox client to display the messages. The code below gives you a starting point, but you can build your own inbox client however you want.
Fetch messages
// Fetch all messages
const messages = await inbox.getMessages();
// Fetch messages filtered by topic
const promotions = await inbox.getMessages('promotions');
Subscribe to inbox updates
// Subscribe to all messages
const subscription = inbox.subscribeToMessages({
onMessagesChanged: (messages) => {
console.log('Messages updated:', messages);
// Update your UI with the messages
setMessages(messages);
}
});
// Subscribe to messages filtered by topic
const topicSubscription = inbox.subscribeToMessages({
onMessagesChanged: (messages) => {
console.log('Topic messages:', messages);
// Update your UI with filtered messages
setTopicMessages(messages);
}
}, 'announcements');
// Don't forget to unsubscribe when you're done
subscription.remove();
topicSubscription.remove();
Mark messages as opened or unopened
// Mark a message as opened
inbox.markMessageOpened(message);
// Mark a message as unopened
inbox.markMessageUnopened(message);
Track message clicks
// Track a click without an action name
inbox.trackMessageClicked(message);
// Track a click with an action name
inbox.trackMessageClicked(message, 'view_offer');
Delete messages
// Mark a message as deleted
inbox.markMessageDeleted(message);
Working with message properties
You can access message properties to display custom content in your inbox:
// Access message properties
const { title, body, link, image } = message.properties;
// Handle message action when user taps
const handleMessagePress = (message) => {
// Mark as opened
inbox.markMessageOpened(message);
// Track click
inbox.trackMessageClicked(message);
// Open link if available
if (message.properties.link) {
Linking.openURL(message.properties.link);
}
};
// Track with specific action name
const handleActionButton = (message, actionType) => {
inbox.markMessageOpened(message);
inbox.trackMessageClicked(message, actionType);
// Navigate based on action
switch (actionType) {
case 'view_offer':
navigation.navigate('OfferDetails', { offerId: message.properties.offerId });
break;
case 'view_order':
navigation.navigate('OrderDetails', { orderId: message.properties.orderId });
break;
}
};
