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

# SDK Integration

> Wire identity, saves, economy, and analytics into your game

The SusaPlay SDK is a Unity package written in C#. Your game runs inside the SusaPlay shell,
and the SDK talks to the platform through that shell.

<Note>
  There is currently no JavaScript SDK. All examples below are C# for Unity.
</Note>

## Install

Add the package to your `Packages/manifest.json`:

```json theme={null}
{
  "dependencies": {
    "com.susaplay.sdk": "https://github.com/susaplay/com.susaplay.sdk.git"
  }
}
```

Requires Unity 2021.3 or later, with the WebGL build target.

## Initialize

Call `Initialize()` once on startup and await it before any other SDK call. It handshakes with
the shell and populates every module.

```csharp theme={null}
using susaplay.SDK;
using UnityEngine;

public class Bootstrap : MonoBehaviour
{
    private async void Start()
    {
        await SusaPlaySDK.Initialize();

        Debug.Log($"Player: {SusaPlaySDK.Auth.DisplayName} ({SusaPlaySDK.Auth.Uid})");

        // Tell the shell your game is ready so it can hide the loading screen.
        SusaPlaySDK.MarkGameLoaded();
    }
}
```

`Initialize()` reads your game key from the `PlatformConfig` asset — create it with
**susaplay → Create Config Asset** in the Unity menu. Do not hardcode the key.

If the shell does not answer within 15 seconds, initialization logs an error and returns. The
module properties stay null, so check before using them.

## Identity

Identity is resolved by the shell during initialization. There is nothing to call.

```csharp theme={null}
string uid = SusaPlaySDK.Auth.Uid;
string name = SusaPlaySDK.Auth.DisplayName;

if (SusaPlaySDK.Auth.IsGuest)
{
    // Guest session — progress is tied to the browser, not an account.
}
```

Guest-to-account merging is handled by the platform when the player signs in. The game does not
drive it.

## Economy

```csharp theme={null}
// Platform wallet balance
var wallet = await SusaPlaySDK.Purchases.GetPlatformWallet();

// Store catalogue
var store = await SusaPlaySDK.Purchases.GetStoreItems();

// Spend platform-wallet currency on an item
var result = await SusaPlaySDK.Purchases.SpendPlatformWallet("sword_of_fire");

// Start a real-money purchase — the shell opens the Xsolla checkout
var purchase = await SusaPlaySDK.Purchases.StartDirectItemPurchase("starter_pack");

// Or top up the platform wallet
var topup = await SusaPlaySDK.Purchases.StartWalletTopupPurchase("coins_100");
```

Every wallet and inventory mutation happens server-side. The client can never write a balance.

## Saves

```csharp theme={null}
// Write — data is any string, usually JSON you serialize yourself
var saved = await SusaPlaySDK.CloudSave.Save("main", JsonUtility.ToJson(myState));
if (saved.success)
{
    Debug.Log($"Saved version {saved.data.version}");
}

// Read
var loaded = await SusaPlaySDK.CloudSave.Load("main");
if (loaded.success)
{
    var state = JsonUtility.FromJson<MyState>(loaded.data.data);
}
```

Versioning is handled by the platform. Slot size is capped at 500 KB.

## Analytics

```csharp theme={null}
SusaPlaySDK.Analytics.LogEvent("level_started", "{\"level\":3}");
await SusaPlaySDK.Analytics.Flush();
```

`session_start` is emitted for you during `Initialize()`. See
[Analytics](/sdk/analytics) for details.

## Error handling

SDK calls do not throw for platform errors — they return a result object with a success flag.
Check it.

```csharp theme={null}
var result = await SusaPlaySDK.Purchases.SpendPlatformWallet("sword_of_fire");
if (!result.Success)
{
    Debug.LogWarning($"Spend failed: {result.ErrorCode} — {result.ErrorMessage}");
}
```

If the shell stops responding, requests time out and return an unsuccessful result rather than
hanging.

## Key rules

* Await `Initialize()` before touching any module — the properties are null until it completes
* Never hardcode the game key; it belongs in the `PlatformConfig` asset
* Call `MarkGameLoaded()` once your first scene is playable, so the shell can hide its loader
* Currency and inventory are server-authoritative — never track balances client-side as truth
* Save writes are versioned by the platform; always read before you write in a new session
