# Battle pass — `client.battlePass` `BattlePassService` (source: `src/battlepass/BattlePassService.ts`). Call-and-response access to battle pass endpoints. Battle pass state is tied to a **scenario battle pass node**, so calls carry `scenarioSlug` + `nodeId` (plus `runId` for mutating calls). NOT observable — re-fetch progress explicitly after a mutation. In most games you do not call this service directly: a scenario battle pass node surfaces through `client.effects.onBattlePass` with a session object that wraps these calls (see `reference/scenarios.md`). Use the service directly when you already know the scenario/node/run identifiers. ## Methods ```ts getProgress(scenarioSlug: string, nodeId: string): Promise addXp(request: AddBattlePassXpRequest): Promise claimReward(request: ClaimBattlePassRewardRequest): Promise purchasePremium(request: PurchaseBattlePassPremiumRequest): Promise ``` ## Request / response types ```ts interface AddBattlePassXpRequest { amount?: number; nodeId?: string; runId?: string; scenarioSlug?: string; source?: string; // configured XP source } interface AddBattlePassXpResponse { level?: number; leveledUp?: boolean; maxLevel?: boolean; xp?: number; } interface ClaimBattlePassRewardRequest { level?: number; nodeId?: string; runId?: string; scenarioSlug?: string; track?: 'free' | 'premium'; } interface ClaimBattlePassRewardResponse { alreadyClaimed?: boolean; error?: string; granted?: Reward[]; // { amount?, currency?, itemId? } success?: boolean; } interface GetBattlePassProgressResponse { claimedTiers?: ClaimedTier[]; // { level?, track? } level?: number; premiumOwned?: boolean; xp?: number; } interface PurchaseBattlePassPremiumRequest { idempotencyKey?: string; nodeId?: string; runId?: string; scenarioSlug?: string; } interface PurchaseBattlePassPremiumResponse { error?: string; success?: boolean; } ``` ## Semantics - `addXp` credits XP from a configured source; returns the new `xp`/`level` plus `leveledUp` / `maxLevel` flags. - `claimReward` claims a tier reward at a reached level; idempotent server-side (`alreadyClaimed`). Claiming a tier above the current level (or a premium tier without premium) fails server-side — check `success`/`error` in the response and the typed error `code` (`RudderErrorCodes`). - `purchasePremium` charges the player's wallet; idempotent; pass your own `idempotencyKey` for safe retries. - Prefer the `onBattlePass` effect session, which binds `scenarioSlug` / `nodeId` / `runId` and posts scenario callbacks for you.