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

<Prompt description="Use Cursor, Claude Code, or another AI to help you integrate the Android (Kotlin) SDK." actions={["copy", "cursor"]}>
  You are an expert Android engineer helping me integrate the Appstack Android SDK (Kotlin) into my app. You are running inside an IDE assistant such as Cursor or Claude Code and you can see my codebase.

  Use the reference below to fully wire the SDK. When I share my Gradle files and app code, you should:

  1. Propose **exact Gradle changes** (repositories and `dependencies { ... }`) using the dependency coordinates below and the **current** artifact version from Maven Central.
  2. Tell me exactly where to initialize the SDK (Application.onCreate) and generate idiomatic Kotlin code that matches my app's structure, using the snippets below.
  3. Wire the documented configuration options (log level, customer user ID) when relevant.
  4. Validate min/target SDK, Java/Gradle versions and any manifest or ProGuard/R8 needs against the requirements below, and point out gaps.
  5. Summarize the full set of steps (install, configure, event tracking) so I can verify everything has been applied.

  ***

  ## Reference: Appstack Android SDK (Kotlin)

  **Requirements**

  * Min SDK: Android 5.0 (API 21), Target SDK: 35+, Java 17+, Gradle 8.0+ (built with Gradle 8.13 / Android Gradle Plugin 8.12)
  * SDK artifact: [Maven Central](https://central.sonatype.com/artifact/tech.appstack.android-sdk/appstack-android-sdk) — use latest version.

  **1. Gradle dependency**

  ```kotlin theme={null}
  dependencies {
      // Resolve the latest from Maven Central, then pin an explicit version for reproducible builds.
      implementation("tech.appstack.android-sdk:appstack-android-sdk:+")
  }
  ```

  Prefer copying a **specific** version from the Maven Central page linked above once you know what you want to ship; avoid leaving `+` in production if your team requires locked versions.

  **2. Initialize in Application.onCreate**

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

  class MyApplication : Application() {
      override fun onCreate() {
          super.onCreate()
          AppstackAttributionSdk.configure(
              context = this,
              apiKey = "your-android-api-key"
          )
      }
  }
  ```

  **3. Full configuration (optional params)**

  ```kotlin theme={null}
  AppstackAttributionSdk.configure(
      context = this,
      apiKey = "your-api-key",
      logLevel = LogLevel.INFO,       // DEBUG, INFO (default), WARN, ERROR, NONE
      customerUserId = "user_123"
  )
  ```

  * Only `context` and `apiKey` are required.
  * For on-device diagnostics use `logLevel = LogLevel.DEBUG` (logcat tag `AppstackSdk`).

  **4. Event tracking**

  * Simple events:

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

  * With parameters (e.g. revenue):

  ```kotlin theme={null}
  AppstackAttributionSdk.sendEvent(
      EventType.PURCHASE,
      parameters = mapOf("revenue" to 29.99, "currency" to "USD")
  )
  ```

  * Custom events:

  ```kotlin theme={null}
  AppstackAttributionSdk.sendEvent(
      EventType.CUSTOM,
      name = "user_attributes",
      parameters = mapOf(
          "email" to "test@example.com",
          "name" to "first_name last_name",
          "phone_number" to "+33060000000",
          "date_of_birth" to "2026-02-01"
      )
  )
  ```

  **EventType values (use standard when possible):** LOGIN, SIGN\_UP/REGISTER, PURCHASE, SUBSCRIBE, ADD\_TO\_CART, ADD\_TO\_WISHLIST, INITIATE\_CHECKOUT, START\_TRIAL, LEVEL\_START, LEVEL\_COMPLETE, TUTORIAL\_COMPLETE, SEARCH, VIEW\_ITEM, VIEW\_CONTENT, SHARE, CUSTOM.

  **Revenue / EAC:** For revenue events send `revenue` or `price` (number) and `currency` (string). For better Meta matching, include when possible: `email`, `name`, `phone_number` (or `phone`/`phoneNumber`), `date_of_birth` (YYYY-MM-DD, or `birthdate`/`birthday`/`dateOfBirth`), `gender`. Appstack automatically encrypts these matching parameters before using them for attribution matching.

  **Limitations:** Init must happen in Application.onCreate before any tracking. Attribution for Play Store installs; network required (events sent before the SDK is ready are buffered and replayed).
</Prompt>

## **Repository**

Here, you will find the [Maven Central Android SDK documentation](https://central.sonatype.com/artifact/tech.appstack.android-sdk/appstack-android-sdk). Please, use the latest version of the SDK available.

## **Quickstart**

Use this path when you only need the minimum production integration:

1. Add the SDK dependency from Maven Central.
2. Copy the **Production** API key from **SDK** in Appstack.
3. Call `AppstackAttributionSdk.configure(...)` from `Application.onCreate()`.
4. Send standard events such as `EventType.LOGIN`, `EventType.SIGN_UP`, `EventType.PURCHASE`, and `EventType.SUBSCRIBE`.
5. Confirm events appear in the Appstack SDK page before enabling downstream integrations.

```kotlin theme={null}
import android.app.Application
import com.appstack.attribution.AppstackAttributionSdk
import com.appstack.attribution.EventType

class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()

        AppstackAttributionSdk.configure(
            context = this,
            apiKey = "your_production_api_key"
        )

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

## **Requirements**

1. Minimum SDK: Android 5.0 (API level 21).
2. Target SDK: 35+
3. Java Version: 17+
4. Gradle: 8.0+ (the SDK is built with Gradle 8.13 and Android Gradle Plugin 8.12)

## **Initial setup**

<Steps>
  <Step title="Installation">
    Add the SDK dependency to your app's `build.gradle.kts`:

    ```kotlin theme={null}
    dependencies {
        // Resolve latest from Maven Central, then prefer pinning an explicit version for release builds.
        implementation("tech.appstack.android-sdk:appstack-android-sdk:+")
    }
    ```

    No additional Gradle configuration is needed after adding the dependency. You still need to initialize the SDK in `Application.onCreate()` before sending events.
  </Step>

  <Step title="Initialization">
    Follow these steps to get the API key:

    1. In Appstack, from the side menu, select **SDK** and ensure you are selecting the correct application.
    2. Select the **Production** environment.
    3. Copy the  **API key**.

    Examples:

    Configure the SDK in your `Application` class:

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

    class MyApplication : Application() {
        override fun onCreate() {
            super.onCreate()

            AppstackAttributionSdk.configure(
                context = this,
                apiKey = "your-android-api-key"
            )
        }
    }
    ```
  </Step>

  <Step title="Configuration parameters" stepNumber={3}>
    <Note>
      Initialize the SDK with your **API key**. Must be called in `Application.onCreate()` before any other SDK methods.
    </Note>

    Parameters:

    * `context` (Context, required): Application context.
    * `apiKey` (String, required): Your Appstack API key.
    * `logLevel` (LogLevel, default: `LogLevel.INFO`): Console log verbosity. One of `DEBUG`, `INFO`, `WARN`, `ERROR`, `NONE`.
    * `listener` (InitListener?, default: null): Optional callback invoked on initialization success or error.
    * `customerUserId` (String?, default: null): Your own user identifier, attached to the event payload.

    Examples:

    ```kotlin theme={null}
    // Minimum configuration — context and the API key are the only required parameters
    AppstackAttributionSdk.configure(
        context = this,
        apiKey = "your-api-key"
    )

    // With optional parameters
    AppstackAttributionSdk.configure(
        context = this,
        apiKey = "your-api-key",
        logLevel = LogLevel.INFO,
        customerUserId = "user_123"
    )
    ```

    <Note>
      `logLevel` only controls logcat output (tag `AppstackSdk`); it does not change what the SDK sends.
    </Note>
  </Step>

  <Step title="Sending events" stepNumber={4}>
    Track user actions and revenue in your activities:

    ```kotlin theme={null}
    // Track events without parameters
    AppstackAttributionSdk.sendEvent(EventType.SIGN_UP)
    AppstackAttributionSdk.sendEvent(EventType.LOGIN)

    // Track events with parameters (including revenue)
    AppstackAttributionSdk.sendEvent(
        EventType.PURCHASE,
        parameters = mapOf("revenue" to 29.99, "currency" to "USD")
    )

    // Custom events
    AppstackAttributionSdk.sendEvent(
        EventType.CUSTOM,
        name = "user_attributes",
        parameters = mapOf(
            "email" to "test@example.com",
            "name" to "first_name last_name",
            "phone_number" to "+33060000000",
            "date_of_birth" to "2026-02-01"
        )
    )
    ```

    **Available EventType values**

    It is recommended to use standard events for a smoother experience.

    <Note>
      `EventType.INSTALL` is tracked automatically on SDK initialization. Do not send it manually.
    </Note>

    * `EventType.LOGIN`  User login.
    * `EventType.SIGN_UP` / `EventType.REGISTER` User registration.
    * `EventType.PURCHASE` Purchase transactions.
    * `EventType.SUBSCRIBE` Subscription events.
    * `EventType.ADD_TO_CART`, `EventType.ADD_TO_WISHLIST`, `EventType.INITIATE_CHECKOUT` E-commerce events.
    * `EventType.START_TRIAL` Trial start.
    * `EventType.LEVEL_START`/ `EventType.LEVEL_COMPLETE` Game progression.
    * `EventType.TUTORIAL_COMPLETE`, `EventType.SEARCH`, `EventType.VIEW_ITEM`, `EventType.VIEW_CONTENT`, `EventType.SHARE`  Engagement events.
    * `EventType.CUSTOM` For any other custom events.

    Tracks custom events with optional parameters:

    * `event` Event type from EventType enum (required).
    * `name` Event name for custom events (optional, required when event is CUSTOM).
    * `parameters` - Optional map of parameters (e.g., `mapOf("revenue" to 29.99, "currency" to "USD")`).

    **Enhanced app campaigns**

    <Tip>
      When running enhanced app campaigns (EACs), it is highly recommended to send multiple parameters with the in-app event to improve matching quality.
    </Tip>

    For any event that represents revenue, we recommend sending:

    1. `revenue` or `price` (number).
    2. `currency` (string, e.g. `EUR`, `USD`).

    ```kotlin theme={null}
    AppstackAttributionSdk.sendEvent(
        EventType.PURCHASE,
        parameters = mapOf("revenue" to 4.99, "currency" to "EUR")
    )
    ```

    To improve matching quality on Meta, send events including the following parameters if you can fulfill them. Appstack automatically encrypts these matching parameters before using them for attribution matching.

    1. `email`.
    2. `name` (first + last name in the same field).
    3. `phone_number` — also accepted as `phone` or `phoneNumber`.
    4. `date_of_birth` (recommended format: `YYYY-MM-DD`) — also accepted as `birthdate`, `birthday`, or `dateOfBirth`.
    5. `gender`.
  </Step>
</Steps>

## **Appstack ID and attribution params**

After `configure`, you can read the Appstack user ID and the attribution map for partner integrations (for example Superwall, RevenueCat).

```kotlin theme={null}
val appstackId = AppstackAttributionSdk.getAppstackId()

// Inside a coroutine: waits for the initial attribution match to finish
val attributionParams = AppstackAttributionSdk.awaitAttributionParams()
```

* **`getAppstackId()`** — Appstack user identifier when a partner expects `$appstackId` or similar.
* **`awaitAttributionParams()`** — `suspend` function that waits for the initial attribution match, then returns the attribution payload (campaign, media source, click IDs, device identifiers where available) to forward to partners. Prefer this over a fixed delay after launch.
* **`getAttributionParams()`** — Non-suspending variant that returns whatever is cached right now. Called immediately after `configure(...)` it can still be empty, because the match runs asynchronously.

## **Development setup**

If you want to test the SDK against the Appstack development environment before shipping, follow these extra steps:

1. In Appstack, from the side menu, select **SDK**, switch to the **Development** environment, and copy the **Development API key**. This key is separate from your production key.
2. In your `configure(...)` call, use the development key and raise the log level:

```kotlin theme={null}
AppstackAttributionSdk.configure(
    context = this,
    apiKey = "your_development_api_key",
    logLevel = LogLevel.DEBUG
)
```

The API key is what selects the environment — there is no flag to set. A development key routes to the development environment, a production key to production; both use the same endpoint.

**On-device diagnostics**

`LogLevel.DEBUG` prints the SDK's initialization, attribution, and event traffic to logcat under the tag `AppstackSdk`:

```text theme={null}
adb logcat -s AppstackSdk
```

Keep the debug log level behind a build-type check so release builds stay quiet:

```kotlin theme={null}
AppstackAttributionSdk.configure(
    context = this,
    apiKey = "your-api-key",
    logLevel = if (BuildConfig.DEBUG) LogLevel.DEBUG else LogLevel.INFO
)
```

## **Security and privacy**

* Never commit API keys to version control.
* Use separate production and development keys, and make sure release builds ship the production key.
* Keep `LogLevel.DEBUG` behind a `BuildConfig.DEBUG` guard so release builds stay quiet.
* Do not put personally identifiable information in event names.
* Only send matching parameters such as `email`, `name`, `phone_number`, and `date_of_birth` when your app has the right consent and compliance basis. Appstack automatically encrypts these fields before using them for attribution matching.
* Prefer standard event types for common flows so event mapping remains consistent across Appstack and ad integrations.

## **Limitations**

### **Platform constraints**

* Android 5.0+ required (API level 21).
* Attribution only works for Play Store installations.
* Network connectivity is required at the moment an event is sent. There is no durable offline queue: an event tracked while the device is offline is dropped, not stored for later. Transient failures on a request that did go out (network errors, HTTP 429/500/502/503/504) are retried in-flight with exponential backoff.

### **Event tracking**

* The SDK must be initialized in `Application.onCreate()` before tracking calls.
* Custom event names should be descriptive and consistent.
* Events sent before the SDK is ready are buffered in memory and replayed once initialization completes.
* `INSTALL` is tracked automatically on SDK initialization. Do not send it manually — the SDK drops such calls.
* Revenue events should include `revenue` or `price` and `currency`.

## **Troubleshooting**

### **Configuration fails**

* Confirm the API key was copied from the correct app and environment in Appstack.
* Confirm the SDK dependency resolves from Maven Central.
* Confirm your `Application` class is registered in `AndroidManifest.xml`.
* Confirm your app declares the `INTERNET` permission in `AndroidManifest.xml` — without it `configure(...)` reports an error through `InitListener.onError()` and `getLastInitError()`.

### **Events do not appear**

* Confirm `configure(...)` runs in `Application.onCreate()` before the first `sendEvent(...)` call.
* Confirm the device has network connectivity.
* Confirm the app was installed from the Play Store when testing attribution.
* Check that revenue events include a numeric `revenue` or `price` value and a valid `currency`.
* Allow a few minutes for events to appear in the dashboard.

### **No SDK logs appear**

* Confirm `configure(...)` passes `logLevel = LogLevel.DEBUG`.
* Filter logcat on the SDK tag: `adb logcat -s AppstackSdk`.

## **Superwall**

To start using the Superwall integration, [click here](/Integrations/superwall) to see the correct SDK documentation.

## **Verification checklist**

* Dependency installed with `tech.appstack.android-sdk:appstack-android-sdk`.
* App meets min SDK 21, target SDK 35+, Java 17+, and Gradle 8.0+ requirements.
* Maven Central is available to Gradle.
* Production API key is used in release builds.
* Development API key is used only in development builds.
* `Application` class is registered in `AndroidManifest.xml`.
* `configure(...)` runs once from `Application.onCreate()`.
* `INSTALL` is not sent manually.
* Login, signup, purchase, subscription, and other key app events use standard event types where possible.
* Revenue events include `revenue` or `price` and `currency`.
* Custom events use `EventType.CUSTOM` with a descriptive `name`.
* Appstack ID and attribution params are available before wiring partner integrations.
* Events are visible in the Appstack SDK page before launch.

## **Support**

For questions or issues:

1. Check the [GitHub Repository](https://github.com/appstack-tech/appstack-android-sdk).
2. Contact our support team at [support@appstack.tech](mailto:support@appstack.tech)
3. Open an issue in the repository.

<Prompt description="Use Cursor, Claude Code, or another AI to validate your existing Appstack Android SDK (Kotlin) integration." actions={["copy", "cursor"]}>
  You are an expert Android engineer reviewing my existing Appstack Android SDK (Kotlin) integration. You are running inside an IDE assistant such as Cursor or Claude Code and you can see my codebase.

  Your goal is to **validate that my integration fully matches the official Kotlin SDK documentation** and identify any missing or incorrect steps. When I paste this prompt and share my project files, you should:

  1. **Gradle & environment**
     * Inspect my Gradle files (project and app module) to confirm:
       * The Appstack SDK dependency is present with the correct Maven coordinates (`tech.appstack.android-sdk:appstack-android-sdk`) and a valid version.
       * Minimum SDK is at least API 21, target SDK is 35+, Java is 17+, and Gradle is 8.0+.
       * Required repositories (including Maven Central) are configured so the SDK can resolve.
     * Call out any mismatches or improvements needed.

  2. **SDK initialization**
     * Locate my `Application` class and verify:
       * It is registered in the `AndroidManifest.xml`.
       * `AppstackAttributionSdk.configure(...)` is called in `Application.onCreate()` before any event tracking.
       * The call passes a valid `context` and `apiKey`, and uses the optional `logLevel`, `listener`, and `customerUserId` parameters appropriately when present.
       * No call still passes the deprecated `isDebug` or `endpointBaseUrl` arguments; both are ignored by the SDK and should be dropped.
     * Suggest exact code changes if initialization is missing, in the wrong place, or misconfigured.

  3. **Logging configuration**
     * Check whether verbose logging is limited to debug builds, for example `logLevel = if (BuildConfig.DEBUG) LogLevel.DEBUG else LogLevel.INFO` in `configure(...)`.
     * Warn if `LogLevel.DEBUG` is left enabled for release builds and propose safe patterns.
     * Flag any leftover `showDebugOverlay(...)` call: the debug overlay was removed from the SDK and the call no longer exists.

  4. **Event tracking implementation**
     * Find all uses of `AppstackAttributionSdk.sendEvent(...)` and verify:
       * Standard `EventType` values are used where appropriate (e.g. `SIGN_UP`, `LOGIN`, `PURCHASE`, `SUBSCRIBE`, `ADD_TO_CART`, `ADD_TO_WISHLIST`, `INITIATE_CHECKOUT`, `START_TRIAL`, `LEVEL_START`, `LEVEL_COMPLETE`, `TUTORIAL_COMPLETE`, `SEARCH`, `VIEW_ITEM`, `VIEW_CONTENT`, `SHARE`).
       * Revenue-related events (such as `PURCHASE`) send `revenue` or `price` and `currency` parameters.
       * Custom events use `EventType.CUSTOM` with a meaningful `name` and, when possible, parameters such as `email`, `name`, `phone_number`, and `date_of_birth` to support enhanced app campaigns, noting that Appstack automatically encrypts these matching parameters before using them for attribution matching.
     * Highlight any missing or inconsistent events and propose concrete event calls that fit my app’s structure and flows.

  5. **Limitations & platform assumptions**
     * Confirm that my integration respects the documented limitations:
       * App supports Android 5.0+ (API 21+).
       * I understand attribution works for Play Store installs, and that events tracked while the device is offline are dropped rather than queued for later — so I should not rely on the SDK to deliver events recorded without connectivity.
     * Flag any edge cases in my setup that might conflict with these assumptions.

  6. **Validation report & checklist**
     * Produce a clear report summarizing:
       * What is already correctly implemented and safe to ship.
       * What is missing, misconfigured, or risky, with specific file names, functions, and code snippets to change.
     * End with a **checklist of verification steps** (Gradle, Application init, log level, key event tracking patterns) that I can tick off to confirm the integration fully matches the Kotlin SDK documentation.
</Prompt>
