Unity SDK v0.1.0 C#

The official Keme SDK for Unity brings drop-in, in-app player support directly into your game — authentication, tickets, and knowledge base, backed by the Keme portal REST API, plus a runtime support panel your players can open without you building any UI.

Overview

The SDK lives in the Keme namespace, ships as the UPM package com.keme.sdk, and uses async/await over UnityWebRequest. It has zero dependencies beyond Unity's built-in uGUI (com.unity.ugui).

    Unity 2021.3+ (works on all platforms including WebGL, iOS, and Android)Zero external dependencies — no NuGet or third-party JSON libraryInstall via Unity Package Manager (UPM git URL) or manual copyDrop-in runtime support panel — no prefab or scene wiring requiredContinuations resume on Unity’s main thread, so it’s safe to touch the UI right after an await
Note:The SDK is published in the monorepo at github.com/kemegames-studio/keme-sdk under the /unity path. Every Keme SDK wraps the same portal REST contract.

Installation

Option A — UPM git URL (recommended)

In Unity, open Window → Package Manager → + → Add package from git URL… and paste:

bash
1https://github.com/kemegames-studio/keme-sdk.git?path=/unity

Or add it directly to your Packages/manifest.json:

Packages/manifest.json
1{
2 "dependencies": {
3 "com.keme.sdk": "https://github.com/kemegames-studio/keme-sdk.git?path=/unity"
4 }
5}

Unity resolves and downloads the package automatically when you open the project or click Refresh in the Package Manager window.

Option B — Manual

Copy the unity folder into your project's Packages/ directory (as Packages/com.keme.sdk), or drop the Runtime/ folder anywhere under Assets/.

Tip:A demo scene is included as a sample. In Package Manager, select Keme SDK → Samples → Demo Scene → Import, add the DemoBootstrap component to an empty GameObject, fill in your gameId / userId, and press Play.

Quickstart

Three lines get you a fully working support surface. Init creates the client, Login authenticates the player (auto-provisioning them on first contact), and OpenSupport shows the drop-in panel.

csharp
1using Keme;
2
3var keme = KemeSDK.Init(new KemeConfig
4{
5 GameId = "your-game-id",
6 AppName = "Your Game Support",
7});
8
9await keme.Login(player.Id, player.Name); // auto-provisions the player, persists token
10keme.OpenSupport(); // runtime drop-in support panel

KemeSDK.Init also stashes the client on KemeSDK.Default, so a UI button handler can call KemeSupport.Open(KemeSDK.Default) without threading a reference through your scene.

Tip:All network calls return Task, so call them from an async method (async void Start() in a MonoBehaviour is fine). Continuations resume on Unity's main thread.

Configuration

Create the client with KemeSDK.Init(KemeConfig), which returns a KemeClient.

FieldTypeNotes
GameIdstringRequired. The game/app tickets are filed against.
ApiBasestringOptional. Defaults to https://api.kemegames.com/api/v1.
AppNamestringOptional. Support panel header. Defaults to "Support".
StorageITokenStorageOptional. Defaults to PlayerPrefsTokenStorage (key keme.portal.token).

Authentication

Call Login with the player's userId (and optional display name / email). The first login for a given userId auto-provisions the player — there is no separate registration step — and the returned 7-day token is persisted automatically.

csharp
1// Either overload works
2await keme.Login(new LoginParams("player-123", "Ari"));
3await keme.Login("player-123", "Ari", "ari@example.com");
4
5bool signedIn = keme.IsLoggedIn(); // true when a token is stored
6Player me = await keme.GetPlayer();
7
8keme.Logout(); // clears the persisted token
Warning:A banned player's login throws KemeException with Status == 403. Reuse the same userId for the same player across sessions and devices so their ticket history follows them.

The Support Panel

keme.OpenSupport() (or KemeSupport.Open(client)) builds a full uGUI panel at runtime — Canvas, ticket list, ticket detail with reply, and a "new ticket" form with category picker — no prefab or scene wiring needed. It auto-creates an EventSystem if your scene lacks one.

csharp
1// Open the drop-in support panel (player must be logged in first)
2keme.OpenSupport();
3
4// Or from a static context, using the default client
5KemeSupport.Open(KemeSDK.Default);
6
7// Close it programmatically
8KemeSupport.Close();
Note:The panel accent colour is Indigo #4F46E5. Close it with the ✕, the backdrop, or KemeSupport.Close(). The player must be logged in first, since the panel calls authenticated endpoints.

Tickets

Access ticket operations through client.Tickets. Subjects are 5–200 characters and descriptions are 10–5000. The ticket is filed against the config GameId unless you override it.

csharp
1using Keme;
2
3// Create a ticket
4Ticket ticket = await keme.Tickets.Create(new CreateTicketParams
5{
6 Subject = "Lost my gems after the update",
7 Description = "I had 500 gems before v1.4 and now they're gone.",
8 Category = TicketCategory.Billing,
9 Priority = TicketPriority.P2,
10});
11
12// List the player's tickets (paginated, normalised to a plain list)
13List mine = await keme.Tickets.List(new ListTicketsParams { Page = 1, Limit = 20 });
14
15// Fetch a single ticket, including its message thread
16Ticket detail = await keme.Tickets.Get(ticket.Id);
17
18// Reply to a ticket (body 1–5000)
19TicketMessage reply = await keme.Tickets.Reply(ticket.Id, "Any update?");
20
21// Rate a resolved ticket (score 1–5)
22await keme.Tickets.Rate(ticket.Id, 5, "Fast fix, thanks!");

Categories & priorities

    TicketCategory: Bug | Billing | Account | Gameplay | Other (serialized lower-case)TicketPriority: P1 | P2 | P3 | P4

Knowledge Base

Access self-serve help content through client.Kb so players can find answers before opening a ticket.

csharp
1List results = await keme.Kb.Search("gems");
2List categories = await keme.Kb.Categories();
3List featured = await keme.Kb.Featured();
4KbArticle article = await keme.Kb.Article("how-to-restore-purchases");

Models & Errors

The core models are Player, Ticket, TicketMessage, KbArticle, and Game. Every model exposes both JSON-shaped camelCase fields (e.g. player.gameUid) and idiomatic PascalCase properties (e.g. player.GameUid) — use whichever you prefer.

Any non-2xx response throws KemeException { Message, Status, Body }. Network/transport failures throw with Status == 0. The server's message (string or string[]) is flattened into Message.

csharp
1try
2{
3 await keme.Tickets.Create(new CreateTicketParams { Subject = "Hi", Description = "Too short" });
4}
5catch (KemeException e)
6{
7 Debug.LogError($"({e.Status}) {e.Message}"); // e.Body has the raw JSON
8}

gameId vs userId

These are two different identifiers — do not mix them up:

    gameId identifies the game/app (e.g. game-marble-sort). Set it once in KemeSDK.Init; it is attached to every ticket. Fetch valid ids with keme.Games().userId identifies the player within your game, and maps to the portal gameUid. Pass it to Login. The first login auto-provisions the player — no separate registration step.
Tip:Token storage persists via PlayerPrefs (works everywhere, including WebGL). Implement ITokenStorage and pass it in KemeConfig.Storage to use your own (e.g. encrypted) store.
Last updated: July 18, 2026Edit this page