Personyze Personyze developer docs
Open Personyze
Mobile SDKs

Android SDK reference

Every class and method of the Personyze Android SDK 2.1.

Personyze developer documentation Questions: support@personyze.com

Every public class of the Personyze Android SDK 2.1, in the package com.personyze.android (the composable is in com.personyze.android.compose). How to put them together is in the Android SDK guide.

None of these throw for a network or server problem. A failed call answers an empty result with its error set, and every failure reaches the error listener. Only programming errors throw, such as an empty API key or a baseUrl that is not https://.

Personyze

The entry point: an object that forwards every call to the client created by initialize.

Member
initialize(context: Context, config: PersonyzeConfig): PersonyzeClient Creates the client. Call it once, in Application.onCreate. Called again with the same settings it changes nothing; with others (another key) it replaces the client.
isInitialized: Boolean Whether initialize has been called.
client: PersonyzeClient The client itself, with the same members as Personyze, and diagnostics(): String: the stored state with the key and the push token left out or cut short, for a support case. Throws IllegalStateException before initialize.
result: StateFlow<PersonyzeResult> The current decision. Every response updates it, and it is restored when the app starts.
visitor: StateFlow<PersonyzeVisitor> The current visitor and session.
pushStatus: StateFlow<PersonyzePushStatus> Where push stands on this install: see PersonyzePushStatus.
suspend navigate(document: String, events: (PersonyzeEvents.() -> Unit)? = null): PersonyzeResult The visitor opened a screen: logs a page view and answers what to present there, in one request. The events in the block run first and go in the same request. Call it once per screen entry.
suspend refresh(): PersonyzeResult Sends what is queued and answers the current decision with the response's changes. With nothing queued, it answers the current decision without a request.
suspend flush() Sends what is queued now, instead of waiting for the automatic send.
setUserId(userId: String?), setUserId(userId: Long) Identifies the visitor with your own user id, after login. null logs out, back to the installation's anonymous visitor.
startNewSession() Starts a new session with the next request. A session otherwise lasts 90 minutes from its start.
suspend reset() A new anonymous visitor; everything stored for the old one is deleted (session, queued events, decision, history).
suspend clearCache() Forgets the cached action and campaign templates and loads them again. Normally never needed.
reportExecuted(actionId: Int) The action was shown.
reportEngaged(actionId: Int) The visitor tapped the action's call to action: the Clicks criterion of an A/B test, and only that.
reportClosed(actionId: Int, dontShowForSessions: Int = 0) The visitor closed the action; with a number above 0 it is not presented again for that many sessions.
reportProductClicked(actionId: Int, productId: String), reportArticleClicked(actionId: Int, articleId: String) The visitor tapped a product or an article the action recommended.
reportError(actionId: Int, message: String) The action could not be presented.
report(click: PersonyzeClick) Reports a tap, as the renderers do.
suspend checkNotifications(): PersonyzeNotification? Checks for a notification now, outside the schedule, and shows it. Answers what was shown, or null.
setNotificationsEnabled(enabled: Boolean) Turns the notifications on or off: the periodic check, and the device's push registration. Turned off, Personyze stops pushing to the device.
setPushToken(token: String) The token Firebase Cloud Messaging gave the app. Pass it from your FirebaseMessagingService.onNewToken, and each time the app comes to the front (FirebaseMessaging.getInstance().token). Personyze then pushes this visitor's notifications to the device at once, when the account has uploaded its Firebase service account.
handlePushMessage(data: Map<String, String>): Boolean A push message, as your FirebaseMessagingService.onMessageReceived gets it (message.data). If it is Personyze's, the SDK shows it, reports it shown and answers true. It waits for the pictures, 15 seconds at most. Anything else answers false and is yours to handle.
suspend verdict(conditionId: Int): Result<PersonyzeVerdict> Who is winning the A/B test of a campaign.

Called before initialize, the events and reports are ignored (and logged), and the suspend calls answer an empty result.

Events

Each call queues one event and returns at once; all are safe to call from any thread. The queue goes out with the next navigate, or by itself 3 seconds after the last event, or when the app goes to the background. Product and article ids are the Internal ID in your catalog. actionId attributes the event to the action that showed the item: with it, a purchase counts for the Products purchased criterion of that action's A/B test.

Event
setProfile(field: String, value: String?) A profile field: email, first_name, or any field of your own.
setProfile(fields: Map<String, String?>) Several profile fields at once.
productViewed(productId: String, actionId: Int? = null)
productAddedToCart(productId: String, actionId: Int? = null, quantity: Int? = null)
productRemovedFromCart(productId: String, actionId: Int? = null, quantity: Int? = null)
productLiked(productId: String, actionId: Int? = null) Added to a wishlist or favorites.
productUnliked(productId: String, actionId: Int? = null) Removed from the wishlist.
productPurchased(productId: String, actionId: Int? = null, quantity: Int? = null)
productsPurchased() Everything reported added to cart was purchased.
productsRemovedFromCart() The cart was emptied.
productsUnliked() The wishlist was emptied.
articleViewed(articleId: String, actionId: Int? = null)
articleLiked, articleCommented, articleUnliked The same parameters.
articleGoal(articleId: String, actionId: Int? = null) The visitor reached the article's goal.
articlesUnliked()
promotionViewed(promotionId: String, actionId: Int) A card of a promotions action came into view. promotionId is the card's data-personyze-click-target="promotions <id>".
promotionClicked(promotionId: String, actionId: Int)
codeRevealed(promotionId: String, actionId: Int) The visitor revealed the promotion's coupon code.
couponUsed(code: String) A coupon code was redeemed.
track(command: List<String>) Any tracker command, sent as given, in a request of its own.

A blank id, or a promotion without its action id, is not sent: the call is ignored and the error listener gets a PersonyzeException.Invalid.

PersonyzeConfig

The settings, built with a block:

PersonyzeConfig("YOUR_API_KEY") {
    notifications = true
    timeout = 3.seconds
}
Setting Default
baseUrl https://app.personyze.com Where the API is. https:// only.
assetsUrl https://counter.personyze.com/ Where Personyze's WebView library is served from.
timeout 5 seconds The time a decision may take, every attempt included. A slower one fails, and the app shows its default.
backgroundTimeout 10 seconds The same for what no screen waits for: queued events, templates, notifications.
retries 1 0 or 1. A retry happens only after a connection failure, a timeout or a server error, and only within the time limit.
notifications false Show notifications from "Web Push Send" actions. The app must declare POST_NOTIFICATIONS.
notificationChannelName Recommendations The notification channel's name in the system settings.
notificationSmallIcon the SDK's bell A drawable resource for the status bar, used when the message has no badge of its own.
autoFlushDelay 3 seconds How long queued events wait for more before going out by themselves. null: only with the next navigate, a flush(), or the app going to the background.
storageName default Keeps a separate visitor and state under this name: for a second account. Letters, digits, - and _.
okHttpClient none An OkHttpClient of your own, for a proxy or certificate pinning. An interceptor of yours that logs headers would log the API key.
onError none A PersonyzeErrorListener.

PersonyzeResult

What Personyze decided for the visitor: the campaigns they match and the actions to present. navigate replaces it; events and reports sent without a navigation add to it, and remove what Personyze withdrew.

Member
actions: List<PersonyzeAction> The actions to present, in the order Personyze sent them.
conditions: List<PersonyzeCondition> The campaigns the visitor matches, for logic of your own.
has(actionId: Int): Boolean Whether this action was decided. What an A/B test in your own code branches on.
action(actionId: Int): PersonyzeAction? The action, if it was decided.
firstOf(vararg actionIds: Int): Int? The first of these actions that was decided.
actionsIn(placeholder: String): List<PersonyzeAction> The actions targeted to a placeholder, by its name or HTML id in the panel: in placeholder order, and no more than the placeholder holds. Also takes the placeholder's numeric id.
dataFor(actionId: Int): Map<String, String>? An action's per-visitor values.
dismissedActions: List<Int>, dismissedConditions: List<Int> What Personyze withdrew in the last response that was not a navigation.
isEmpty: Boolean No actions and no campaigns.
failed: Boolean, error: PersonyzeException? Whether it is empty because the request failed, and why.
sessionId: String?, cacheVersion: Int The session and the account version it was decided in.
rawJson: String? The response as it came, for anything this class does not model.

PersonyzeAction

An action Personyze decided to present: usually HTML (a banner, a recommendation widget), sometimes JSON or text that you render yourself. The decision and the action's per-visitor data arrive first; the template arrives a moment later and is cached.

Member
id: Int The action's id.
name: String? Its name in the panel.
contentType: String? text/html for banners and recommendation widgets, application/json for a JSON feed.
isHtml: Boolean, isJson: Boolean The same, as flags.
isLoaded: Boolean Whether the template has arrived. Until then content is null, and the result updates again when it comes.
content: String? The content, ready to use.
data: Map<String, String> The values Personyze computed for this visitor: product lists, texts.
placeholders: List<PersonyzePlaceholder> The placeholders it is targeted to.
placeholderOrder: Int? Its order among the actions in a placeholder; null means last.
libs: List<String> The helper scripts its HTML needs.
contentJsonArray(): List<Map<String, String>>? For a JSON feed: its rows, every value as text.
contentHtmlDocument(): String? For an HTML action: a complete page that runs it in a WebView of your own, with Personyze's library and click handling.
reportExecuted(), reportEngaged(), reportClosed(dontShowForSessions: Int = 0), reportProductClicked(productId: String), reportArticleClicked(articleId: String), reportError(message: String) The reports of this action.

PersonyzeCondition

A campaign the visitor matches: id: Int, and name: String?, its name in the panel.

PersonyzePlaceholder

A placeholder an action is targeted to. In an app, a named slot of your own.

Member
id: Int
name: String Its name in the panel.
htmlId: String The HTML id or selector set in the panel.
unitsCountMax: Int How many actions it holds; 0 means no limit.

PersonyzeActionView

A View (a FrameLayout) that renders an HTML action in a WebView and reports what happens in it. It can be created in code or in a layout.

Member
render(action: PersonyzeAction) Shows the action. The same action with the same content again does nothing, so it is safe to call on every update.
clear() Shows nothing.
destroy() Releases the WebView. Call it when the screen is gone; the view can render again afterwards.
action: PersonyzeAction? The action shown.
onClick: PersonyzeClickListener? Called for each tap, after it is reported.
reportExecuted: Boolean Report the action shown once its page has loaded. Default true.
reportClicks: Boolean Report the taps. Default true.
autoHeight: Boolean Take the content's height when the view's height is not fixed. Default true.

A tap that the click listener does not handle does the default: a link opens in the browser, and a close hides the view.

PersonyzeActionContent

The Compose version of PersonyzeActionView, in personyze-android-compose:

@Composable
fun PersonyzeActionContent(
    action: PersonyzeAction,
    modifier: Modifier = Modifier,
    reportExecuted: Boolean = true,
    reportClicks: Boolean = true,
    onClick: ((PersonyzeClick) -> Boolean)? = null
)

It takes the content's height unless modifier sets one, and releases its WebView when it leaves the composition. onClick returns true when the app handled the tap.

PersonyzeClick

A tap inside a rendered action.

Member
actionId: Int
kind: PersonyzeClick.Kind TARGET (the call to action), CLOSE (a close or "don't show again" button), PRODUCT or ARTICLE (a recommended item).
href: String The link's address when a link was tapped, else empty.
productId: String?, articleId: String? The item's Internal ID, for PRODUCT and ARTICLE.
dontShowForSessions: Int For CLOSE: how many sessions not to show the action again; 0 just closes it.

PersonyzeClickListener is the handler: fun onClick(click: PersonyzeClick): Boolean, returning true when the app handled the tap.

PersonyzeVisitor

Who Personyze is talking about right now, from Personyze.visitor.

Member
userId: String? The id set with setUserId, or null for the installation's anonymous visitor.
visitorId: Int? The id Personyze files the visitor under: your numeric user id, a number made from a text one, or the installation's own.
sessionId: String? The current session, or null before the first request.

PersonyzeNotification

A notification the SDK showed, as checkNotifications() answers it: messageId, title, body, url (where a tap goes), imageUrl, iconUrl, badgeUrl, buttons (each with title, iconUrl and url), silent, renotify, and vibrate (a pattern in milliseconds).

PersonyzePushStatus

Where push stands on this install, from Personyze.pushStatus: what a screen of your app, or a support case, can show when notifications do not arrive at once. Its toString() cuts the token short.

Member
token: String? The token the app passed on with setPushToken, or null.
registeredVisitorId: Int? The visitor Personyze has this device registered for, or null.
registeredAtMs: Long When it was last registered, in milliseconds since the epoch; 0 for never.
pushed: Boolean Whether Personyze pushes to this device: the account has uploaded its Firebase service account.
State What it means
No token The app has not passed one on. Notifications appear when the app checks.
A token, no registeredVisitorId Not registered yet. That happens after the app's first request (a navigate, events or a refresh), and again after a login or logout. Or notifications are turned off.
Registered, pushed false The account has no Firebase service account in the panel (Settings › Integrations › App push). The device is registered all the same, so a key added later reaches it.
pushed true A campaign's notification reaches this device at once.

PersonyzeVerdict

Who is winning an A/B test, as verdict(conditionId) answers it. The same comparison the panel shows; see ab_test for what each value means.

Member
conditionId: Int, conditionName: String The campaign.
hasWinner: Boolean True only when every goal passed its thresholds and they all name the same arm.
winnerActiongroupId: Int? The winning arm.
message: String Why there is no winner yet, in words; empty once there is one.
controlGroupRotation: Double, maxDurationReached: Boolean
goals: List<PersonyzeVerdict.Goal> Per goal: title, best and comparedTo (arms), significancePrc, improvementPrc (in percentage points), the thresholds, reached, summary, and every arm's numbers in groups.
rawJson: String The response as it came.

PersonyzeException

What the error listener receives, and what PersonyzeResult.error holds. The SDK never throws these at your code. No message ever contains the API key.

Type
PersonyzeException.Auth Personyze rejected the API key (HTTP 401). Check it in Settings › Integrations.
PersonyzeException.BadRequest Personyze refused the request. status is the HTTP status, text the reason, such as No Product ID specified. Retrying cannot help.
PersonyzeException.Transport No answer to act on. kind says why: OFFLINE, CONNECTION, TIMEOUT, SERVER, RATE_LIMITED (the account's tracking is paused; the SDK waits 10 minutes before asking again), MALFORMED_RESPONSE. status is the HTTP status, when there was one.
PersonyzeException.Delivery Events were dropped rather than sent. commands lists them, and reason says why: AMBIGUOUS (the request may have reached Personyze, so it is not sent twice), INTERRUPTED (the app stopped while it was being sent), EXPIRED (it waited more than a day for a network), OTHER_VISITOR, OTHER_SESSION, OVERFLOW (too many were waiting), REFUSED.
PersonyzeException.Invalid The SDK refused a call before sending it, such as a blank product id.

PersonyzeErrorListener

Receives every failure the SDK absorbs, on a background thread:

fun interface PersonyzeErrorListener
{   fun onError(error: PersonyzeException, context: PersonyzeErrorContext)
}

PersonyzeErrorContext says where it happened: operation (navigate, refresh, flush, metadata, notifications, verdict or track), and how many events were deferred (kept to send later) or dropped.