Skip to main content

Integration (Android)

Enabling API-pull in-app messaging is a single config object on top of your normal SDK setup. When it is null (the default), the SDK never issues a fetch, so the feature is off until you opt in. Set the config before PaylisherAndroid.setup(...).

import com.paylisher.android.PaylisherAndroid
import com.paylisher.android.PaylisherAndroidConfig
import com.paylisher.android.PaylisherEngageInAppConfig

val config = PaylisherAndroidConfig(
apiKey = "phc_your_public_sdk_key",
host = "https://your-datastudio-host",
).apply {
// …your other config…

engageInAppConfig = PaylisherEngageInAppConfig(
// Engage usually lives on a different host/prefix than analytics ingestion,
// so set the full URL explicitly (note the `/engage` prefix in most deployments):
fetchEndpoint = "https://api-eu.paylisher.com/engage/v1/push/inapp/fetch",
).apply {
autoFetchOnForeground = true // default
maxMessages = 5
debugLogging = true // turn on while integrating
}
}

PaylisherAndroid.setup(this, config)
Minimum OS version

The pull flow runs on API 29+. On older devices it is inert even with a correct config.

Manual fetch (see Scenarios):

PaylisherAndroid.refreshEngageInAppMessages(context, target = "wallet")
// or, with no screen target:
PaylisherAndroid.refreshEngageInAppMessages(context)

Config reference — PaylisherEngageInAppConfig

Every field is optional. Identity fields are resolved by the SDK / Engage; you normally set only fetchEndpoint (when Engage is on a different host) and the tuning flags.

FieldTypeDefaultPurpose
fetchEndpointString?null{host}/v1/push/inapp/fetchFull absolute URL of the fetch endpoint. Set this when Engage is not on your analytics host (the common case). The ack endpoint is derived as the sibling …/ack.
sdkKeyString?null → SDK apiKeyThe public key Engage uses to resolve your project/source. Override only if the in-app source differs from analytics.
teamId / projectId / sourceIdString?nullOptional explicit identity. Normally omitted — Engage reverse-resolves them from sdkKey.
autoFetchOnForegroundBooleantrueWhen true, the SDK fetches automatically on foreground and on screen change. When false, the SDK never fetches on its own — you drive it with refreshEngageInAppMessages(...).
maxMessagesInt1How many messages a single fetch may return (clamped to 1..5).
debugLoggingBooleanfalseVerbose SDK logs for the fetch / render / ack path.
excludedActivitiesList<String>["Splash"]Activity class-name fragments where a message must not render. Messages are queued and shown on the next non-excluded Activity.
excludedActivities and Jetpack Compose

excludedActivities matches the Activity class name. It works for multi-Activity apps. In a single-Activity Compose app every screen lives under one Activity, so class-name matching cannot tell screens apart — gate screens with the manual, per-screen approach in Scenarios → Don't show on login/splash instead.


Verifying the fetch without a device

Exercise the exact request the SDK makes with curl. Use a fresh distinctId each time (delivered messages are de-duplicated per user):

curl -i -X POST "https://api-eu.paylisher.com/engage/v1/push/inapp/fetch" \
-H "Content-Type: application/json" \
-H "X-SDK-Key: phc_your_public_sdk_key" \
-d '{"distinctId":"probe-1","sdkKey":"phc_your_public_sdk_key","platform":"android","maxMessages":5}'
  • 201 {"messages":[]} → auth is fine, but no campaign matched → see Campaign Setup.
  • 201 {"messages":[{…}]} → the server path works end-to-end → test on device.
  • 401 {"message":"Invalid sdkKey"} → the key does not resolve in this environment → see Troubleshooting.