The App Cards module provides a complete card-based messaging solution for the Insider Android SDK. It enables developers to retrieve card campaigns, manage read/unread/delete status, handle deeplink actions, and log analytics events (clicks and views).
This documentation covers the App Cards API (InsiderAppCards), the current architecture. The legacy v1 API (getMessageCenterData) 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.
Prerequisites
Insider Android SDK com.useinsider:insider:16.0.0 or later
SDK must be initialized via Insider.Instance.init(application, partnerName) before accessing App Cards
Access
The InsiderAppCards client is obtained through the main SDK singleton.
InsiderAppCards appCards = Insider.Instance.appCards();val appCards = Insider.Instance.appCards()appCards() never returns null. If the SDK is not initialized or frozen (e.g., GDPR consent is revoked), a no-op instance is returned. All callback methods on a no-op instance will report an AppCardsException with code SDK_NOT_INITIALIZED, and all void methods will silently return.
Callback Interfaces
AppCardsCampaignsCallback
Callback interface for campaign retrieval operations.
public interface AppCardsCampaignsCallback {
void onComplete(InsiderAppCardCampaignsResponse responseObject, AppCardsException error);
}interface AppCardsCampaignsCallback {
fun onComplete(responseObject: InsiderAppCardCampaignsResponse?, error: AppCardsException?)
}Name | Type | Description |
|---|---|---|
responseObject | InsiderAppCardCampaignsResponse? | The campaign response, or null if an error occurred |
error | AppCardsException? | The error, or null if the request succeeded. |
AppCardsMarkAsReadCallback
Callback interface for mark-as-read and mark-as-unread operations.
public interface AppCardsMarkAsReadCallback {
void onComplete(AppCardsException error);
}interface AppCardsMarkAsReadCallback {
fun onComplete(error: AppCardsException?)
}Name | Type | Description |
|---|---|---|
error | AppCardsException? | The error, or null if the request succeeded. |
AppCardsDeleteCallback
Callback interface for delete operations.
public interface AppCardsDeleteCallback {
void onComplete(AppCardsException error);
}interface AppCardsDeleteCallback {
fun onComplete(error: AppCardsException?)
}Name | Type | Description |
|---|---|---|
error | AppCardsException? | The error, or null if the request succeeded. |
Error Handling
AppCardsException
All App Cards operations report errors via AppCardsException, which extends Exception and provides a typed error code via getCode().
Code | Description |
|---|---|
SDK_NOT_INITIALIZED | SDK is not initialized, frozen, or not GDPR compliant. |
INVALID_PARAMETER | Invalid parameter provided (e.g., null or empty card IDs). |
NETWORK_ERROR | A network error occurred during the request. |
SERVER_ERROR | Server returned an error response (HTTP 4xx/5xx). |
PARSE_ERROR | Failed to parse the server response. |
UNKNOWN | An unexpected error occurred. |
appCards.getCampaigns((response, error) -> {
if (error != null) {
switch (error.getCode()) {
case SDK_NOT_INITIALIZED:
// SDK not initialized
break;
case NETWORK_ERROR:
// Retry later
break;
case SERVER_ERROR:
// Server issue
break;
default:
// Handle other errors
break;
}
}
});appCards.getCampaigns { response, error ->
if (error != null) {
when (error.code) {
AppCardsException.AppCardsExceptionCode.SDK_NOT_INITIALIZED -> { /* ... */ }
AppCardsException.AppCardsExceptionCode.NETWORK_ERROR -> { /* ... */ }
AppCardsException.AppCardsExceptionCode.SERVER_ERROR -> { /* ... */ }
else -> { /* ... */ }
}
}
}Core Types
InsiderAppCardCampaignsResponse
Model class representing an app cards campaign response. Contains a list of card items.
Name | Type | Nullable | Description |
|---|---|---|---|
appCards | List<InsiderAppCard> | No | The list of cards in the campaign response |
InsiderAppCard
Model class representing a single card in the campaign response.
Name | Type | Nullable | Description |
|---|---|---|---|
id | String | No | The card identifier. |
type | String | No | The card type (e.g., "image", "card"). |
isRead | Boolean | No | Whether the card has been read. |
images | List<InsiderAppCardImage>? | Yes | List of images, or null. |
content | InsiderAppCardContent? | Yes | Content (title/description), or null. |
couponSettings | JSONObject? | Yes | Coupon settings JSON, or null. |
action | InsiderAppCardDeeplinkAction? | Yes | Card-level deeplink action, or null. |
buttons | List<InsiderAppCardButton>? | Yes | List of buttons, or null. |
Convenience methods
Method | Description |
|---|---|
markAsRead(callback) | Marks this single card as read. |
markAsUnread(callback) | Marks this single card as unread. |
delete(callback) | Deletes this card permanently. |
click() | Handles a click event (executes action + logs click conversion). |
view() | Handles a view event (logs view conversion). |
InsiderAppCardContent
Model class containing the title and description of a card.
Name | Type | Nullable | Description |
|---|---|---|---|
title | String | No | The content title. |
description | String | No | The content description. |
InsiderAppCardImage
Model class representing an image within a card.
Name | Type | Nullable | Description |
|---|---|---|---|
url | String | No | The image URL. |
InsiderAppCardButton
Model class representing a button in a card. Buttons can have deeplink, app settings, or app review actions.
Name | Type | Nullable | Description |
|---|---|---|---|
id | String | No | The button identifier. |
text | String | No | The button display text. |
action | InsiderAppCardAction? | Yes | The button action, or null. |
Convenience methods
Method | Description |
|---|---|
click() | Handles a click event (executes action + logs button click event). |
InsiderAppCardAction (Abstract)
Abstract base class for all app card action models. Extended by InsiderAppCardDeeplinkAction, InsiderAppCardAppSettingsAction, and InsiderAppCardAppReviewAction.
Method | Return Type | Description |
|---|---|---|
getType() | String | Returns the action type ("deep_link", "open_settings", "feedback"). |
runAction() | void | Executes the action. |
Action Types
Class | Type Value | Description |
|---|---|---|
InsiderAppCardDeeplinkAction | "deep_link" | Deeplink navigation (URL scheme, internal/external browser). |
InsiderAppCardAppSettingsAction | "open_settings" | Opens the app's system settings. |
InsiderAppCardAppReviewAction | "feedback" | Triggers the native app review dialog. |
InsiderAppCardDeeplinkAction
Deeplink action with support for URL schemes, internal browser, and external browser URLs. Can also carry JSON data and key-value pairs.
Name | Type | Nullable | Description |
|---|---|---|---|
url | String? | Yes | The resolved URL (url_scheme > internal_browser > external_browser). |
type | String | No | The action type. |
deeplinkURLType | String | No | The URL type: "url_scheme", "internal", "external", or "unknown". |
json | HashMap<String, Any>? | Yes | Associated JSON data, or null. |
keysAndValues | List<HashMap<String, String>>? | Yes | List of key-value pairs, or null. |
InsiderAppCardDeeplinkURLType
Constants class for deeplink URL type identifiers.
Constant | Value | Description |
|---|---|---|
EXTERNAL | “external“ | Open in external browser. |
INTERNAL | “internal“ | Open in internal webview. |
URL_SCHEME | "url_scheme" | Open via custom URL scheme. |
UNKNOWN | “unknown“ | Unknown or invalid URL type. |
Available Methods
getCampaigns
public void getCampaigns(AppCardsCampaignsCallback callback)fun getCampaigns(callback: AppCardsCampaignsCallback): UnitRetrieves the app card campaigns for the current user. The response is automatically decrypted and deserialized into an InsiderAppCardCampaignsResponse.
Name | Type | Required | Description |
|---|---|---|---|
callback | AppCardsCampaignsCallback | Yes | The callback to invoke when the request completes. |
InsiderAppCards appCards = Insider.Instance.appCards();
appCards.getCampaigns(new AppCardsCampaignsCallback() {
@Override
public void onComplete(InsiderAppCardCampaignsResponse responseObject, AppCardsException error) {
if (error != null) {
Log.e("AppCards", "Failed to get campaigns: " + error.getCode(), error);
return;
}
List<InsiderAppCard> cards = responseObject.getAppCards();
for (InsiderAppCard card : cards) {
Log.d("AppCards", "Card ID: " + card.getId());
Log.d("AppCards", "Is Read: " + card.isRead());
InsiderAppCardContent content = card.getContent();
if (content != null) {
Log.d("AppCards", "Title: " + content.getTitle());
}
}
}
});val appCards = Insider.Instance.appCards()
appCards.getCampaigns { responseObject, error ->
if (error != null) {
Log.e("AppCards", "Failed to get campaigns: ${error.code}", error)
return@getCampaigns
}
val cards = responseObject?.getAppCards() ?: return@getCampaigns
for (card in cards) {
Log.d("AppCards", "Card ID: ${card.getId()}")
Log.d("AppCards", "Is Read: ${card.isRead()}")
card.getContent()?.let { content ->
Log.d("AppCards", "Title: ${content.getTitle()}")
}
}
}markAsRead
public void markAsRead(String[] appCardIds, AppCardsMarkAsReadCallback callback)fun markAsRead(appCardIds: Array<String>, callback: AppCardsMarkAsReadCallback): UnitMarks one or more cards as read.
Name | Type | Required | Description |
|---|---|---|---|
appCardIds | Array<String> | Yes | An array of card IDs to mark as read. |
callback | AppCardsMarkAsReadCallback | Yes | The callback to invoke when the request completes. |
InsiderAppCards appCards = Insider.Instance.appCards();
String[] ids = new String[]{"card-001", "card-002"};
appCards.markAsRead(ids, new AppCardsMarkAsReadCallback() {
@Override
public void onComplete(AppCardsException error) {
if (error != null) {
Log.e("AppCards", "Failed to mark as read", error);
return;
}
Log.d("AppCards", "Cards marked as read successfully");
}
});val appCards = Insider.Instance.appCards()
val ids = arrayOf("card-001", "card-002")
appCards.markAsRead(ids) { error ->
if (error != null) {
Log.e("AppCards", "Failed to mark as read", error)
return@markAsRead
}
Log.d("AppCards", "Cards marked as read successfully")
}markAsUnread
public void markAsUnread(String[] appCardIds, AppCardsMarkAsReadCallback callback)fun markAsUnread(appCardIds: Array<String>, callback: AppCardsMarkAsReadCallback): UnitMarks one or more cards as unread.
Name | Type | Required | Description |
|---|---|---|---|
appCardIds | Array<String> | Yes | An array of card IDs to mark as unread. |
callback | AppCardsMarkAsReadCallback | Yes | The callback to invoke when the request completes. |
InsiderAppCards appCards = Insider.Instance.appCards();
String[] ids = new String[]{"card-001"};
appCards.markAsUnread(ids, new AppCardsMarkAsReadCallback() {
@Override
public void onComplete(AppCardsException error) {
if (error != null) {
Log.e("AppCards", "Failed to mark as unread", error);
return;
}
Log.d("AppCards", "Cards marked as unread successfully");
}
});val appCards = Insider.Instance.appCards()
val ids = arrayOf("card-001")
appCards.markAsUnread(ids) { error ->
if (error != null) {
Log.e("AppCards", "Failed to mark as unread", error)
return@markAsUnread
}
Log.d("AppCards", "Cards marked as unread successfully")
}You can also use the convenience methods card.markAsRead(callback) and card.markAsUnread(callback) directly on an InsiderAppCard instance to mark a single card.
delete
public void delete(String[] appCardIds, AppCardsDeleteCallback callback)fun delete(appCardIds: Array<String>, callback: AppCardsDeleteCallback): UnitDeletes one or more cards from the current user's campaigns. Deleted cards are permanently removed and will not be returned in subsequent campaign calls.
Name | Type | Required | Description |
|---|---|---|---|
appCardIds | Array<String> | Yes | An array of card IDs to delete. |
callback | AppCardsDeleteCallback | Yes | The callback to invoke when the request completes. |
InsiderAppCards appCards = Insider.Instance.appCards();
String[] ids = new String[]{"card-001"};
appCards.delete(ids, new AppCardsDeleteCallback() {
@Override
public void onComplete(AppCardsException error) {
if (error != null) {
Log.e("AppCards", "Failed to delete cards", error);
return;
}
Log.d("AppCards", "Cards deleted successfully");
}
});val appCards = Insider.Instance.appCards()
val ids = arrayOf("card-001")
appCards.delete(ids) { error ->
if (error != null) {
Log.e("AppCards", "Failed to delete cards", error)
return@delete
}
Log.d("AppCards", "Cards deleted successfully")
}You can also use the convenience method card.delete(callback) directly on an InsiderAppCard instance to delete a single card.
click
public void click(InsiderAppCard appCard)fun click(appCard: InsiderAppCard): UnitLogs a click conversion event for a card and executes its action (if available).
Name | Type | Required | Description |
|---|---|---|---|
appCard | InsiderAppCard | Yes | The card that was clicked. |
// Using the InsiderAppCards client directly
InsiderAppCards appCards = Insider.Instance.appCards();
appCards.click(card);
// Or using the convenience method on the card
card.click();// Using the InsiderAppCards client directly
val appCards = Insider.Instance.appCards()
appCards.click(card)
// Or using the convenience method on the card
card.click()view
public void view(InsiderAppCard appCard)fun view(appCard: InsiderAppCard): UnitLogs a view conversion event for a card.
Name | Type | Required | Description |
|---|---|---|---|
appCard | InsiderAppCard | Yes | The card that was viewed. |
// Using the InsiderAppCards client directly
InsiderAppCards appCards = Insider.Instance.appCards();
appCards.view(card);
// Or using the convenience method on the card
card.view();// Using the InsiderAppCards client directly
val appCards = Insider.Instance.appCards()
appCards.view(card)
// Or using the convenience method on the card
card.view()clickButton
public void clickButton(InsiderAppCardButton button)fun clickButton(button: InsiderAppCardButton): UnitLogs a button click action event and executes the button's action (if available).
Name | Type | Required | Description |
|---|---|---|---|
button | InsiderAppCardButton | Yes | The button that was clicked. |
// Using the InsiderAppCards client directly
InsiderAppCards appCards = Insider.Instance.appCards();
appCards.clickButton(button);
// Or using the convenience method on the button
button.click();// Using the InsiderAppCards client directly
val appCards = Insider.Instance.appCards()
appCards.clickButton(button)
// Or using the convenience method on the button
button.click()Full Integration Example
A complete example showing how to retrieve, display, interact with, and manage cards.
InsiderAppCards appCards = Insider.Instance.appCards();
appCards.getCampaigns(new AppCardsCampaignsCallback() {
@Override
public void onComplete(InsiderAppCardCampaignsResponse responseObject, AppCardsException error) {
if (error != null) {
Log.e("AppCards", "Failed to get campaigns: " + error.getCode(), error);
return;
}
List<InsiderAppCard> cards = responseObject.getAppCards();
for (InsiderAppCard card : cards) {
// Log view event
card.view();
// Display card content
InsiderAppCardContent content = card.getContent();
if (content != null) {
displayCard(content.getTitle(), content.getDescription());
}
// Display images
List<InsiderAppCardImage> images = card.getImages();
if (images != null) {
for (InsiderAppCardImage image : images) {
loadImage(image.getUrl());
}
}
// Handle buttons
List<InsiderAppCardButton> buttons = card.getButtons();
if (buttons != null) {
for (InsiderAppCardButton button : buttons) {
addButton(button.getText(), () -> button.click());
}
}
// Handle card-level action
InsiderAppCardDeeplinkAction action = card.getAction();
if (action != null) {
String url = action.getUrl();
String urlType = action.getDeeplinkURLType();
Log.d("AppCards", "Action URL: " + url + " Type: " + urlType);
}
// Mark as read when user views
if (!card.isRead()) {
card.markAsRead(readError -> {
if (readError == null) {
Log.d("AppCards", "Marked as read: " + card.getId());
}
});
}
}
}
});val appCards = Insider.Instance.appCards()
appCards.getCampaigns { responseObject, error ->
if (error != null) {
Log.e("AppCards", "Failed to get campaigns: ${error.code}", error)
return@getCampaigns
}
val cards = responseObject?.getAppCards() ?: return@getCampaigns
for (card in cards) {
// Log view event
card.view()
// Display card content
card.getContent()?.let { content ->
displayCard(content.getTitle(), content.getDescription())
}
// Display images
card.getImages()?.forEach { image ->
loadImage(image.getUrl())
}
// Handle buttons
card.getButtons()?.forEach { button ->
addButton(button.getText()) { button.click() }
}
// Handle card-level action
card.getAction()?.let { action ->
val url = action.getUrl()
val urlType = action.getDeeplinkURLType()
Log.d("AppCards", "Action URL: $url Type: $urlType")
}
// Mark as read when user views
if (!card.isRead()) {
card.markAsRead { readError ->
if (readError == null) {
Log.d("AppCards", "Marked as read: ${card.getId()}")
}
}
}
}
}