---
title: "Android SDK reference"
description: "Kotlin setup, identity, event capture, feature access, and native purchase interfaces."
sidebar:
  label: "Android"
search:
  tags: ["sdk", "reference", "android"]
  keywords: ["Kotlin", "Gradle", "Android", "configure", "identify", "consumeFeature", "App Action"]
---

The Android SDK provides Kotlin methods for customer identity, Experiences, purchases, and feature access. [Install and configure the SDK](/docs/sdks/android) before calling these methods.

<span id="interfaces-and-contracts" />

## Configuration

Create a `NuxieConfiguration` and pass it to `Nuxie.setup(context, configuration)` once at app launch. The SDK uses the application context.

| Option | Default | Description |
| --- | --- | --- |
| `apiKey` | Required | Your Android app's publishable key. |
| `environment` | `PRODUCTION` | Nuxie service environment: `PRODUCTION` or `DEVELOPMENT`. |
| `logLevel` | `WARN` | `NONE`, `ERROR`, `WARN`, `INFO`, `DEBUG`, or `VERBOSE`. |
| `redactSensitiveData` | `true` | Redact sensitive values in diagnostic output. |
| `featureCacheTTL` | `300000` | How long a feature check remains fresh, in milliseconds. |
| `localeIdentifier` | `null` | Use the device locale, or supply an app-selected locale. |
| `beforeSend` | `null` | Transform an event, or return `null` to omit it. |
| `purchaseHandlingMode` | `NUXIE_MANAGED` | Choose who completes Google Play purchases. |
| `purchaseDelegate` | `null` | Provide checkout and restore through your billing integration. |
| `testStoreEnabled` | `false` | No-charge Test Store checkout. Requires the `DEVELOPMENT` service, a `pk_test_` key, and a debuggable app. |

Use the public `pk_test_` key for preview content and the `pk_live_` key for live content. Keep the default service environment for both. The development environment selects a separate Nuxie service; it does not select test mode for your app.

`Nuxie.isSetup` reports whether local setup has completed.

## Identify a customer

Use your application's customer ID to associate events and access with an account:

```kotlin
import ai.nuxie.sdk.Nuxie

Nuxie.identify(
    "customer_123",
    userProperties = mapOf("plan" to "pro")
)
```

`Nuxie.distinctId` returns the current ID. On sign-out, call `Nuxie.reset()` to clear the identified customer and generate a new anonymous ID.

### Customer properties

`identify()` accepts `userProperties` for values to update and `userPropertiesSetOnce` for values to set only when absent. Both are optional maps of JSON values.

`Nuxie.anonymousId` returns the anonymous ID, and `Nuxie.isIdentified` tells you whether the current customer has been identified. `reset(keepAnonymousId = true)` retains the anonymous ID; the default rotates it for sign-out.

### Locale

Call the suspending `setLocaleIdentifier(localeIdentifier)` to change the app's locale. Pass `null` to follow the device again. The change takes effect when the SDK next synchronizes the profile.

## Trigger an Experience

```kotlin
Nuxie.trigger("upgrade_requested", mapOf("source" to "settings"))
```

The event name must match a published trigger. The call returns immediately; Nuxie checks the audience and re-entry rules before presenting. Use `Nuxie.dismiss()` from a coroutine to close a presented Experience.

## Check access

Call `hasFeature()` from a coroutine:

```kotlin
val access = Nuxie.hasFeature("premium-export")
if (access.allowed) {
    // Enable premium export.
}
```

The default `CACHE_FIRST` policy uses fresh cached access. Pass `policy = FeatureCheckPolicy.REMOTE` to query the server. `requiredBalance` and `entityId` select the amount and entity to check. A check does not consume usage.

### Access values and local state

`FeatureAccess` contains `allowed`, `unlimited`, an optional `balance`, and a feature `type`. A Boolean feature expresses access; metered and credit features can also have balances.

`Nuxie.features` exposes `StateFlow` values for `snapshot`, `state`, and `all`. Collect the snapshot to receive access and readiness from the same update. It includes `identityGeneration` and `revision` alongside the feature map.

State is `FeatureInfo.State.Unknown`, `Reconciling`, or `Ready`. Show a loading state while access is `Unknown`; `Reconciling` means purchase access is being synchronized. Call `awaitReady()` to suspend until access is ready. `isAllowed(featureId)` and `balance(featureId)` read cached global access without a request. Use this state to render UI and a consumption result to authorize spending.

### Record usage

`useFeature(featureId, amount = 1.0, entityId = null, metadata = null)` records usage without returning a result. Use it when the app does not need to wait for acceptance.

`useFeatureAndWait(featureId, amount = 1.0, entityId = null, setUsage = false, metadata = null)` is suspending and returns `FeatureUsageResult`: `success`, `featureId`, `amountUsed`, optional `message`, optional `usage`, and optional `authoritativeAccess`. `usage` contains `current`, optional `limit`, and optional `remaining`.

With `setUsage = true`, `amount` is a cumulative total for that customer, feature, and entity. Sending `20` and then `25` consumes 20 units and then five more. Sending a lower total does not refund usage.

Use `consumeFeature()` when your app needs a saved operation ID for retries.

## Consume usage

```kotlin
val receipt = Nuxie.consumeFeature(
    "credits",
    quantity = 5.0,
    operationId = "generation_123"
)
if (receipt.accepted) {
    // Start the generation once.
}
```

Save one operation ID for each action and reuse it when retrying. `accepted` determines whether the action was charged; a successful final-unit consumption can leave a zero balance. Handle request errors without starting the work.

### Consumption result

`FeatureConsumptionResult` includes the following fields:

| Field | Meaning |
| --- | --- |
| `customerId`, `featureId` | Customer and feature charged by this operation. |
| `operationId`, `quantity` | The operation you submitted. |
| `accepted`, `code` | Whether it was accepted and the result code. |
| `balance`, `unlimited`, `active` | Access after the operation. `balance` may be absent. |
| `occurredAtMs` | Optional operation time in milliseconds. |
| `idempotentReplay` | Whether this is a previous result returned for the same operation. |

`quantity` must be a positive whole number no greater than `9,007,199,254,740,991`. Supply `entityId` when spending an entity-specific allowance. For shared credits, use the credit feature's key and the number of credits the action costs.

## Purchases

Published purchase buttons use the configured checkout integration. For an app-owned checkout entry point, `purchase(activity, product, replacement = null)` is suspending and returns `PurchaseResult.Purchased`, `Cancelled`, `Pending`, or `Failed(cause)`.

A `StoreProduct` identifies the selection shown to the customer: `productId`, `storeProductId`, optional `basePlanId`, `purchaseOptionId`, `offerId`, and `placementId`. `rawProduct` holds the corresponding Google Play `ProductDetails` when available. Forward `isOfferPersonalized` to your purchase provider.

When replacing an active subscription, provide `SubscriptionReplacement(oldPurchaseToken, replacementMode)`. The supported modes are `WITH_TIME_PRORATION`, `CHARGE_PRORATED_PRICE`, `WITHOUT_PRORATION`, `CHARGE_FULL_PRICE`, and `DEFERRED`. A checkout requiring replacement fails with `SubscriptionReplacementRequiredException` when that choice is missing.

### External checkout

Implement `NuxiePurchaseDelegate` with two suspending methods:

- `purchase(product: StoreProduct): PurchaseResult`
- `restorePurchases(): RestoreResult`

Set the delegate on the configuration before setup. Use `PurchaseHandlingMode.APP_MANAGED` when your app or provider owns Google Play acknowledgement and consumption. The default `NUXIE_MANAGED` mode lets Nuxie complete native purchases. After setup, `setPurchaseDelegate()` and `setPurchaseHandlingMode()` change these choices; passing a null delegate returns to native checkout.

Return the actual checkout outcome. Opening a purchase dialog does not mean a purchase succeeded. Observe feature access for the resulting entitlement.

## Restore purchases

`Nuxie.restorePurchases()` is a suspending method. It returns `RestoreResult.Restored`, `NoPurchases`, or `Failed(cause)` through the configured native or external purchase integration.

For existing provider checkout, see the [RevenueCat](https://github.com/nuxieai/nuxie-android/blob/main/example-revenuecat/README.md) and [Superwall](https://github.com/nuxieai/nuxie-android/blob/main/example-superwall/README.md) adapters.

## App Actions

Set `Nuxie.listener` to a `NuxieListener` when an Experience needs to call your app, such as opening the export screen after onboarding. Its `onAppActionRequested` callback receives the action name and payload. The listener also supports activity and feature-access callbacks.

Keep the listener in an app-owned property: the SDK holds it weakly. Callbacks run on Android's main thread.

### Listener callbacks

| Callback | When to use it |
| --- | --- |
| `onAppActionRequested(sdk, action)` | Handle an authored App Action in your app. |
| `onActivityEmitted(sdk, info)` | Forward Experience activity to your analytics integration. |
| `featureAccessDidChange(featureId, oldAccess, newAccess)` | Update UI when a feature changes. `oldAccess` can be absent. |

An App Action includes its name, payload, and Experience context. Route only action names your app recognizes. Clear or replace listeners when their owner no longer needs callbacks.

`NuxieActivityInfo` exposes `id`, `customerId`, `timestampMillis`, `receivedAtMillis`, typed `activity`, and an analytics-ready `name` and `properties`. Check `isCurrentIdentity` before applying an activity to customer-specific UI. Forward analytics with the activity's original customer ID.

## Errors and shutdown

Catch failures from suspending feature and lifecycle methods. A request failure does not establish that a customer lacks access. For a consumption retry, reuse the same operation ID so a delayed response cannot cause a second charge.

Use `shutdownAndAwait()` from a coroutine when you need to wait for cleanup before configuring another session. `shutdown()` starts cleanup without waiting. Call purchase-owner setters only after setup and before shutdown; an inactive SDK rejects those changes.

<span id="shared-platform-behavior" />

See [Delivery](/docs/guides/delivery) for trigger rules and [Features and entitlements](/docs/monetization/features-and-entitlements) for access configuration. The [public API declaration](https://github.com/nuxieai/nuxie-android/blob/main/nuxie-android/api/nuxie-android.api) lists all signatures.
