---
title: "Unity SDK reference"
description: "C# lifecycle, game-thread subscriptions, feature access, and consumption receipts."
sidebar:
  label: "Unity"
search:
  tags: ["sdk", "reference", "unity"]
  keywords: ["C#", "IL2CPP", "Unity", "configure", "identify", "consumeFeature", "App Action"]
---

`Nuxie.Client` provides the C# interface for Nuxie's iOS and Android SDKs. [Install and configure the package](/docs/sdks/unity), then call the client on Unity's main thread.

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

## Configuration

Await `Nuxie.Client.ConfigureAsync(options)` before using the client. `NuxieOptions` accepts:

| Option | Default | Description |
| --- | --- | --- |
| `IosApiKey`, `AndroidApiKey` | Platform key required | Publishable keys for the iOS and Android apps. |
| `Environment` | `Production` | `Production` or `Development`. |
| `LogLevel` | `Warning` | `Warning`, `Debug`, `Info`, `Error`, or `None`. |
| `LocaleIdentifier` | `null` | App-selected locale; null follows the device. |
| `Billing` | `NuxieBilling.Native` | Native checkout or `NuxieBilling.External(controller)`. |

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.

`Status.State` is `Unconfigured`, `Configuring`, `Configured`, or `Failed`. Status also exposes `WrapperVersion`, optional `NativeVersion`, and an error when configuration fails. `SubscribeStatus()` delivers the current status immediately and returns a subscription for later changes.

Configuration is copied into the session. Await `ShutdownAsync()` before configuring a session with different options.

## Identify a player

```csharp
using Nuxie.Unity;

await Nuxie.Client.IdentifyAsync("player-123");
var identity = await Nuxie.Client.GetIdentityAsync();
```

`identity` contains `CustomerId`, `AnonymousId`, and `IsIdentified`. Call `ResetAsync()` on sign-out to clear the customer and rotate the anonymous ID.

Pass an `IdentityOptions` value to `IdentifyAsync()` to update `Properties` or set `PropertiesSetOnce` only where a property has no value. Use JSON-compatible values in both dictionaries.

Await identity changes before issuing customer-specific requests. `SetLocaleAsync(locale)` changes the locale; pass null to follow the device again.

## Trigger an Experience

```csharp
await Nuxie.Client.TriggerAsync("shop_requested");
```

The Task completes after native event acceptance. The published trigger and audience determine whether an Experience appears. `DismissAsync()` closes the current presentation.

The client survives scene changes. Your game controls pause, audio, and input while native UI is visible.

## Observe feature access

```csharp
var subscription = Nuxie.Client.ObserveFeature("premium", state => {
    if (state.State == FeatureStateKind.Unknown) return;
    bool allowed = state.Access != null && state.Access.Allowed;
    // Update the game UI.
});
```

Dispose the subscription when the observing object no longer needs updates. `Features` provides the full snapshot; `HasFeatureAsync()` queries a feature with a `FeatureQuery`, including an optional entity and cache policy.

### Query options

`HasFeatureAsync(featureId, query)` returns `FeatureAccess`. Its fields are `Allowed`, `Unlimited`, nullable `Balance`, and `Type` (`Boolean`, `Metered`, or `CreditSystem`). It checks access without spending an allowance.

`FeatureQuery` accepts `EntityId`, `RequiredBalance` (default `1`), and `Policy` (`CacheFirst` or `Remote`). Entity-specific checks return their result without replacing the customer's global feature snapshot.

`Features` includes `State`, `All`, `IdentityGeneration`, and `Revision`. State is `Unknown` while loading, `Reconciling` while purchase access is being synchronized, or `Ready`. `SubscribeFeatures()` observes that full snapshot. `ObserveFeature()` selects one feature; a ready state can still have null `Access` when no grant exists.

## Consume usage

```csharp
var receipt = await Nuxie.Client.ConsumeFeatureAsync(
    "credits",
    new FeatureCommand {
        Quantity = 5,
        OperationId = "generation-123"
    }
);

if (receipt.Accepted) {
    // Apply the action once.
}
```

Save the operation ID before sending and reuse it for retries. `Accepted` determines whether the deduction succeeded, including when the resulting balance is zero. Your game must also avoid applying the same accepted action twice.

### Consumption receipts

`FeatureCommand` requires `OperationId` and accepts `Quantity` (default `1`) and an optional `EntityId`. Quantity must be a positive whole number up to `9,007,199,254,740,991`.

`FeatureConsumption` contains `CustomerId`, `FeatureId`, `OperationId`, `Quantity`, nullable `OccurredAtMs`, `Accepted`, `Code`, nullable `Balance`, `Unlimited`, `Active`, and `IdempotentReplay`. An idempotent replay returns the saved result for the operation; it does not charge again.

Use the credit feature key directly when spending shared credits. A request failure is not a denied receipt: handle the error and retry with the same operation ID when appropriate.

## Checkout integration

Use native billing for Nuxie's built-in checkout. To keep an existing purchase provider, pass `NuxieBilling.External(controller)` in `NuxieOptions`. Implement `INuxiePurchaseController`:

| Method | Return value |
| --- | --- |
| `PurchaseAsync(StoreProduct product)` | `Task<PurchaseResult>` |
| `RestorePurchasesAsync()` | `Task<RestoreResult>` |

Create `PurchaseResult` with `PurchaseOutcome.Purchased`, `Cancelled`, `Pending`, or `Failed`, and an optional message. Create `RestoreResult` with `RestoreOutcome.Restored`, `NoPurchases`, or `Failed`.

`StoreProduct` provides `Platform`, `ProductId`, `StoreProductId`, optional `BasePlanId`, `OfferId`, `PurchaseOptionId`, `PlacementId`, `DisplayName`, `DisplayPrice`, and `EligibilityJws`. `Details` contains the full selected product metadata, including pricing phases and introductory terms where supplied by the platform. Preserve that selection when starting provider checkout.

External checkout leaves transaction finishing and acknowledgement to your billing integration. Report the actual result, and observe Features for the resulting access.

## App Actions and restore

`SubscribeAppAction()` receives actions sent from an Experience, such as returning the player to the shop after onboarding. Match the action's `Name` to a handler in your game and read its `Payload` for supplied values. `SubscribeActivity()` receives runtime activity. Both return an `IDisposable` subscription.

`RestorePurchasesAsync()` returns `Restored`, `NoPurchases`, or `Failed` through the configured billing integration.

An `AppAction` contains `Name`, `Payload`, and `Experience` (`ExperienceId`, `ExperienceVersion`, `JourneyId`). `NuxieActivity` contains `Id`, `Name`, `SchemaVersion`, `TimestampMs`, `ReceivedAtMs`, and `Properties`.

## Inspector components

| Component | Setup and events |
| --- | --- |
| `NuxieSettings` | Create a **Nuxie → Settings** asset with app keys, environment, and log level. `ToOptions()` returns the client configuration. |
| `NuxieBootstrap` | Assign a settings asset. It configures on `Start` and emits `Configured` or `Failed(message)`. |
| `NuxieTrigger` | Set an event name, then connect a button to `Trigger()`. Failures emit `Failed(message)`. |
| `NuxieFeatureGate` | Set a Feature key and connect `Unknown`, `Allowed`, and `Denied` UnityEvents to your UI. |

The feature gate subscribes while enabled and disposes its observer when disabled. It reads access for UI; use a consumption call for actions that spend credits or quota.

## Errors and cleanup

Await client Tasks and catch `NuxieException`. Its `Code` identifies errors such as `invalidArgument`, `notConfigured`, `alreadyConfigured`, `wrongThread`, `unsupportedPlatform`, `staleOperation`, and `identityBusy`; the message provides context. `SubscribeErrors()` receives errors delivered outside an individual Task.

All client calls and callbacks use Unity's main thread. Do not block it with `.Wait()` or `.Result`. Dispose every subscription when its owner is destroyed, and await `ShutdownAsync()` when ending the SDK session. Scene changes alone do not require shutdown.

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

See [Features and entitlements](/docs/monetization/features-and-entitlements) for access configuration. The [C# API reference](https://github.com/nuxieai/nuxie-unity/blob/main/Documentation~/api-reference.md) covers options, errors, and result types.
