Files
rudder-csharp-sdk/skills/rudder-csharp-sdk/reference/battlepass.md
T
edmand46 ea20ea6d51
CI / publish (push) Failing after 39s
CI / check (push) Successful in 52s
0.4.0: Claim, Models/ DTOs, compile
LeaderboardSession.ClaimAsync sends onClaim. Generated DTOs live under Models/ with nullable wire fields. Remove incomplete duplicate type files.
2026-08-29 11:33:01 +03:00

5.7 KiB

Battle pass — client.BattlePass (BattlePassService)

Source: Services/BattlePassService.cs, Services/Scenarios/Sessions/BattlePassSession.cs, Services/Scenarios/Sessions/BattlePassLevelSession.cs, BattlePass/*.cs (generated DTOs).

Battle pass state is tied to a scenario battle-pass node, so every call carries ScenarioId/NodeId (mutations also RunId). Inside a scenario run, Scenario.OnBattlePass hands you a BattlePassSession that supplies these ids — prefer it over calling the service directly.

BattlePassService

public const string TrackFree = "free";
public const string TrackPremium = "premium";

// POST /sdk/v1/battlepass/progress
public Task<GetBattlePassProgressResponse> GetProgressAsync(
    string scenarioId, string nodeId, CancellationToken cancellationToken = default);

// POST /sdk/v1/battlepass/xp
public Task<AddBattlePassXpResponse> AddXpAsync(
    AddBattlePassXpRequest request, CancellationToken cancellationToken = default);

// POST /sdk/v1/battlepass/claim — idempotent server-side
public Task<ClaimBattlePassRewardResponse> ClaimRewardAsync(
    ClaimBattlePassRewardRequest request, CancellationToken cancellationToken = default);

// POST /sdk/v1/battlepass/premium — charges the wallet; a random
// IdempotencyKey is generated when request.IdempotencyKey is null
public Task<PurchaseBattlePassPremiumResponse> PurchasePremiumAsync(
    PurchaseBattlePassPremiumRequest request, CancellationToken cancellationToken = default);

Request DTOs (RudderSdk.Core.Models.BattlePass)

public class GetBattlePassProgressRequest
{
    public string? NodeId { get; set; }     // "nodeId"
    public string? ScenarioId { get; set; } // "scenarioId"
}

public class AddBattlePassXpRequest
{
    public long? Amount { get; set; }       // "amount"
    public string? NodeId { get; set; }     // "nodeId"
    public string? RunId { get; set; }      // "runId"
    public string? ScenarioId { get; set; } // "scenarioId"
    public string? Source { get; set; }     // "source"
}

public class ClaimBattlePassRewardRequest
{
    public int? Level { get; set; }         // "level"
    public string? NodeId { get; set; }     // "nodeId"
    public string? RunId { get; set; }      // "runId"
    public string? ScenarioId { get; set; } // "scenarioId"
    public string? Track { get; set; }      // "track" — TrackFree / TrackPremium
}

public class PurchaseBattlePassPremiumRequest
{
    public string? IdempotencyKey { get; set; } // "idempotencyKey"
    public string? NodeId { get; set; }         // "nodeId"
    public string? RunId { get; set; }          // "runId"
    public string? ScenarioId { get; set; }     // "scenarioId"
}

Response DTOs

public class GetBattlePassProgressResponse
{
    public List<ClaimedTier>? ClaimedTiers { get; set; } // "claimedTiers"
    public int? Level { get; set; }                      // "level"
    public bool? PremiumOwned { get; set; }              // "premiumOwned"
    public long? Xp { get; set; }                        // "xp"
}

public class ClaimedTier { public int? Level { get; set; } public string? Track { get; set; } }

public class AddBattlePassXpResponse
{
    public int? Level { get; set; }          // "level"
    public bool? LeveledUp { get; set; }     // "leveledUp"
    public bool? MaxLevel { get; set; }      // "maxLevel"
    public ExecutionPlan? Plan { get; set; } // "plan" — scenario continuation
    public long? Xp { get; set; }            // "xp"
}

public class ClaimBattlePassRewardResponse
{
    public bool? AlreadyClaimed { get; set; }  // "alreadyClaimed"
    public string? Error { get; set; }         // "error"
    public List<Reward>? Granted { get; set; } // "granted"
    public bool? Success { get; set; }         // "success"
}

public class PurchaseBattlePassPremiumResponse
{
    public string? Error { get; set; }       // "error"
    public ExecutionPlan? Plan { get; set; } // "plan"
    public bool? Success { get; set; }       // "success"
}

Reward (RudderSdk.Core.Models): Amount (long?), Currency (string?), ItemId (string?). Responses carry business errors in Error — check Success. Claim failures surface codes such as RudderErrorCodes.LevelNotReached.

BattlePassSession (scenario node session)

Raised via Scenario.OnBattlePass. Bound to the node's scenario/node/run ids:

public ScenarioNodeContext Context { get; }
public string Id { get; }  // node id
public T Get<T>(string key, T defaultValue = default!);

public Task<GetBattlePassProgressResponse> GetProgressAsync(CancellationToken ct = default);
public Task<AddBattlePassXpResponse> AddXpAsync(string source, long amount, CancellationToken ct = default);
public Task<ClaimBattlePassRewardResponse> ClaimRewardAsync(int level, string track, CancellationToken ct = default);

// Purchases premium, then crosses the onPremiumPurchase handle on success.
public Task<PurchaseBattlePassPremiumResponse> PurchasePremiumAsync(CancellationToken ct = default);

// Boundary crossings (async + fire-and-forget variants):
public Task LevelUpAsync(CancellationToken ct = default);   public void LevelUp();    // onLevelUp
public Task MaxLevelAsync(CancellationToken ct = default);  public void MaxLevel();   // onMaxLevel
public Task CompleteAsync(CancellationToken ct = default);  public void Complete();   // onComplete

BattlePassLevelSession (scenario battlepass_level node)

Raised via Scenario.OnBattlePassLevel; a single claimable tier:

public int Level { get; }  // reads the "levelNumber" node data key
public Task ClaimAsync(CancellationToken ct = default);  public void Claim();

ClaimAsync crosses onComplete; the server accepts it only once the player has reached the node's configured level.