> ## Documentation Index
> Fetch the complete documentation index at: https://docs.appstack.tech/llms.txt
> Use this file to discover all available pages before exploring further.

# Kotlin API reference

Every public symbol in the `tech.appstack.android-sdk:appstack-android-sdk`
artifact. For installation and integration guidance, see the
[Kotlin SDK guide](/SDKs/kotlin).

Current stable release: **1.11.0**, published 16 September 2026. See the [changelog](/changelog/kotlin) for everything that changed.

## AppstackAttributionSdk

A Kotlin `object`, so every member is called statically. All members carry
`@JvmStatic`, so Java callers use `AppstackAttributionSdk.configure(...)` too.

```kotlin theme={null}
import com.appstack.attribution.AppstackAttributionSdk
```

### configure()

```kotlin theme={null}
public fun configure(
    context: Context,
    apiKey: String,
    logLevel: LogLevel = LogLevel.INFO,
    listener: InitListener? = null,
    customerUserId: String? = null,
)
```

Starts the SDK. Call once from `Application.onCreate()`. A repeat call is a no-op,
including its `customerUserId`, so use [`setCustomerUserId()`](#setcustomeruserid)
to set the ID later.

<ParamField path="context" type="Context" required>
  Application context.
</ParamField>

<ParamField path="apiKey" type="String" required>
  Your app's Appstack API key, from the dashboard under app settings.
</ParamField>

<ParamField path="logLevel" type="LogLevel" default="LogLevel.INFO">
  Logcat verbosity under the tag `AppstackSdk`. See [LogLevel](#loglevel).
</ParamField>

<ParamField path="listener" type="InitListener?" default="null">
  Callbacks for initialization success and failure. See
  [InitListener](#initlistener).
</ParamField>

<ParamField path="customerUserId" type="String?" default="null">
  Your identifier for the signed-in user, when known at launch.
</ParamField>

```kotlin theme={null}
class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        AppstackAttributionSdk.configure(this, apiKey = "your_api_key")
    }
}
```

<Accordion title="Deprecated overloads">
  Three earlier `configure()` shapes remain callable and delegate to the current
  one. Each carries `ReplaceWith("configure(context, apiKey, logLevel, listener, customerUserId)")`,
  so the IDE can migrate them automatically.
</Accordion>

### setCustomerUserId()

```kotlin theme={null}
public fun setCustomerUserId(customerUserId: String?)
```

Sets your own identifier for the signed-in user, so Appstack can join
server-to-server events, which identify the user by this ID rather than by the
install, back to their install.

Prefer this over the `configure()` parameter when the ID is only known after launch,
which is usually the case. It applies to every event sent from here on, including any
`sendEvent()` buffered during startup, but establishes nothing on its own: at least
one event has to follow. Callable from any thread, before or after `configure()`;
last write wins.

<ParamField path="customerUserId" type="String?" required>
  Your identifier for the signed-in user. Set it as soon as it is known.
</ParamField>

```kotlin theme={null}
AppstackAttributionSdk.setCustomerUserId("user_123")  // once login reveals it
```

### sendEvent()

```kotlin theme={null}
public fun sendEvent(event: EventType, name: String?
```

Sends an event. Safe to call before `configure()` completes: events arriving early
are buffered and flushed once configuration finishes.

<ParamField path="event" type="EventType" required>
  The event to send. Prefer a standard case over `CUSTOM` wherever one fits. See
  [EventType](#eventtype).
</ParamField>

<ParamField path="name" type="String?" default="null">
  The event name. Required when `event` is `CUSTOM`, ignored otherwise.
</ParamField>

<ParamField path="parameters" type="Map<String, Any>?" default="null">
  Event properties. For revenue events send `revenue` and `currency`. Matching
  parameters (`email`, `name`, `phone_number`, `date_of_birth`, `gender`) are
  encrypted on device before being used for attribution matching. See
  [enhanced app campaigns](/enhanced-app-campaigns).
</ParamField>

```kotlin theme={null}
AppstackAttributionSdk.sendEvent(EventType.LOGIN)

AppstackAttributionSdk.sendEvent(
    EventType.PURCHASE,
    parameters = mapOf("revenue" to 29.99, "currency" to "USD"),
)

AppstackAttributionSdk.sendEvent(
    EventType.CUSTOM,
    name = "onboarding_finished",
    parameters = mapOf("variant" to "b"),
)
```

### getAppstackId()

```kotlin theme={null}
public fun getAppstackId(): String?
```

Returns the stable local Appstack identity for this install.

<ResponseField name="returns" type="String?">
  The install's Appstack ID, or `null` before the SDK has minted one.
</ResponseField>

### isSdkDisabled()

```kotlin theme={null}
public fun isSdkDisabled(): Boolean
```

Whether the SDK is disabled and sending nothing. It reports `true` before
`configure()` has run, and whenever remote configuration has switched it off.

<ResponseField name="returns" type="Boolean">
  `true` when the SDK is disabled.
</ResponseField>

### isConfigured()

```kotlin theme={null}
public fun isConfigured(): Boolean
```

Whether `configure()` has been called and the SDK's components exist. This says
nothing about whether the SDK is enabled: use [`isEnabled()`](#isenabled) for that.

<ResponseField name="returns" type="Boolean">
  `true` once `configure()` has run.
</ResponseField>

### isEnabled()

```kotlin theme={null}
public fun isEnabled(): Boolean
```

Whether the SDK is configured and remote configuration has it switched on.

<ResponseField name="returns" type="Boolean">
  `true` when the SDK is ready and enabled.
</ResponseField>

### getLastInitError()

```kotlin theme={null}
public fun getLastInitError(): Throwable?
```

The most recent initialization failure, for apps that prefer polling over an
[InitListener](#initlistener).

<ResponseField name="returns" type="Throwable?">
  The last initialization error, or `null` if there has not been one.
</ResponseField>

### handleAppLink()

```kotlin theme={null}
public fun handleAppLink(intent: Intent, options: LinkOptions

public fun handleAppLink(uri: Uri, options: LinkOptions
```

Handles a tapped App Link for an app that is already installed, parsing the
`deeplinkId` and query parameters directly off the URI with no network round trip.
Safe to call before `configure()`.

<Note>
  The OS intercepts this tap, so no click event is recorded server-side. If you want
  to count it as re-engagement, call `sendEvent()` yourself.
</Note>

<ParamField path="uri" type="Uri" required>
  The tapped link. The `Intent` overload reads `intent.data` for you, so you can
  pass the intent straight from `onCreate()` or `onNewIntent()`.
</ParamField>

<ParamField path="options" type="LinkOptions" default="LinkOptions()">
  Optional host filtering. See [LinkOptions](#linkoptions).
</ParamField>

<ResponseField name="returns" type="AppLinkResult?">
  The parsed link, or `null` when the URI is not a recognised Appstack link.
</ResponseField>

```kotlin theme={null}
override fun onNewIntent(intent: Intent) {
    super.onNewIntent(intent)
    AppstackAttributionSdk.handleAppLink(intent)?.let { link ->
        route(link.deeplinkId, link.queryParams)
    }
}
```

### getAttributionParams()

```kotlin theme={null}
public fun getAttributionParams(rawReferrer: String?
```

Returns the attribution parameters known right now, without waiting. Use
[`awaitAttributionParams()`](#awaitattributionparams) when the match may still be in
flight.

<ParamField path="rawReferrer" type="String?" default="null">
  An Install Referrer string to merge in, when your app already holds one.
</ParamField>

<ResponseField name="returns" type="Map<String, String>">
  Attribution parameters, empty when none are known yet.
</ResponseField>

### awaitAttributionParams()

```kotlin theme={null}
public suspend fun awaitAttributionParams(rawReferrer: String?
```

Suspends until the initial attribution match finishes, then returns the parameters.
Prefer this over a fixed delay after launch.

<ParamField path="rawReferrer" type="String?" default="null">
  An Install Referrer string to merge in, when your app already holds one.
</ParamField>

<ResponseField name="returns" type="Map<String, String>">
  Attribution parameters once the match phase has completed.
</ResponseField>

```kotlin theme={null}
lifecycleScope.launch {
    val params = AppstackAttributionSdk.awaitAttributionParams()
}
```

### deleteUserData()

```kotlin theme={null}
public suspend fun deleteUserData()
```

Permanently deletes this install's Appstack data, for GDPR and privacy requests. On
success, locally cached attribution data is cleared too.

### refreshConfig()

```kotlin theme={null}
public suspend fun refreshConfig()
```

Re-fetches remote configuration. The SDK does this itself at startup, so this is
only for apps that need to pick up a configuration change mid-session.

## Types

### EventType

```kotlin theme={null}
public enum class EventType
```

Standard attribution events. Names follow the SNAKE\_CASE convention used by mobile
measurement partners, and the value sent over the wire is the name itself. Where two
names are synonymous, both are provided for compatibility with existing
integrations.

| Group        | Cases                                                                                         |
| ------------ | --------------------------------------------------------------------------------------------- |
| Lifecycle    | `INSTALL`                                                                                     |
| Auth         | `LOGIN`, `SIGN_UP`, `REGISTER`                                                                |
| Monetization | `PURCHASE`, `ADD_TO_CART`, `ADD_TO_WISHLIST`, `INITIATE_CHECKOUT`, `START_TRIAL`, `SUBSCRIBE` |
| Games        | `LEVEL_START`, `LEVEL_COMPLETE`                                                               |
| Engagement   | `TUTORIAL_COMPLETE`, `SEARCH`, `VIEW_ITEM`, `VIEW_CONTENT`, `SHARE`                           |
| Catch-all    | `CUSTOM`                                                                                      |

<Note>
  `INSTALL` is tracked by the SDK itself. You do not need to send it.
</Note>

### LogLevel

```kotlin theme={null}
public enum class LogLevel { DEBUG, INFO, WARN, ERROR, NONE }
```

Verbosity of the SDK's integrator-facing logcat output, under the tag `AppstackSdk`.
`NONE` silences the SDK entirely. Defaults to `INFO`.

### LinkOptions

```kotlin theme={null}
public class LinkOptions @JvmOverloads constructor(
    allowedHosts: Set<String>? = null,
) {
    public val allowedHosts: Set<String>?
}
```

Optional filtering for incoming links. Requires no network access or SDK
initialization.

<ResponseField name="allowedHosts" type="Set<String>?" default="null">
  Hosts to accept. A link on any other host returns `null`. `null` accepts any host.
  This does not verify domain ownership: your app decides what to route.
</ResponseField>

### AppLinkResult

```kotlin theme={null}
public data class AppLinkResult(
    val deeplinkId: String?,
    val queryParams: Map<String, String>,
    val uri: Uri,
)
```

A tapped App Link on an already-installed app, parsed entirely from the URI.

<ResponseField name="deeplinkId" type="String?">
  The single path segment of the tapped standard link, matching the `deeplink_id`
  generated server-side, as in `https://links.customer.com/{deeplinkId}`.
</ResponseField>

<ResponseField name="queryParams" type="Map<String, String>">
  Query parameters on the tapped URL, percent-decoded, with the last value winning
  for a repeated name. Missing values become empty strings. Includes any custom
  parameter a marketer attached to the link, such as `deep_link_path`.
</ResponseField>

<ResponseField name="uri" type="Uri">
  The full tapped URI.
</ResponseField>

### InitListener

```kotlin theme={null}
public fun interface InitListener {
    public fun onError(t: Throwable)
    public fun onInitialized(mainThreadDurationMs: Long, totalDurationMs: Long) {}
}
```

Callbacks for observing the outcome of `configure()`. As a `fun interface`, a lambda
passed to `configure()` implements `onError`. Implement the interface explicitly when
you also need `onInitialized`.

<ResponseField name="onError" type="(Throwable) -> Unit">
  Invoked when initialization hits an error, such as a failed remote config fetch.
  After an authentication failure or a missing required install-time permission the
  SDK disables itself; for other errors initialization continues with a placeholder
  config. May be invoked on a background thread.
</ResponseField>

<ResponseField name="onInitialized" type="(Long, Long) -> Unit">
  Invoked on the main thread once initialization has fully completed, including the
  remote config fetch. `mainThreadDurationMs` is wall-clock time spent in the
  synchronous part of `configure()`; `totalDurationMs` runs from the `configure()`
  call until full initialization completed. Has a default empty implementation, so
  overriding it is optional.
</ResponseField>

### HttpException

```kotlin theme={null}
public class HttpException(public val code: Int) : RuntimeException
```

A non-success HTTP response from the backend. `code` carries the status.

### AuthenticationException

```kotlin theme={null}
public class AuthenticationException(public val code: Int) : RuntimeException
```

The API key was rejected. The SDK disables itself when this happens.
