Android SDK
Public API surface for the Amply Android SDK. Kotlin signatures are copied verbatim from the source.
At a glance
Initialization
Amply(config, application), AmplyConfig(...), amplyConfig { ... }
Event tracking
track(event, properties)
User attributes
setUserId(userId), setCustomProperty(key, value), setCustomProperties(properties), getCustomProperty(key), removeCustomProperty(key), clearCustomProperties()
Deeplinks
registerDeepLinkListener(listener) → token, removeDeepLinkListener(token)
System events
setSystemEventsListener(listener) → token, clearSystemEventsListener(token)
Data inspection
getRecentEvents(limit), getDataSetSnapshot(type)
Logging
setLogLevel(level), getLogLevel(), setLogListener(listener)
Detaching a listener
Registering a listener returns a token. Keep it — passing that token back is how you detach:
val token = amply.registerDeepLinkListener(router)
// later, when whatever owns `router` goes away:
amply.removeDeepLinkListener(token)Detaching with a token that is no longer the current registration does nothing. That is deliberate: if a screen is replaced by a new one that registers first, the departing screen cannot silence its replacement on the way out.
Who needs to do this. A listener set up once at launch and kept for the life of the app never has to detach. Anything shorter-lived does — a screen, a feature module. A listener left attached after its owner is gone keeps that owner alive and the SDK keeps calling it.
Detach where your teardown actually runs. Do not rely on the object's deallocation hook: while the SDK still holds the listener, that hook does not run. Use whatever explicit teardown point your host gives you.
Gates work the same way. registerGate returns a token and unregisterGate takes it. A gate left registered by a screen that has gone away makes the next gated call on that URL wait out its full timeout with nothing on screen.
Initialization
class Amply(val config: AmplyConfig, val application: Application)
Construct the SDK. Construction is initialization — the init block wires internal components, starts the first session, and begins tracking the activity lifecycle. No separate initialize() call is required.
Parameters:
config
AmplyConfig
yes
Credentials and optional network overrides.
application
android.app.Application
yes
Application instance used for lifecycle callbacks, storage, and context.
Hold the returned instance for the lifetime of the process (commonly on the Application subclass).
class AmplyConfig
Credential and network configuration.
appId
String
yes
Application identifier from the Amply dashboard.
apiKeyPublic
String
yes
Public API key.
apiKeySecret
String
yes
Secret API key. Keep it out of source control.
defaultConfig
String?
yes (nullable)
JSON string of a fallback configuration used until the remote config loads. Pass null to skip.
configBaseUrl
String?
no
Override for the configuration service base URL.
backendBaseUrl
String?
no
Override for the events backend base URL.
fun amplyConfig(initializer: AmplyConfigBuilder.() -> Unit): AmplyConfig
Kotlin DSL for building an AmplyConfig. Enforces that appId, apiKeyPublic, and apiKeySecret are non-null and throws IllegalArgumentException otherwise.
The api { } block sets credentials; the network { } block sets optional overrides. Returns a fully validated AmplyConfig.
Event tracking
fun track(event: String, properties: Map<String, Any> = emptyMap())
Record a custom event.
event
String
yes
Event name.
properties
Map<String, Any>
no
Event properties. Defaults to emptyMap().
Returns Unit. Events are persisted locally and flushed by the SDK; no network call is tied to this call site.
Gating
Gate a user-facing step on a campaign's outcome — for example, a rewarded ad before an export. See Gating actions for the full flow.
suspend fun trackGated(event: String, properties: Map<String, Any> = emptyMap()): GateDecision
Track an event and suspend until any gating campaign on it resolves, then return the decision. If no gate applies, returns GateDecision.Proceed(ProceedReason.FailOpen) immediately. Call from a coroutine.
event
String
yes
Event name a campaign may gate.
properties
Map<String, Any>
no
Event properties.
fun registerGate(baseUrl: String, presenter: CampaignPresenter, onAbort: AbortPolicy = AbortPolicy.Cancel, timeoutMs: Long = 60_000): ListenerToken
Register the single gate presenter once at startup. The SDK calls the presenter when a gated campaign needs to show UI, and calls its dismiss() if the gate is abandoned.
baseUrl
String
yes
Base URL the gate resolves against.
presenter
CampaignPresenter
yes
Your presenter (see below).
onAbort
AbortPolicy
no
What a user dismiss means. Default AbortPolicy.Cancel.
timeoutMs
Long
no
Fail-open deadline in milliseconds. Default 60_000.
fun unregisterGate(token: ListenerToken)
Withdraws the gate registered with that token. The URL stays gate-able, so a gated call still resolves immediately rather than falling through as an ordinary deeplink - it resolves the way the gate was registered to resolve, and costs the campaign no impression.
A gate registered at launch and kept for the life of the app needs no withdrawal. One owned by something shorter-lived does: the registry outlives whatever registered into it.
sealed class GateDecision
GateDecision.Proceed(reason: ProceedReason)
Do the next step. reason distinguishes a satisfied gate from a fail-open.
GateDecision.Cancelled
User deliberately dismissed a Cancel-policy gate. Suppress the next step.
when (decision) { is GateDecision.Proceed -> … ; is GateDecision.Cancelled -> … }.
enum class ProceedReason
ProceedReason.Completed — the campaign's value-exchange was satisfied (e.g. reward earned). ProceedReason.FailOpen — nothing to wait on, or the gate couldn't run to a decision; do not reward.
enum class AbortPolicy
AbortPolicy.Cancel (default) — a dismiss returns GateDecision.Cancelled (true gating, for value-exchange actions). AbortPolicy.Proceed — a dismiss fails open (for consent-style flows).
interface CampaignPresenter
present shows the gated UI and reports the result through the resolution handle; dismiss tears it down without producing a result (the SDK calls it when the gate is abandoned). Both are required.
CampaignResolution / enum class CampaignResult
The resolution handle passed to present(...) reports the outcome exactly once:
CampaignResult: Completed / Dismissed / Unavailable.
User attributes
fun setUserId(userId: String?)
Associate subsequent events with a user identifier.
userId
String?
yes
Stable user identifier, or null to clear.
Returns Unit. Survives across sessions until changed.
fun setCustomProperty(key: String, value: Any)
Set one custom property on the current user.
key
String
yes
Property key.
value
Any
yes
One of: String, Int, Long, Float, Double, Boolean, DateTimeValue.
Returns Unit. Use DateTimeValue(epochMillis) to persist a value as a datetime rather than as a number.
fun setCustomProperties(properties: Map<String, Any>)
Set multiple custom properties at once.
properties
Map<String, Any>
yes
Keys to supported values.
Returns Unit. Equivalent to calling setCustomProperty per entry.
suspend fun getCustomProperty(key: String): Any?
Read the current value of a custom property.
key
String
yes
Property key.
Returns Any? — the stored value, or null if unset. suspend because storage access runs off the main thread.
fun removeCustomProperty(key: String)
Delete a single custom property.
key
String
yes
Property key to remove.
Returns Unit.
fun clearCustomProperties()
Remove every custom property on the current user. Returns Unit. Takes no parameters.
Deeplinks
fun registerDeepLinkListener(listener: DeepLinkListener): ListenerToken
Register a handler that receives campaign deep link URLs.
listener
DeepLinkListener
yes
Handler implementing onDeepLink(url, info): Boolean.
Returns Unit. Multiple listeners can be registered; each is invoked in registration order.
interface DeepLinkListener
Return true if your code handled the URL; false to allow other listeners to handle it.
A listener that throws is treated as "did not handle it" — the URL still reaches the listeners registered after it.
fun removeDeepLinkListener(token: ListenerToken)
Withdrawing takes the token returned at registration, not the listener object. A token that is no longer the current registration is ignored, so a component being torn down cannot detach the one that replaced it.
Stop sending deep links to a previously registered listener.
listener
DeepLinkListener
yes
The listener to withdraw.
Returns Unit. Registering adds a listener rather than replacing one, so anything you register from an object that can be torn down and rebuilt must be withdrawn when that object goes away — otherwise the old listeners stay registered and every later deep link is delivered to all of them.
System events
fun setSystemEventsListener(listener: SystemEventsListener): ListenerToken
Receive SDK lifecycle events (session start, config fetch, campaign shown).
listener
SystemEventsListener
yes
Handler with one onEvent(event) method.
Returns Unit. Replaces any previously set listener.
interface SystemEventsListener
fun clearSystemEventsListener(token: ListenerToken)
Withdrawing takes the token returned at registration, not the listener object. A token that is no longer the current registration is ignored, so a component being torn down cannot detach the one that replaced it.
Stop sending system events to a previously set listener.
listener
SystemEventsListener
yes
The listener to withdraw.
Returns Unit. The listener is cleared only if it is still the one currently set — so if a replacement has already registered itself, withdrawing the old one leaves the new one in place. Call it when the object you registered is being torn down.
Data inspection
suspend fun getRecentEvents(limit: Int = 30): List<EventInterface>
Fetch the most recent events tracked in the current install. Intended for in-app debug tools.
limit
Int
no
Maximum number of events. Defaults to 30.
Returns List<EventInterface> newest-first.
suspend fun getDataSetSnapshot(type: DataSetType): Map<String, Any>
Return a snapshot of one dataset the SDK uses for targeting.
type
DataSetType
yes
Dataset selector.
Returns Map<String, Any>.
sealed class DataSetType
DataSetType.Device
@device
Advertising ID, model, OS version, locale, timezone.
DataSetType.User
@user
User ID and identity attributes.
DataSetType.Custom
@custom
All custom properties you've set.
DataSetType.Session
@session
Current session metadata.
DataSetType.TriggeredEvent(countStrategy, params, eventName)
@triggeredEvent
Aggregated counts for a specific event. CountStrategy is GLOBAL or SESSION.
DataSetType.Events(data)
@events
Counts for a list of events. Each Event(name, type, params).
Logging
fun setLogLevel(level: LogLevel)
Set the SDK log level.
level
LogLevel
yes
LogLevel.NONE, ERROR, WARN, INFO, or DEBUG.
Returns Unit. Defaults to NONE.
fun setLogLevel(level: String?)
String overload. Accepts "none", "error", "warn", "info", "debug" (case-insensitive). Any other value — including null — maps to NONE. Returns Unit.
fun getLogLevel(): LogLevel
Return the current log level. Takes no parameters.
fun setLogListener(listener: LogListener): ListenerToken
No longer accepts null. Detach with clearLogListener(token).
Install a handler that receives every SDK log entry above the current level. Pass null to remove the existing listener.
listener
LogListener?
yes
Handler with onLog(entry), or null to clear.
Returns Unit.
interface LogListener
data class LogEntry
level
LogLevel
Severity of the entry.
category
String
SDK-assigned category (e.g. "sdk", "session", "deeplink").
message
String
Human-readable message.
timestamp
Long
UTC epoch milliseconds.
details
Map<String, Any>?
Structured context, if provided.
Types
enum class LogLevel
NONE
0
ERROR
1
WARN
2
INFO
3
DEBUG
4
Higher values include all lower-severity entries.
class DateTimeValue(val epochMillis: Long)
Wrapper passed to setCustomProperty to mark a value as a datetime rather than as a number.
interface EventInterface
name
String
Event name.
timestamp
Long
UTC epoch milliseconds.
properties
Map<String, Any>
Event properties.
type
EventType
EventType.CUSTOM or EventType.SYSTEM.
System event names
Well-known values on EventInterface.name when type == EventType.SYSTEM:
SystemEvents.SDK_INITIALIZED
SdkInitialized
SDK finished initialization.
SystemEvents.CONFIG_FETCH_STARTED
ConfigFetchStarted
Remote configuration fetch began.
SystemEvents.CONFIG_FETCH_FINISHED
ConfigFetchFinished
Remote configuration fetch completed.
SystemEvents.SESSION_START
SessionStarted
Session started. properties["type"] is "cold" or "warm".
SystemEvents.SESSION_END
SessionFinished
Session ended.
SystemEvents.CAMPAIGN_SHOWN
CampaignShown
Campaign impression recorded.
SystemEvents.EVENT_TRIGGERED
EventTriggered
A custom event matched a campaign trigger.
SystemEvents.CUSTOM_PROPERTY_CHANGED
CustomPropertyChanged
A custom property was set, updated, removed, or cleared. Usable as a campaign trigger.
SystemEvents.CAMPAIGN_RESOLVED
CampaignResolved
A presented (blocking) campaign action resolved or was skipped (0.5.0+). Stats only.
Related
iOS SDK reference — Swift surface on the other native platform.
React Native SDK reference — TypeScript surface for RN apps.
Last updated