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)
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.
| Field | Type | Default | Purpose |
|---|---|---|---|
fetchEndpoint | String? | null → {host}/v1/push/inapp/fetch | Full 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. |
sdkKey | String? | null → SDK apiKey | The public key Engage uses to resolve your project/source. Override only if the in-app source differs from analytics. |
teamId / projectId / sourceId | String? | null | Optional explicit identity. Normally omitted — Engage reverse-resolves them from sdkKey. |
autoFetchOnForeground | Boolean | true | When 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(...). |
maxMessages | Int | 1 | How many messages a single fetch may return (clamped to 1..5). |
debugLogging | Boolean | false | Verbose SDK logs for the fetch / render / ack path. |
excludedActivities | List<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 ComposeexcludedActivities 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.