The App Cards module provides a complete API for accessing and managing the Insider platform's app cards campaigns. It allows you to fetch marketing messages and notifications, track read/unread status, handle interactive buttons within messages, and observe app cards events in real time.
Messages can contain rich content, including text, images, and interactive buttons with deeplink actions.
This documentation covers the App Cards API (RNInsider.appCards), the current architecture. The legacy RNInsider.getMessageCenterData(...) method is a separate, older interface for retrieving push notification payloads as a notification center. If you are building a new integration, use the App Cards API.
The InsiderAppCards instance cannot be constructed directly. You need to access it through the main Insider SDK: RNInsider.appCards.
Prerequisites
react-native-insider 8.0.1 or later
SDK must be initialized via RNInsider.init(...) before accessing App Cards.
Access
Obtain the InsiderAppCards instance from the main Insider SDK.
const appCards = RNInsider.appCards;RNInsider.appCards never returns null. If the SDK is not initialized or is frozen (e.g., after GDPR consent is revoked), a no-op instance is returned. In that state every async call reports an InsiderAppCardsError with code SDK_NOT_INITIALIZED, and every void method (view, click, clickButton) silently returns, so it is always safe to reference RNInsider.appCards.
Error Handling
App Cards operations can fail with a typed InsiderAppCardsError. In callback form, the error is delivered as the first argument; in Promise form, it is thrown by await.
InsiderAppCardsError
Extends the standard Error class with a structured code that maps to native SDK error codes on both Android and iOS.
Name | Type | Required | Description |
|---|---|---|---|
name | 'InsiderAppCardsError' | Yes | Always 'InsiderAppCardsError' |
code | InsiderAppCardsErrorCodeType | Yes | Error code identifying the type of error |
message | string | Yes | A human-readable error description |
Static methods
Name | Signature | Description |
|---|---|---|
from | (error: { code: string; message: string } | string | unknown) => InsiderAppCardsError | Normalizes a native bridge error into a typed InsiderAppCardsError |
InsiderAppCardsErrorCode
Constant | Value | Description |
|---|---|---|
UNKNOWN | "unknown" | An unknown or unexpected error occurred. |
SDK_NOT_INITIALIZED | "sdkNotInitialized" | The Insider SDK is not initialized, frozen, or not GDPR compliant. |
INVALID_PARAMETER | "invalidParameter" | An invalid parameter was provided (e.g., empty or non-string IDs). |
NETWORK_ERROR | "networkError" | A network error occurred during the request. |
SERVER_ERROR | "serverError" | The server returned an error response. |
PARSE_ERROR | "parseError" | The server response could not be parsed. |
Method example
try {
const campaignResponse = await RNInsider.appCards.getCampaigns();
console.log('Campaigns:', campaignResponse.appCards.length);
} catch (error) {
if (error instanceof RNInsider.AppCardsError) {
switch (error.code) {
case RNInsider.AppCardsErrorCode.NETWORK_ERROR:
console.warn('Network issue, please try again');
break;
case RNInsider.AppCardsErrorCode.SDK_NOT_INITIALIZED:
console.warn('SDK not ready');
break;
default:
console.warn('App Cards error:', error.code, error.message);
}
}
}Core Types
InsiderAppCardsCampaignResponse
Root container returned from getCampaigns. Holds the full list of app cards retrieved for the current user.
Name | Type | Required | Description |
|---|---|---|---|
appCards | InsiderAppCard[] | Yes | Array of all app cards in the campaigns |
InsiderAppCard
Represents a single app card. Contains all data for the card, content, images, buttons, and associated action.
Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique identifier for the app card |
type | InsiderAppCardType | Yes | Type of the app card ("message" or "image") |
isRead | boolean | Yes | Whether the app card has been read by the user |
content | InsiderAppCardContent | No | Text content (title and description) |
images | InsiderAppCardImage[] | No | Array of images associated with the app card |
buttons | InsiderAppCardButton[] | No | Array of action buttons that can be displayed with the app card |
action | InsiderAppCardAction | No | Action to be executed when the app card is tapped |
App card types
Constant | Description |
|---|---|
"message" | Text-based app card |
"image" | Image-based app card |
Convenience methods
Method | Description |
|---|---|
markAsRead(completion) | Marks this single card as read. Also available as a Promise (omit completion). |
markAsUnread(completion) | Marks this single card as unread. Also available as a Promise. |
delete(completion) | Deletes this card permanently. Also available as a Promise. |
click() | Handles a click event (executes action + logs click conversion) |
view() | Handles a view event (logs view conversion) |
InsiderAppCardContent
Textual content of an app card.
Name | Type | Required | Description |
|---|---|---|---|
title | string | Yes | Main title text of the app card |
description | string | Yes | Description text of the app card |
InsiderAppCardImage
Image associated with an app card.
Name | Type | Required | Description |
|---|---|---|---|
url | string | Yes | URL of the image to be displayed |
InsiderAppCardButton
An interactive button within an app card.
Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique identifier for the button |
appCardId | string | Yes | Unique identifier of the parent app card |
text | string | Yes | Display text shown on the button |
action | InsiderAppCardAction | No | Action executed when the button is tapped |
Convenience methods
Method | Description |
|---|---|
click() | Handles a click event (executes action + logs button click event) |
InsiderAppCardAction (Abstract)
Base type for app card actions. Subtypes represent different actions executed when a user interacts with an app card or a button, such as opening a deep link, showing feedback, or navigating to system settings.
Name | Type | Required | Description |
|---|---|---|---|
type | InsiderAppCardActionType | Yes | Type of the action |
Action types
Constant | Description |
|---|---|
"deep_link" | Deeplink navigation |
"feedback" | Feedback action |
"open_settings" | Open system app settings |
The concrete runtime type is one of InsiderAppCardDeeplinkAction | InsiderAppCardFeedbackAction | InsiderAppCardOpenSettingsAction. Check action.type before narrowing to a subtype.
InsiderAppCardDeeplinkAction
Deeplink action that navigates to a specific location in the app or to an external URL. Extends InsiderAppCardAction with type === 'deep_link'.
Name | Type | Required | Description |
|---|---|---|---|
url | string | null | No | The resolved deeplink URL (URL scheme > internal browser > external browser). Returns null when none is configured |
deeplinkType | InsiderAppCardDeeplinkType | Yes | Identifies which URL family was resolved |
json | any | null | No | Parsed JSON payload attached to the deeplink, or null if no JSON was supplied |
keysAndValues | { key: string; value: string }[] | No | Array of key-value pairs defining additional deeplink parameters |
Deeplink types
Constant | Description |
|---|---|
"url_scheme" | Custom URL scheme (e.g., myapp://...) |
"internal" | Internal webview URL |
"external" | External browser URL |
"unknown" | Unknown or missing URL |
InsiderAppCardFeedbackAction
Marker type for a feedback action. Extends InsiderAppCardAction with no additional fields; type is always "feedback".
InsiderAppCardOpenSettingsAction
Marker type for opening the app's system settings. Extends InsiderAppCardAction with no additional fields; type is always "open_settings".
Available Methods
getCampaigns
Method signatures
RNInsider.appCards.getCampaigns(completion)
RNInsider.appCards.getCampaigns() // returns a PromiseThis method retrieves the user's app card campaigns, and fetches all available app cards from the Insider platform for the current user. Pending campaign requests are canceled before initiating a new one.
Name | Type | Required | Description |
|---|---|---|---|
completion | (error?: Error, campaignResponse?: InsiderAppCardsCampaignResponse) => void | No | Called with the campaign response or an error. Omit to use the Promise form. |
The method supports both completion-callback and Promise forms. Pass a callback to receive (error, campaignResponse), or omit it and await the returned Promise.
Method example
try {
const campaignResponse = await RNInsider.appCards.getCampaigns();
campaignResponse.appCards.forEach((appCard) => {
console.log('App Card Id:', appCard.id, 'Read:', appCard.isRead);
});
} catch (error) {
if (error instanceof RNInsider.AppCardsError) {
console.warn(error.code, error.message);
}
}markAsRead
Method signatures
RNInsider.appCards.markAsRead(appCardIds, completion)
RNInsider.appCards.markAsRead(appCardIds) // returns a PromiseThis method marks specified app cards as read, and updates the read status of one or more app cards to indicate they have been viewed by the user. The operation synchronizes with the Insider backend to persist state across devices.
Name | Type | Required | Description |
|---|---|---|---|
appCardIds | string[] | Yes | A non-empty array of app card identifiers to mark as read |
completion | (error?: Error) => void | No | Called with an error if the request fails, otherwise called with no arguments on success. Omit for the Promise form. |
App card IDs that don't exist on the backend are silently ignored. You can also call appCard.markAsRead (completion) directly on an InsiderAppCard instance to mark a single card.
Method example
try {
await RNInsider.appCards.markAsRead(['card_123', 'card_456']);
console.log('App cards marked as read successfully');
} catch (error) {
if (error instanceof RNInsider.AppCardsError) {
console.warn(error.code, error.message);
}
}markAsUnread
Method signatures
RNInsider.appCards.markAsUnread(appCardIds, completion)
RNInsider.appCards.markAsUnread(appCardIds) // returns a PromiseThis method marks specified app cards as unread, and updates the read status of one or more app cards to indicate they are unread. The operation synchronizes with the Insider backend to persist state across devices.
Name | Type | Required | Description |
|---|---|---|---|
appCardIds | string[] | Yes | A non-empty array of app card identifiers to mark as unread |
completion | (error?: Error) => void | No | Called with an error if the request fails, otherwise called with no arguments on success. Omit for the Promise form. |
You can also call appCard.markAsUnread (completion) directly on an InsiderAppCard instance to unmark a single card.
Method example
try {
await RNInsider.appCards.markAsUnread(['card_123', 'card_456']);
console.log('App cards marked as unread successfully');
} catch (error) {
if (error instanceof RNInsider.AppCardsError) {
console.warn(error.code, error.message);
}
}delete
Method signatures
RNInsider.appCards.delete(appCardIds, completion)
RNInsider.appCards.delete(appCardIds) // returns a PromiseThis method permanently removes one or more app cards from the user's campaigns. The operation synchronizes with the Insider backend.
Name | Type | Required | Description |
|---|---|---|---|
appCardIds | string[] | Yes | A non-empty array of app card identifiers to delete |
completion | . | No | Called with an error if the request fails, otherwise called with no arguments on success. Omit for the Promise form |
You can also call appCard.delete (completion) directly on an InsiderAppCard instance to delete a single card.
Method example
try {
await RNInsider.appCards.delete(['card_123', 'card_456']);
console.log('App cards deleted successfully');
} catch (error) {
if (error instanceof RNInsider.AppCardsError) {
console.warn(error.code, error.message);
}
}click
Method signature
RNInsider.appCards.click(appCard)This method records a click event for an app card. Call this method when a user clicks or taps on an app card. This executes the app card's deeplink action (if present) and notifies observers.
Name | Type | Required | Description |
|---|---|---|---|
appCard | InsiderAppCard | No | The app card that was clicked. Must be an instance returned from getCampaigns. |
You can also call appCard.click() directly on the card instance.
Method example
RNInsider.appCards.click(appCard);view
Method signature
RNInsider.appCards.view(appCard)This method records a view event for an app card. Call this method when an app card becomes visible to the user. This notifies observers and can be used for analytics tracking.
Name | Type | Required | Description |
|---|---|---|---|
appCard | InsiderAppCard | Yes | The app card that was viewed. Must be an instance returned from getCampaigns. |
You can also call appCard.view() directly on the card instance.
Method example
RNInsider.appCards.view(appCard);clickButton
Method signature
RNInsider.appCards.clickButton(button)This method records a click event for a button within an app card. Call this method when a user clicks or taps on a button in an app card. This executes the button's action (if present) and notifies observers.
Name | Type | Required | Description |
|---|---|---|---|
button | InsiderAppCardButton | Yes | The button that was clicked. Must be an instance obtained from appCard.buttons. |
You can also call button.click() directly on the button instance.
Method example
RNInsider.appCards.clickButton(button);Full Integration Example
Below is an end-to-end flow: initialize the SDK, fetch campaigns, view a card, click a button, branch on action type, and mark unread cards as read, with proper error handling.
import { Linking } from 'react-native';
RNInsider.init('your_partner_name', 'group.com.example.app', (type, data) => {
// handle SDK callbacks here
});
async function loadAppCards() {
try {
const campaignResponse = await RNInsider.appCards.getCampaigns();
const cards = campaignResponse.appCards ?? [];
if (cards.length === 0) return;
const firstCard = cards[0];
RNInsider.appCards.view(firstCard);
const firstButton = firstCard.buttons?.[0];
if (firstButton) {
RNInsider.appCards.clickButton(firstButton);
handleAction(firstButton.action);
}
const unreadIds = cards.filter((card) => !card.isRead).map((card) => card.id);
if (unreadIds.length > 0) {
await RNInsider.appCards.markAsRead(unreadIds);
}
} catch (error) {
if (error instanceof RNInsider.AppCardsError) {
switch (error.code) {
case RNInsider.AppCardsErrorCode.NETWORK_ERROR:
console.warn('Network issue, please try again');
break;
case RNInsider.AppCardsErrorCode.SDK_NOT_INITIALIZED:
console.warn('SDK not ready');
break;
default:
console.warn('App Cards error:', error.code, error.message);
}
}
}
}
function handleAction(action) {
if (!action) return;
switch (action.type) {
case 'deep_link':
if (action.url) {
Linking.openURL(action.url);
}
break;
case 'feedback':
// present your feedback UI
break;
case 'open_settings':
Linking.openSettings();
break;
}
}
loadAppCards();