> For the complete documentation index, see [llms.txt](https://docs.amply.tools/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.amply.tools/reference/sdk-android.md).

# Android SDK

Public API surface for the Amply Android SDK. Kotlin signatures are copied verbatim from the source.

## At a glance

| Group           | Function                                                                                                                                                                  |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 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)`                                                                                                                                      |
| System events   | `setSystemEventsListener(listener)`                                                                                                                                       |
| Data inspection | `getRecentEvents(limit)`, `getDataSetSnapshot(type)`                                                                                                                      |
| Logging         | `setLogLevel(level)`, `getLogLevel()`, `setLogListener(listener)`                                                                                                         |

## 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:

| Name          | Type                      | Required | Description                                                              |
| ------------- | ------------------------- | -------- | ------------------------------------------------------------------------ |
| `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.

```kotlin
class AmplyConfig(
    val appId: String,
    val apiKeyPublic: String,
    val apiKeySecret: String,
    val defaultConfig: String?,
    val configBaseUrl: String? = null,
    val backendBaseUrl: String? = null,
)
```

| Name             | Type      | Required       | Description                                                                                      |
| ---------------- | --------- | -------------- | ------------------------------------------------------------------------------------------------ |
| `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.

```kotlin
val config = amplyConfig {
    api {
        appId = "your.app.id"
        apiKeyPublic = "your-public-key"
        apiKeySecret = "your-secret-key"
    }
    network {
        configBaseUrl = "https://config.example.com"
        backendBaseUrl = "https://events.example.com"
    }
    defaultConfig = "{ ... }"
}
```

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.

| Name         | Type               | Required | Description                                 |
| ------------ | ------------------ | -------- | ------------------------------------------- |
| `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](/developer-guide/gating-actions.md) 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.

| Name         | Type               | Required | Description                     |
| ------------ | ------------------ | -------- | ------------------------------- |
| `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)`

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.

| Name        | Type                | Required | Description                                              |
| ----------- | ------------------- | -------- | -------------------------------------------------------- |
| `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`.    |

### `sealed class GateDecision`

| Variant                                       | Meaning                                                                     |
| --------------------------------------------- | --------------------------------------------------------------------------- |
| `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`

```kotlin
interface CampaignPresenter {
    fun present(params: Map<String, String>, info: Map<String, Any>, resolution: CampaignResolution)
    fun dismiss()
}
```

`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:

```kotlin
resolution.resolve(CampaignResult.Completed)    // value-exchange satisfied → proceeds (ProceedReason.Completed)
resolution.resolve(CampaignResult.Dismissed)    // user backed out → honors the onAbort policy
resolution.resolve(CampaignResult.Unavailable)  // couldn't run (no fill / error) → fail-open
```

`CampaignResult`: `Completed` / `Dismissed` / `Unavailable`.

## User attributes

### `fun setUserId(userId: String?)`

Associate subsequent events with a user identifier.

| Name     | Type      | Required | Description                                 |
| -------- | --------- | -------- | ------------------------------------------- |
| `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.

| Name    | Type     | Required | Description                                                                     |
| ------- | -------- | -------- | ------------------------------------------------------------------------------- |
| `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.

| Name         | Type               | Required | Description               |
| ------------ | ------------------ | -------- | ------------------------- |
| `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.

| Name  | Type     | Required | Description   |
| ----- | -------- | -------- | ------------- |
| `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.

| Name  | Type     | Required | Description             |
| ----- | -------- | -------- | ----------------------- |
| `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)`

Register a handler that receives campaign deep link URLs.

| Name       | Type               | Required | Description                                            |
| ---------- | ------------------ | -------- | ------------------------------------------------------ |
| `listener` | `DeepLinkListener` | yes      | Handler implementing `onDeepLink(url, info): Boolean`. |

Returns `Unit`. Multiple listeners can be registered; each is invoked in registration order.

### `interface DeepLinkListener`

```kotlin
interface DeepLinkListener {
    fun onDeepLink(url: String, info: Map<String, Any>): Boolean
}
```

Return `true` if your code handled the URL; `false` to allow other listeners to handle it.

## System events

### `fun setSystemEventsListener(listener: SystemEventsListener)`

Receive SDK lifecycle events (session start, config fetch, campaign shown).

| Name       | Type                   | Required | Description                               |
| ---------- | ---------------------- | -------- | ----------------------------------------- |
| `listener` | `SystemEventsListener` | yes      | Handler with one `onEvent(event)` method. |

Returns `Unit`. Replaces any previously set listener.

### `interface SystemEventsListener`

```kotlin
interface SystemEventsListener {
    fun onEvent(event: EventInterface)
}
```

## 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.

| Name    | Type  | Required | Description                               |
| ------- | ----- | -------- | ----------------------------------------- |
| `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.

| Name   | Type          | Required | Description       |
| ------ | ------------- | -------- | ----------------- |
| `type` | `DataSetType` | yes      | Dataset selector. |

Returns `Map<String, Any>`.

### `sealed class DataSetType`

| Variant                                                        | Value             | Contents                                                                          |
| -------------------------------------------------------------- | ----------------- | --------------------------------------------------------------------------------- |
| `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.

| Name    | Type       | Required | Description                                           |
| ------- | ---------- | -------- | ----------------------------------------------------- |
| `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?)`

Install a handler that receives every SDK log entry above the current level. Pass `null` to remove the existing listener.

| Name       | Type           | Required | Description                                      |
| ---------- | -------------- | -------- | ------------------------------------------------ |
| `listener` | `LogListener?` | yes      | Handler with `onLog(entry)`, or `null` to clear. |

Returns `Unit`.

### `interface LogListener`

```kotlin
interface LogListener {
    fun onLog(entry: LogEntry)
}
```

### `data class LogEntry`

| Field       | Type                | Description                                                      |
| ----------- | ------------------- | ---------------------------------------------------------------- |
| `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`

| Value   | Int level |
| ------- | --------- |
| `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`

| Field        | Type               | Description                               |
| ------------ | ------------------ | ----------------------------------------- |
| `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`:

| Constant                               | Value                   | When it fires                                                                          |
| -------------------------------------- | ----------------------- | -------------------------------------------------------------------------------------- |
| `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](/reference/sdk-ios.md) — Swift surface on the other native platform.
* [React Native SDK reference](/reference/sdk-react-native.md) — TypeScript surface for RN apps.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.amply.tools/reference/sdk-android.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
