@yaelouuu/fortnite-api 8.0.0 → 9.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -108,7 +108,7 @@ const duoLeaderboard = await client.tournaments.getLeaderboardV2(
108
108
  ```
109
109
 
110
110
  #### Tournament Tracker
111
- Track player participation history:
111
+ Track player participation history. Returns human-readable event names plus the official window `beginTime` / `endTime`:
112
112
 
113
113
  ```typescript
114
114
  const tracker = await client.tournaments.getTracker(
@@ -118,6 +118,34 @@ const tracker = await client.tournaments.getTracker(
118
118
  // Returns: All tournaments the player has participated in
119
119
  ```
120
120
 
121
+ #### Player Result in One Tournament — **no user token**
122
+ Final placement, points, team and every match played, without the OAuth flow:
123
+
124
+ ```typescript
125
+ const result = await client.tournaments.getPlayerWindowMatches(
126
+ "epicgames_S41_CashCup_DuosZB_OCE",
127
+ "S41_CashCup_DuosZB_Event1Round1_OCE",
128
+ "b6d0db0cefd74ccda92c111e7230ac33",
129
+ { rankHint: 1 } // optional, but turns a page scan into a single fetch
130
+ );
131
+
132
+ console.log(result.rank); // 1
133
+ console.log(result.pointsEarned); // 704
134
+ console.log(result.teamAccountIds.length); // 2 -> team size
135
+ console.log(result.matches[0].trackedStats.PLACEMENT_STAT_INDEX);
136
+ ```
137
+
138
+ #### Full Match History — **token required**
139
+ Every tournament match a player has played, grouped by event window. Epic only serves this to the player it belongs to, so a token-less call returns `403`:
140
+
141
+ ```typescript
142
+ const matches = await client.tournaments.getPlayerMatches(
143
+ "accountId",
144
+ "fortniteToken",
145
+ { after: "2026-01-01" }
146
+ );
147
+ ```
148
+
121
149
  #### Check Tournament Eligibility
122
150
  Verify if a player meets requirements for major tournaments (e.g., 14 tournaments in 180 days):
123
151
 
@@ -151,6 +179,57 @@ const events = await client.tournaments.download(
151
179
 
152
180
  ---
153
181
 
182
+ ### Power Rankings - **NEW**
183
+
184
+ Epic's own competitive Power Rankings ladder — the same figure shown in the in-game Compete tab and on Fortnite's competitive site. Read live from Epic's events service; nothing here is computed by the API or taken from a third-party tracker.
185
+
186
+ Top 10,000 players (100 pages x 100), chapter-scoped (e.g. `"C7 Power Rankings"`). Epic publishes the ladder as a periodic snapshot — every entry on every page carries the same `sessionHistory[0].endTime`, which is that snapshot's date. The API re-fetches Epic hourly and rebuilds the search index every 2 hours.
187
+
188
+ #### Leaderboard
189
+
190
+ ```typescript
191
+ const board = await client.powerRankings.getLeaderboard({ page: 0 });
192
+
193
+ const top = board.entries[0];
194
+ console.log(top.rank); // 1
195
+ console.log(top.pointsEarned); // PR score
196
+ console.log(top.sessionHistory[0].trackedStats); // PR, countingEvents (max 20), peakPR, deltaPR, peakPerf
197
+ console.log(top.teamAccountDisplayNames); // display names, already resolved
198
+ ```
199
+
200
+ Pass a token **and** the matching `accountId` to also get that player's own entry as `playerEntry`, even when they fall outside the requested page:
201
+
202
+ ```typescript
203
+ const board = await client.powerRankings.getLeaderboard(
204
+ { page: 0, accountId: "your-account-id" },
205
+ "fortniteToken"
206
+ );
207
+ console.log(board.playerEntry); // null when unranked
208
+ ```
209
+
210
+ #### Look up one player — **no token**
211
+
212
+ ```typescript
213
+ const found = await client.powerRankings.search("scroll", 3);
214
+ console.log(found.results[0]); // { accountId, displayName, rank, score, countingEvents, peakPr, deltaPr }
215
+
216
+ const archived = await client.powerRankings.getFromArchive("accountId");
217
+ console.log(archived.rank, archived.bestRank, archived.seasonLabel, archived.lastUpdated);
218
+ ```
219
+
220
+ #### Look up one player — **token required**
221
+
222
+ `getPlayer()` needs the `x-fortnite-token` of the player being looked up. Epic rejects the underlying `teamAccountIds` filter under service auth, so a token-less call returns **400** for every account, including accounts inside the top 10,000. With the token it resolves players ranked beyond the top 10,000 as well.
223
+
224
+ ```typescript
225
+ const entry = await client.powerRankings.getPlayer("displayNameOrAccountId", "fortniteToken");
226
+ console.log(entry.rank, entry.pointsEarned, entry.trackedStats);
227
+ ```
228
+
229
+ > **Note:** PR is a rolling aggregate of a player's best 20 events (`countingEvents` caps at 20). Epic does not publish how much any individual tournament contributed, so there is no per-event PR figure in this data.
230
+
231
+ ---
232
+
154
233
  ### Quests - **NEW**
155
234
 
156
235
  Access player quest progress, XP, and account level information.
@@ -446,6 +525,31 @@ const history = await client.map.getHistory();
446
525
 
447
526
  ---
448
527
 
528
+ ### Sprites - **NEW**
529
+
530
+ Seasonal Sprites catalog (Chapter 7 Season 3 extraction mechanic) — every sprite family and variant with rarity, icons, boons, and **live drop rates**. Drop weights include Epic's live hotfix overlay, so Power-Hour / "More Gem Sprites!" rotations show up without waiting for a game update.
531
+
532
+ ```typescript
533
+ // Get the full catalog (families, variants, drop rates, level-up curve, event weight sets)
534
+ const catalog = await client.sprites.getSprites();
535
+ // catalog.data.sprites[0].variants[1].dropChancePercent -> e.g. 2 (% within the family)
536
+
537
+ // Only Gold variants across all families
538
+ const gold = await client.sprites.getSprites({ variant: "gold" });
539
+
540
+ // Search by name, filter by rarity
541
+ const ducks = await client.sprites.getSprites({ search: "duck" });
542
+ const legendaries = await client.sprites.getSprites({ rarity: "legendary" });
543
+
544
+ // One family — by family id, variant id, or display name
545
+ const duck = await client.sprites.getSprite("DuckSprite");
546
+
547
+ // All SpriteBoons perks with names and descriptions
548
+ const boons = await client.sprites.getBoons();
549
+ ```
550
+
551
+ ---
552
+
449
553
  ### Playlists - **NEW**
450
554
 
451
555
  Fortnite playlists and game modes.
package/dist/client.d.ts CHANGED
@@ -19,6 +19,8 @@ import { CosmeticsResource } from "./resources/cosmetics";
19
19
  import { CrewResource } from "./resources/crew";
20
20
  import { MapResource } from "./resources/map";
21
21
  import { PlaylistsResource } from "./resources/playlists";
22
+ import { SpritesResource } from "./resources/sprites";
23
+ import { PowerRankingsResource } from "./resources/powerrankings";
22
24
  export interface ClientOptions {
23
25
  apiKey: string;
24
26
  baseUrl?: string;
@@ -47,6 +49,8 @@ export declare class FortniteAPI {
47
49
  crew: CrewResource;
48
50
  map: MapResource;
49
51
  playlists: PlaylistsResource;
52
+ sprites: SpritesResource;
53
+ powerRankings: PowerRankingsResource;
50
54
  constructor(options: ClientOptions);
51
55
  /**
52
56
  * Internal method to make HTTP requests
package/dist/client.js CHANGED
@@ -23,6 +23,8 @@ const cosmetics_1 = require("./resources/cosmetics");
23
23
  const crew_1 = require("./resources/crew");
24
24
  const map_1 = require("./resources/map");
25
25
  const playlists_1 = require("./resources/playlists");
26
+ const sprites_1 = require("./resources/sprites");
27
+ const powerrankings_1 = require("./resources/powerrankings");
26
28
  class FortniteAPI {
27
29
  constructor(options) {
28
30
  this.apiKey = options.apiKey;
@@ -50,6 +52,8 @@ class FortniteAPI {
50
52
  this.crew = new crew_1.CrewResource(this);
51
53
  this.map = new map_1.MapResource(this);
52
54
  this.playlists = new playlists_1.PlaylistsResource(this);
55
+ this.sprites = new sprites_1.SpritesResource(this);
56
+ this.powerRankings = new powerrankings_1.PowerRankingsResource(this);
53
57
  }
54
58
  /**
55
59
  * Internal method to make HTTP requests
@@ -41,10 +41,32 @@ export declare class EventsResource {
41
41
  getPlayerWindowStanding(eventId: string, eventWindowId: string, accountId: string): Promise<PlayerWindowStanding>;
42
42
  /**
43
43
  * Get a player's event participation history.
44
- * Uses the V2 events endpoint with service token — no user token required.
44
+ *
45
+ * **`fortniteToken` is mandatory.** Epic serves this history only to the player
46
+ * it belongs to — service auth is rejected, so a token-less call returns **401**.
47
+ * Get a token through the OAuth flow: `client.oauth.getToken()` then
48
+ * `client.oauth.complete()`.
49
+ *
50
+ * Returns one score object per event window: `scoreKey` (gameId, eventId,
51
+ * eventWindowId), `teamId`, `teamAccountIds` (so team size is
52
+ * `teamAccountIds.length`), `pointsEarned`, `score`, `rank` (the placement),
53
+ * `percentile`, `pointBreakdown`, `sessionHistory` (one entry per match, with
54
+ * `endTime` and tracked stats) and `unscoredSessions`.
55
+ *
56
+ * Note that Epic returns raw event/window IDs here, not display names — pair it
57
+ * with `client.tournaments.getTracker()` for human-readable event names and the
58
+ * official window begin/end times.
59
+ *
60
+ * If you do not have the player's token, look a single tournament up instead with
61
+ * `client.tournaments.getPlayerWindowMatches()`, which needs no user token.
62
+ *
45
63
  * @param accountId - Epic account ID of the player
64
+ * @param fortniteToken - Required. Fortnite access token of that same player.
65
+ *
66
+ * @throws {FortniteAPIError} 401 when the token is missing, expired, or belongs to
67
+ * a different account
46
68
  */
47
- getPlayerEventHistory(accountId: string): Promise<any>;
69
+ getPlayerEventHistory(accountId: string, fortniteToken: string): Promise<any>;
48
70
  /**
49
71
  * Get the raw token set for one or more players.
50
72
  * Tokens are eligibility flags earned by participating in tournaments
@@ -56,11 +56,33 @@ class EventsResource {
56
56
  }
57
57
  /**
58
58
  * Get a player's event participation history.
59
- * Uses the V2 events endpoint with service token — no user token required.
59
+ *
60
+ * **`fortniteToken` is mandatory.** Epic serves this history only to the player
61
+ * it belongs to — service auth is rejected, so a token-less call returns **401**.
62
+ * Get a token through the OAuth flow: `client.oauth.getToken()` then
63
+ * `client.oauth.complete()`.
64
+ *
65
+ * Returns one score object per event window: `scoreKey` (gameId, eventId,
66
+ * eventWindowId), `teamId`, `teamAccountIds` (so team size is
67
+ * `teamAccountIds.length`), `pointsEarned`, `score`, `rank` (the placement),
68
+ * `percentile`, `pointBreakdown`, `sessionHistory` (one entry per match, with
69
+ * `endTime` and tracked stats) and `unscoredSessions`.
70
+ *
71
+ * Note that Epic returns raw event/window IDs here, not display names — pair it
72
+ * with `client.tournaments.getTracker()` for human-readable event names and the
73
+ * official window begin/end times.
74
+ *
75
+ * If you do not have the player's token, look a single tournament up instead with
76
+ * `client.tournaments.getPlayerWindowMatches()`, which needs no user token.
77
+ *
60
78
  * @param accountId - Epic account ID of the player
79
+ * @param fortniteToken - Required. Fortnite access token of that same player.
80
+ *
81
+ * @throws {FortniteAPIError} 401 when the token is missing, expired, or belongs to
82
+ * a different account
61
83
  */
62
- async getPlayerEventHistory(accountId) {
63
- return this.client.request(`/events/players/${encodeURIComponent(accountId)}/history`, {}, "v2");
84
+ async getPlayerEventHistory(accountId, fortniteToken) {
85
+ return this.client.request(`/events/players/${encodeURIComponent(accountId)}/history`, { headers: { "x-fortnite-token": fortniteToken } }, "v2");
64
86
  }
65
87
  /**
66
88
  * Get the raw token set for one or more players.
@@ -0,0 +1,95 @@
1
+ import { FortniteAPI } from "../client";
2
+ import { PowerRankingsLeaderboard, PowerRankingsSearchResponse, PowerRankingsArchiveEntry, PowerRankingsPlayerEntry } from "../types";
3
+ /**
4
+ * Power Rankings Resource
5
+ *
6
+ * Epic's own competitive Power Rankings ladder — the same figure shown in the
7
+ * in-game Compete tab and on Fortnite's competitive site. It is read live from
8
+ * Epic's events service (`epicgames_dreamyparadox`); nothing here is computed by
9
+ * the API or sourced from a third-party tracker.
10
+ *
11
+ * The ladder covers the top 10,000 players (100 pages x 100 entries) and is
12
+ * chapter-scoped (e.g. `"C7 Power Rankings"`).
13
+ *
14
+ * Epic publishes the ladder as a periodic snapshot: every entry on every page
15
+ * carries the same `sessionHistory[0].endTime`, which is the date of the snapshot
16
+ * currently being served. The API re-fetches Epic hourly and rebuilds the search
17
+ * index every 2 hours, so polling more often than that will not surface newer data.
18
+ *
19
+ * All methods require the `pro` or `custom` plan.
20
+ */
21
+ export declare class PowerRankingsResource {
22
+ private client;
23
+ constructor(client: FortniteAPI);
24
+ /**
25
+ * Get a page of the Power Rankings leaderboard.
26
+ *
27
+ * 100 entries per page, 100 pages total (top 10,000). No `x-fortnite-token`
28
+ * needed for the global page.
29
+ *
30
+ * Per entry: `rank`, `pointsEarned` / `score` (the PR value),
31
+ * `teamAccountIds`, `teamAccountDisplayNames`, `playerFlagTokens` (region), and
32
+ * `sessionHistory[0].trackedStats` with `PR`, `countingEvents` (capped at 20),
33
+ * `peakPerf`, `deltaPR`, `peakPR` and `deltaPosition`.
34
+ *
35
+ * @param options.page - Zero-indexed page (default: 0, max: 99)
36
+ * @param options.accountId - Epic account ID of the token holder. Required when
37
+ * `fortniteToken` is supplied, ignored otherwise.
38
+ * @param fortniteToken - Optional. When supplied together with `accountId`, the
39
+ * response also carries that player's own entry as
40
+ * `playerEntry` (`null` when they are unranked), even if
41
+ * they sit outside the requested page.
42
+ */
43
+ getLeaderboard(options?: {
44
+ page?: number;
45
+ accountId?: string;
46
+ }, fortniteToken?: string): Promise<PowerRankingsLeaderboard>;
47
+ /**
48
+ * Search Power Rankings players by display name (partial, case-insensitive).
49
+ *
50
+ * Backed by an in-memory index built from the full 10,000-player leaderboard and
51
+ * rebuilt every 2 hours. **No `x-fortnite-token` required** — this is the simplest
52
+ * way to resolve a player's PR when you do not have their OAuth token.
53
+ *
54
+ * @param q - Display name search term (partial match; 2+ characters recommended)
55
+ * @param limit - Max results (default: 10, max: 50)
56
+ */
57
+ search(q: string, limit?: number): Promise<PowerRankingsSearchResponse>;
58
+ /**
59
+ * Look up a player's live Power Rankings entry by display name or account ID.
60
+ *
61
+ * **`fortniteToken` is mandatory, and it must belong to the player being looked
62
+ * up.** Epic rejects the `teamAccountIds` filter this endpoint relies on when the
63
+ * request carries service auth, so a token-less call returns **400** for every
64
+ * account — including accounts that sit inside the top 10,000. With the token the
65
+ * entry resolves even when the player is ranked beyond the top 10,000.
66
+ *
67
+ * Get a token through the OAuth flow: `client.oauth.getToken()` then
68
+ * `client.oauth.complete()`.
69
+ *
70
+ * If you do not have the player's token, use {@link search} or
71
+ * {@link getFromArchive} instead — same PR figures, no OAuth required.
72
+ *
73
+ * @param identifier - Epic display name or 32-char hex account ID (clan tags are
74
+ * stripped automatically)
75
+ * @param fortniteToken - Required. Fortnite access token of the player being looked up.
76
+ *
77
+ * @throws {FortniteAPIError} 400 when the token is missing, expired, or belongs to
78
+ * a different account
79
+ * @throws {FortniteAPIError} 404 when the player has no Power Rankings entry
80
+ */
81
+ getPlayer(identifier: string, fortniteToken: string): Promise<PowerRankingsPlayerEntry>;
82
+ /**
83
+ * Look up a player's most recent archived Power Rankings entry by account ID.
84
+ *
85
+ * **No `x-fortnite-token` required.** Works for any account that has appeared in
86
+ * the top-10,000 leaderboard. Returns `rank`, `score`, `bestRank`, `peakPr`,
87
+ * `deltaPr`, `countingEvents`, `seasonLabel` and `lastUpdated` — read the
88
+ * `lastUpdated` timestamp to see how fresh the archived row is.
89
+ *
90
+ * @param accountId - 32-char hex Epic account ID
91
+ *
92
+ * @throws {FortniteAPIError} 404 when the account is not in the archive
93
+ */
94
+ getFromArchive(accountId: string): Promise<PowerRankingsArchiveEntry>;
95
+ }
@@ -0,0 +1,115 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PowerRankingsResource = void 0;
4
+ /**
5
+ * Power Rankings Resource
6
+ *
7
+ * Epic's own competitive Power Rankings ladder — the same figure shown in the
8
+ * in-game Compete tab and on Fortnite's competitive site. It is read live from
9
+ * Epic's events service (`epicgames_dreamyparadox`); nothing here is computed by
10
+ * the API or sourced from a third-party tracker.
11
+ *
12
+ * The ladder covers the top 10,000 players (100 pages x 100 entries) and is
13
+ * chapter-scoped (e.g. `"C7 Power Rankings"`).
14
+ *
15
+ * Epic publishes the ladder as a periodic snapshot: every entry on every page
16
+ * carries the same `sessionHistory[0].endTime`, which is the date of the snapshot
17
+ * currently being served. The API re-fetches Epic hourly and rebuilds the search
18
+ * index every 2 hours, so polling more often than that will not surface newer data.
19
+ *
20
+ * All methods require the `pro` or `custom` plan.
21
+ */
22
+ class PowerRankingsResource {
23
+ constructor(client) {
24
+ this.client = client;
25
+ }
26
+ /**
27
+ * Get a page of the Power Rankings leaderboard.
28
+ *
29
+ * 100 entries per page, 100 pages total (top 10,000). No `x-fortnite-token`
30
+ * needed for the global page.
31
+ *
32
+ * Per entry: `rank`, `pointsEarned` / `score` (the PR value),
33
+ * `teamAccountIds`, `teamAccountDisplayNames`, `playerFlagTokens` (region), and
34
+ * `sessionHistory[0].trackedStats` with `PR`, `countingEvents` (capped at 20),
35
+ * `peakPerf`, `deltaPR`, `peakPR` and `deltaPosition`.
36
+ *
37
+ * @param options.page - Zero-indexed page (default: 0, max: 99)
38
+ * @param options.accountId - Epic account ID of the token holder. Required when
39
+ * `fortniteToken` is supplied, ignored otherwise.
40
+ * @param fortniteToken - Optional. When supplied together with `accountId`, the
41
+ * response also carries that player's own entry as
42
+ * `playerEntry` (`null` when they are unranked), even if
43
+ * they sit outside the requested page.
44
+ */
45
+ async getLeaderboard(options, fortniteToken) {
46
+ const params = new URLSearchParams();
47
+ if (options?.page != null)
48
+ params.append("page", String(options.page));
49
+ if (options?.accountId)
50
+ params.append("accountId", options.accountId);
51
+ const qs = params.toString();
52
+ const requestOptions = fortniteToken
53
+ ? { headers: { "x-fortnite-token": fortniteToken } }
54
+ : undefined;
55
+ return this.client.request(`/events/powerrankings${qs ? `?${qs}` : ""}`, requestOptions);
56
+ }
57
+ /**
58
+ * Search Power Rankings players by display name (partial, case-insensitive).
59
+ *
60
+ * Backed by an in-memory index built from the full 10,000-player leaderboard and
61
+ * rebuilt every 2 hours. **No `x-fortnite-token` required** — this is the simplest
62
+ * way to resolve a player's PR when you do not have their OAuth token.
63
+ *
64
+ * @param q - Display name search term (partial match; 2+ characters recommended)
65
+ * @param limit - Max results (default: 10, max: 50)
66
+ */
67
+ async search(q, limit) {
68
+ const params = new URLSearchParams({ q });
69
+ if (limit != null)
70
+ params.append("limit", String(limit));
71
+ return this.client.request(`/events/powerrankings/search?${params.toString()}`);
72
+ }
73
+ /**
74
+ * Look up a player's live Power Rankings entry by display name or account ID.
75
+ *
76
+ * **`fortniteToken` is mandatory, and it must belong to the player being looked
77
+ * up.** Epic rejects the `teamAccountIds` filter this endpoint relies on when the
78
+ * request carries service auth, so a token-less call returns **400** for every
79
+ * account — including accounts that sit inside the top 10,000. With the token the
80
+ * entry resolves even when the player is ranked beyond the top 10,000.
81
+ *
82
+ * Get a token through the OAuth flow: `client.oauth.getToken()` then
83
+ * `client.oauth.complete()`.
84
+ *
85
+ * If you do not have the player's token, use {@link search} or
86
+ * {@link getFromArchive} instead — same PR figures, no OAuth required.
87
+ *
88
+ * @param identifier - Epic display name or 32-char hex account ID (clan tags are
89
+ * stripped automatically)
90
+ * @param fortniteToken - Required. Fortnite access token of the player being looked up.
91
+ *
92
+ * @throws {FortniteAPIError} 400 when the token is missing, expired, or belongs to
93
+ * a different account
94
+ * @throws {FortniteAPIError} 404 when the player has no Power Rankings entry
95
+ */
96
+ async getPlayer(identifier, fortniteToken) {
97
+ return this.client.request(`/events/powerrankings/player/${encodeURIComponent(identifier)}`, { headers: { "x-fortnite-token": fortniteToken } });
98
+ }
99
+ /**
100
+ * Look up a player's most recent archived Power Rankings entry by account ID.
101
+ *
102
+ * **No `x-fortnite-token` required.** Works for any account that has appeared in
103
+ * the top-10,000 leaderboard. Returns `rank`, `score`, `bestRank`, `peakPr`,
104
+ * `deltaPr`, `countingEvents`, `seasonLabel` and `lastUpdated` — read the
105
+ * `lastUpdated` timestamp to see how fresh the archived row is.
106
+ *
107
+ * @param accountId - 32-char hex Epic account ID
108
+ *
109
+ * @throws {FortniteAPIError} 404 when the account is not in the archive
110
+ */
111
+ async getFromArchive(accountId) {
112
+ return this.client.request(`/events/powerrankings/archive/${encodeURIComponent(accountId)}`);
113
+ }
114
+ }
115
+ exports.PowerRankingsResource = PowerRankingsResource;
@@ -0,0 +1,29 @@
1
+ import { FortniteAPI } from "../client";
2
+ import { SpritesResponse, SpriteResponse, SpriteBoonsResponse } from "../types";
3
+ export declare class SpritesResource {
4
+ private client;
5
+ constructor(client: FortniteAPI);
6
+ /**
7
+ * Get the full sprite catalog: families with nested variants, current + PAK-base
8
+ * drop weights, normalized drop chances, rarity, icons, boons, the level-up XP
9
+ * curve, and alternate event weight sets. Drop weights include Epic's live hotfix
10
+ * overlay, so Power-Hour / event rotations are reflected without a game update.
11
+ * @param options.search - Filter by sprite name or id (family or variant, contains match)
12
+ * @param options.rarity - Filter by rarity (e.g. epic, legendary)
13
+ * @param options.variant - Filter to one variant label across families (base, gold, candy, galaxy, gem, holofoil, cube)
14
+ */
15
+ getSprites(options?: {
16
+ search?: string;
17
+ rarity?: string;
18
+ variant?: string;
19
+ }): Promise<SpritesResponse>;
20
+ /**
21
+ * Get a single sprite family by family id (e.g. "DuckSprite"), variant id
22
+ * (e.g. "DuckSprite_Variant_Gold"), or display name (e.g. "Duck Sprite").
23
+ */
24
+ getSprite(id: string): Promise<SpriteResponse>;
25
+ /**
26
+ * Get all SpriteBoons perks with names and descriptions.
27
+ */
28
+ getBoons(): Promise<SpriteBoonsResponse>;
29
+ }
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SpritesResource = void 0;
4
+ class SpritesResource {
5
+ constructor(client) {
6
+ this.client = client;
7
+ }
8
+ /**
9
+ * Get the full sprite catalog: families with nested variants, current + PAK-base
10
+ * drop weights, normalized drop chances, rarity, icons, boons, the level-up XP
11
+ * curve, and alternate event weight sets. Drop weights include Epic's live hotfix
12
+ * overlay, so Power-Hour / event rotations are reflected without a game update.
13
+ * @param options.search - Filter by sprite name or id (family or variant, contains match)
14
+ * @param options.rarity - Filter by rarity (e.g. epic, legendary)
15
+ * @param options.variant - Filter to one variant label across families (base, gold, candy, galaxy, gem, holofoil, cube)
16
+ */
17
+ async getSprites(options) {
18
+ const params = new URLSearchParams();
19
+ if (options?.search)
20
+ params.set("search", options.search);
21
+ if (options?.rarity)
22
+ params.set("rarity", options.rarity);
23
+ if (options?.variant)
24
+ params.set("variant", options.variant);
25
+ const query = params.toString() ? `?${params.toString()}` : "";
26
+ return this.client.request(`/sprites${query}`, {}, "v2");
27
+ }
28
+ /**
29
+ * Get a single sprite family by family id (e.g. "DuckSprite"), variant id
30
+ * (e.g. "DuckSprite_Variant_Gold"), or display name (e.g. "Duck Sprite").
31
+ */
32
+ async getSprite(id) {
33
+ return this.client.request(`/sprites/${encodeURIComponent(id)}`, {}, "v2");
34
+ }
35
+ /**
36
+ * Get all SpriteBoons perks with names and descriptions.
37
+ */
38
+ async getBoons() {
39
+ return this.client.request("/sprites/boons", {}, "v2");
40
+ }
41
+ }
42
+ exports.SpritesResource = SpritesResource;
@@ -61,6 +61,56 @@ export declare class TournamentsResource {
61
61
  leaderboardDef?: string;
62
62
  accountId?: string;
63
63
  }, fortniteToken?: string): Promise<Leaderboard>;
64
+ /**
65
+ * Get a player's result in one tournament window — **no user token required.**
66
+ *
67
+ * Returns their final `rank` (placement), `pointsEarned`, `teamAccountIds` (team
68
+ * size is `teamAccountIds.length`) and every match they played in that window,
69
+ * each with `sessionId`, `endTime` and `trackedStats` (`PLACEMENT_STAT_INDEX`,
70
+ * `TEAM_ELIMS_STAT_INDEX`, `TIME_ALIVE_STAT`, `VICTORY_ROYALE_STAT`, ...).
71
+ *
72
+ * The lookup works by scanning leaderboard pages until the player's team is found.
73
+ * Pass `rankHint` (their approximate final rank) to turn it into a single page
74
+ * fetch — without it up to `maxPages` pages are scanned in order, which is slower
75
+ * and may miss players placed beyond that point.
76
+ *
77
+ * Use this when you do not have the player's OAuth token. For their full history
78
+ * across every tournament, use `client.events.getPlayerEventHistory()` (token
79
+ * required).
80
+ *
81
+ * @param eventId - Event identifier (e.g. `"epicgames_S41_CashCup_DuosZB_OCE"`)
82
+ * @param eventWindowId - Event window identifier (e.g. `"S41_CashCup_DuosZB_Event1Round1_OCE"`)
83
+ * @param accountId - Epic account ID of any player on the team
84
+ * @param options.rankHint - Approximate leaderboard rank, if known — makes this a single page fetch
85
+ * @param options.maxPages - Max leaderboard pages to scan (default: 15, max: 100)
86
+ *
87
+ * @throws {FortniteAPIError} 404 when the player was not found within the scanned pages
88
+ */
89
+ getPlayerWindowMatches(eventId: string, eventWindowId: string, accountId: string, options?: {
90
+ rankHint?: number;
91
+ maxPages?: number;
92
+ }): Promise<any>;
93
+ /**
94
+ * Get every tournament match a player has played, grouped by event window.
95
+ *
96
+ * Sourced from Epic's player-scoped download data, which Epic only serves to the
97
+ * player it belongs to — so `fortniteToken` is effectively required (without it
98
+ * Epic returns **403**). For a token-free lookup scoped to one tournament, use
99
+ * {@link getPlayerWindowMatches}.
100
+ *
101
+ * @param accountId - Epic Games Account ID
102
+ * @param fortniteToken - Fortnite access token of that same player (from OAuth flow)
103
+ * @param options.after - Only matches ending at or after this UTC timestamp
104
+ * @param options.before - Only matches ending before this UTC timestamp
105
+ * @param options.region - Region for the events catalogue (default: EU). Match history itself is global.
106
+ * @param options.platform - Platform (default: Windows)
107
+ */
108
+ getPlayerMatches(accountId: string, fortniteToken: string, options?: {
109
+ after?: string;
110
+ before?: string;
111
+ region?: string;
112
+ platform?: string;
113
+ }): Promise<any>;
64
114
  /**
65
115
  * Get tournament participation history for a player
66
116
  * Requires user's own Fortnite token
@@ -92,6 +92,68 @@ class TournamentsResource {
92
92
  : undefined;
93
93
  return this.client.request(`/events/global/leaderboard?${query.toString()}`, options);
94
94
  }
95
+ /**
96
+ * Get a player's result in one tournament window — **no user token required.**
97
+ *
98
+ * Returns their final `rank` (placement), `pointsEarned`, `teamAccountIds` (team
99
+ * size is `teamAccountIds.length`) and every match they played in that window,
100
+ * each with `sessionId`, `endTime` and `trackedStats` (`PLACEMENT_STAT_INDEX`,
101
+ * `TEAM_ELIMS_STAT_INDEX`, `TIME_ALIVE_STAT`, `VICTORY_ROYALE_STAT`, ...).
102
+ *
103
+ * The lookup works by scanning leaderboard pages until the player's team is found.
104
+ * Pass `rankHint` (their approximate final rank) to turn it into a single page
105
+ * fetch — without it up to `maxPages` pages are scanned in order, which is slower
106
+ * and may miss players placed beyond that point.
107
+ *
108
+ * Use this when you do not have the player's OAuth token. For their full history
109
+ * across every tournament, use `client.events.getPlayerEventHistory()` (token
110
+ * required).
111
+ *
112
+ * @param eventId - Event identifier (e.g. `"epicgames_S41_CashCup_DuosZB_OCE"`)
113
+ * @param eventWindowId - Event window identifier (e.g. `"S41_CashCup_DuosZB_Event1Round1_OCE"`)
114
+ * @param accountId - Epic account ID of any player on the team
115
+ * @param options.rankHint - Approximate leaderboard rank, if known — makes this a single page fetch
116
+ * @param options.maxPages - Max leaderboard pages to scan (default: 15, max: 100)
117
+ *
118
+ * @throws {FortniteAPIError} 404 when the player was not found within the scanned pages
119
+ */
120
+ async getPlayerWindowMatches(eventId, eventWindowId, accountId, options) {
121
+ const params = new URLSearchParams();
122
+ if (options?.rankHint != null)
123
+ params.append("rankHint", String(options.rankHint));
124
+ if (options?.maxPages != null)
125
+ params.append("maxPages", String(options.maxPages));
126
+ const qs = params.toString();
127
+ return this.client.request(`/events/${encodeURIComponent(eventId)}/${encodeURIComponent(eventWindowId)}/player/${encodeURIComponent(accountId)}/matches${qs ? `?${qs}` : ""}`);
128
+ }
129
+ /**
130
+ * Get every tournament match a player has played, grouped by event window.
131
+ *
132
+ * Sourced from Epic's player-scoped download data, which Epic only serves to the
133
+ * player it belongs to — so `fortniteToken` is effectively required (without it
134
+ * Epic returns **403**). For a token-free lookup scoped to one tournament, use
135
+ * {@link getPlayerWindowMatches}.
136
+ *
137
+ * @param accountId - Epic Games Account ID
138
+ * @param fortniteToken - Fortnite access token of that same player (from OAuth flow)
139
+ * @param options.after - Only matches ending at or after this UTC timestamp
140
+ * @param options.before - Only matches ending before this UTC timestamp
141
+ * @param options.region - Region for the events catalogue (default: EU). Match history itself is global.
142
+ * @param options.platform - Platform (default: Windows)
143
+ */
144
+ async getPlayerMatches(accountId, fortniteToken, options) {
145
+ const params = new URLSearchParams();
146
+ if (options?.after)
147
+ params.append("after", options.after);
148
+ if (options?.before)
149
+ params.append("before", options.before);
150
+ if (options?.region)
151
+ params.append("region", options.region);
152
+ if (options?.platform)
153
+ params.append("platform", options.platform);
154
+ const qs = params.toString();
155
+ return this.client.request(`/events/player/${encodeURIComponent(accountId)}/matches${qs ? `?${qs}` : ""}`, { headers: { "x-fortnite-token": fortniteToken } });
156
+ }
95
157
  /**
96
158
  * Get tournament participation history for a player
97
159
  * Requires user's own Fortnite token
@@ -733,6 +733,110 @@ export interface PlayerWindowStanding {
733
733
  percentile?: number;
734
734
  sessionHistory: PlayerWindowStandingSession[];
735
735
  }
736
+ /**
737
+ * Tracked stats carried on a Power Rankings ladder entry.
738
+ * `PR` is the Power Rankings score itself; `countingEvents` is capped at 20
739
+ * (Epic only counts a player's best 20 events).
740
+ */
741
+ export interface PowerRankingsTrackedStats {
742
+ PR: number;
743
+ countingEvents: number;
744
+ peakPerf: number;
745
+ deltaPR: number;
746
+ peakPR: number;
747
+ deltaPosition?: number;
748
+ }
749
+ export interface PowerRankingsSession {
750
+ sessionId: string;
751
+ /** Date of the Epic snapshot this ladder was published from — identical across every entry. */
752
+ endTime: string;
753
+ trackedStats: PowerRankingsTrackedStats;
754
+ }
755
+ export interface PowerRankingsLeaderboardEntry {
756
+ gameId: string;
757
+ eventId: string;
758
+ eventWindowId: string;
759
+ teamId: string;
760
+ teamAccountIds: string[];
761
+ teamAccountDisplayNames?: string[];
762
+ /** The player's PR value. `score` carries the same number. */
763
+ pointsEarned: number;
764
+ score: number;
765
+ rank: number;
766
+ percentile: number;
767
+ pointBreakdown: Record<string, {
768
+ timesAchieved: number;
769
+ pointsEarned: number;
770
+ }>;
771
+ sessionHistory: PowerRankingsSession[];
772
+ /** Region/geo identity flag, e.g. `GroupIdentity_GeoIdentity_denmark`. */
773
+ playerFlagTokens?: Record<string, string>;
774
+ unscoredSessions?: any[];
775
+ }
776
+ /**
777
+ * Returned by GET /api/v1/events/powerrankings
778
+ */
779
+ export interface PowerRankingsLeaderboard {
780
+ gameId: string;
781
+ eventId: string;
782
+ eventWindowId: string;
783
+ page: number;
784
+ totalPages: number;
785
+ updatedTime: string;
786
+ entries: PowerRankingsLeaderboardEntry[];
787
+ /**
788
+ * The token holder's own entry — present only when both `x-fortnite-token` and
789
+ * `accountId` were supplied. `null` when that player is unranked.
790
+ */
791
+ playerEntry?: PowerRankingsLeaderboardEntry | null;
792
+ }
793
+ export interface PowerRankingsSearchResult {
794
+ accountId: string;
795
+ displayName: string;
796
+ rank: number;
797
+ score: number;
798
+ countingEvents: number;
799
+ peakPr: number;
800
+ deltaPr: number;
801
+ }
802
+ /**
803
+ * Returned by GET /api/v1/events/powerrankings/search
804
+ */
805
+ export interface PowerRankingsSearchResponse {
806
+ query: string;
807
+ total: number;
808
+ results: PowerRankingsSearchResult[];
809
+ }
810
+ /**
811
+ * Returned by GET /api/v1/events/powerrankings/player/{identifier}
812
+ * (requires the x-fortnite-token of the player being looked up)
813
+ */
814
+ export interface PowerRankingsPlayerEntry {
815
+ accountId: string;
816
+ displayName: string;
817
+ eventId: string;
818
+ eventWindowId: string;
819
+ rank?: number;
820
+ pointsEarned?: number;
821
+ trackedStats?: PowerRankingsTrackedStats;
822
+ }
823
+ /**
824
+ * Returned by GET /api/v1/events/powerrankings/archive/{accountId}
825
+ */
826
+ export interface PowerRankingsArchiveEntry {
827
+ accountId: string;
828
+ displayName: string;
829
+ rank: number;
830
+ score: number;
831
+ bestRank: number;
832
+ peakPr: number;
833
+ deltaPr: number;
834
+ countingEvents: number;
835
+ /** When this archived row was last refreshed — not the date of Epic's snapshot. */
836
+ lastUpdated: string;
837
+ /** Chapter the ladder belongs to, e.g. `"C7 Power Rankings"`. */
838
+ seasonLabel: string;
839
+ }
736
840
  export interface PayoutTableReward {
737
841
  itemType: string;
738
842
  itemId?: string;
@@ -1008,3 +1112,78 @@ export interface Playlist {
1008
1112
  lastModified?: string;
1009
1113
  [key: string]: any;
1010
1114
  }
1115
+ export interface SpriteImages {
1116
+ icon?: string | null;
1117
+ iconLarge?: string | null;
1118
+ }
1119
+ export interface SpriteBoonRef {
1120
+ id: string;
1121
+ chance?: number | null;
1122
+ }
1123
+ export interface SpriteVariant {
1124
+ id: string;
1125
+ /** Variant label: Base, Gold, Candy, Galaxy, Gem, Holofoil, Cube, ... */
1126
+ variant: string;
1127
+ name?: string | null;
1128
+ rarity?: string | null;
1129
+ /** False when the current hotfix disables the variant. */
1130
+ enabled: boolean;
1131
+ images?: SpriteImages | null;
1132
+ /** Weight as cooked in the game files (PAK). */
1133
+ baseWeight?: number | null;
1134
+ /** Weight after Epic's live hotfix overlay — what the game currently uses. */
1135
+ weight?: number | null;
1136
+ /** Current weight normalized within the family, percentage 0-100. */
1137
+ dropChancePercent?: number | null;
1138
+ boons: SpriteBoonRef[];
1139
+ }
1140
+ export interface SpriteFamily {
1141
+ id: string;
1142
+ name?: string | null;
1143
+ description?: string | null;
1144
+ /** Epic's own sprite-dex ordering number. */
1145
+ dexNumber?: number | null;
1146
+ rarity?: string | null;
1147
+ acquisitionHint?: string | null;
1148
+ extractRewardLootTier?: string | null;
1149
+ images?: SpriteImages | null;
1150
+ tags: string[];
1151
+ boons: SpriteBoonRef[];
1152
+ variants: SpriteVariant[];
1153
+ }
1154
+ export interface SpriteLevel {
1155
+ level: number;
1156
+ xp: number;
1157
+ }
1158
+ export interface SpriteEvent {
1159
+ name: string;
1160
+ weights: Record<string, number>;
1161
+ }
1162
+ export interface SpritesData {
1163
+ gameVersion: string;
1164
+ generated: string;
1165
+ /** True when the drop weights include the live CloudStorage hotfix overlay. */
1166
+ hotfixApplied: boolean;
1167
+ sprites: SpriteFamily[];
1168
+ /** Cumulative Sprite Dust thresholds per sprite level. */
1169
+ levelUpCurve: SpriteLevel[];
1170
+ /** Alternate weight sets from event hotfixes (Power Hours etc.). */
1171
+ events: SpriteEvent[];
1172
+ }
1173
+ export interface SpritesResponse {
1174
+ status: number;
1175
+ data: SpritesData;
1176
+ }
1177
+ export interface SpriteResponse {
1178
+ status: number;
1179
+ data: SpriteFamily;
1180
+ }
1181
+ export interface SpriteBoon {
1182
+ id: string;
1183
+ name?: string | null;
1184
+ description?: string | null;
1185
+ }
1186
+ export interface SpriteBoonsResponse {
1187
+ status: number;
1188
+ data: SpriteBoon[];
1189
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yaelouuu/fortnite-api",
3
- "version": "8.0.0",
3
+ "version": "9.0.0",
4
4
  "description": "SDK for Fortnite API - api-fortnite.com - Author : Yael Brinkert",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",