C# SDK
The C# SDK exposes RudderClient and service classes under
RudderSdk.Core. It is runtime-agnostic: the game supplies HTTP,
token, device id, upload, realtime, and persistence adapters for its engine.
Client requirements
RudderClient validates that transport, token storage, device id
provider, and project key are configured. Optional adapters enable uploads,
scenario persistence, scheduling, logging, and realtime transport.
| Option | Purpose |
|---|---|
ProjectKey | Project identifier copied from the Rudder dashboard. |
BaseUrl | API origin, usually https://api.rudder.build. Your transport should use this as its origin. |
Transport | Implementation of IRudderTransport for SDK HTTP requests. |
TokenStore | Stores access and refresh tokens returned by device login. |
DeviceIdProvider | Returns a stable device id for the current install or player profile. |
RealtimeTransportFactory | Creates websocket-like transports for realtime sessions. |
Create and authenticate a client
The concrete adapter classes depend on your runtime. In Unity, they commonly
wrap UnityWebRequest, PlayerPrefs, and the engine
update loop.
using RudderSdk.Core;
using RudderSdk.Core.Abstractions;
var rudder = new RudderClient(new RudderClientOptions
{
ProjectKey = "YOUR_PROJECT_KEY",
BaseUrl = "https://api.rudder.build",
RealtimeUrl = "wss://realtime.rudder.build/api/realtime/ws",
Transport = new GameHttpTransport("https://api.rudder.build"),
TokenStore = new PlayerPrefsTokenStore(),
DeviceIdProvider = new StableDeviceIdProvider(),
PlanStateStore = new PlayerPrefsPlanStateStore(),
RealtimeTransportFactory = new GameRealtimeTransportFactory()
});
await rudder.Auth.LoginViaDeviceAsync(
region: "eu",
language: "en"); Remote config
Load config once during startup or use GetAsync<T> to load
lazily. The SDK parses strings, numbers, booleans, and JSON values according
to the config value type.
await rudder.RemoteConfig.LoadAsync();
var difficulty = rudder.RemoteConfig.Get("difficulty", "normal");
var bonusMultiplier = rudder.RemoteConfig.Get("bonus_multiplier", 1);
var newShopEnabled = rudder.RemoteConfig.Get("new_shop_enabled", false);
var economy = await rudder.RemoteConfig.GetAsync(
"economy",
new EconomyConfig { SoftCurrencyName = "Coins" }); Analytics
TrackAsync sends immediately through the configured transport.
The fire-and-forget Track helper is available for non-critical
telemetry.
await rudder.Analytics.TrackAsync("level_started", new
{
level = 7,
difficulty
});
rudder.Analytics.Track("purchase_opened", new
{
source = "main_menu"
}); Stores and leaderboards
Store APIs expose list, get, and purchase calls. Leaderboards support direct score submission and a cached handle API.
var stores = await rudder.Stores.ListAsync();
var eventStore = await rudder.Stores.GetAsync("weekend-sale");
var purchase = await rudder.Stores.BuyAsync(
"weekend-sale",
"starter-pack",
Guid.NewGuid().ToString("N"));
await rudder.Leaderboards.SubmitScoreAsync("pumpkin-collectors", 4200);
var leaderboard = rudder.Leaderboards.FindBySlug("pumpkin-collectors");
await leaderboard.SubmitAsync(4250);
var entries = await leaderboard.ListAsync(limit: 20); Scenario runtime
Call Restore() after client creation if you configured
PlanStateStore. Scenario events expose typed sessions for client
actions such as notifications, stores, quests, and battle pass nodes.
rudder.Scenarios.Restore();
rudder.Scenarios.OnNotification += async notification =>
{
var title = notification.Get("title", "Event update");
var message = notification.Get("message", "");
ShowInGameMessage(title, message);
await notification.CompleteAsync();
};
rudder.Scenarios.OnStore += store =>
{
ShowStore(store.Id,
onPurchase: () => store.Buy(),
onDismiss: () => store.Decline());
};
rudder.Scenarios.OnQuest += quest =>
{
quest.AddProgress("kills", 1);
};
await rudder.Scenarios.SendAsync("player_login"); Realtime and update loop
Realtime needs RealtimeUrl, a token from device login, and a
RealtimeTransportFactory. Call Update(deltaTime)
from the game loop so scenario waits and realtime transports can advance.
var session = await rudder.Realtime.ConnectAsync(timeoutSeconds: 10);
session.MessageReceived += bytes =>
{
HandleRealtimeMessage(bytes);
};
await session.SendAsync(BuildReadyPayload());
// Unity example:
void Update()
{
rudder.Update(Time.deltaTime);
} Logout and cleanup
Clear tokens when the player logs out and disconnect realtime when the scene or game session ends.
await rudder.Realtime.DisconnectAsync();
rudder.Auth.Logout();