@yaelouuu/fortnite-api 8.1.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 +80 -1
- package/dist/client.d.ts +2 -0
- package/dist/client.js +2 -0
- package/dist/resources/events.d.ts +24 -2
- package/dist/resources/events.js +25 -3
- package/dist/resources/powerrankings.d.ts +95 -0
- package/dist/resources/powerrankings.js +115 -0
- package/dist/resources/tournaments.d.ts +50 -0
- package/dist/resources/tournaments.js +62 -0
- package/dist/types/index.d.ts +104 -0
- package/package.json +1 -1
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.
|
package/dist/client.d.ts
CHANGED
|
@@ -20,6 +20,7 @@ import { CrewResource } from "./resources/crew";
|
|
|
20
20
|
import { MapResource } from "./resources/map";
|
|
21
21
|
import { PlaylistsResource } from "./resources/playlists";
|
|
22
22
|
import { SpritesResource } from "./resources/sprites";
|
|
23
|
+
import { PowerRankingsResource } from "./resources/powerrankings";
|
|
23
24
|
export interface ClientOptions {
|
|
24
25
|
apiKey: string;
|
|
25
26
|
baseUrl?: string;
|
|
@@ -49,6 +50,7 @@ export declare class FortniteAPI {
|
|
|
49
50
|
map: MapResource;
|
|
50
51
|
playlists: PlaylistsResource;
|
|
51
52
|
sprites: SpritesResource;
|
|
53
|
+
powerRankings: PowerRankingsResource;
|
|
52
54
|
constructor(options: ClientOptions);
|
|
53
55
|
/**
|
|
54
56
|
* Internal method to make HTTP requests
|
package/dist/client.js
CHANGED
|
@@ -24,6 +24,7 @@ const crew_1 = require("./resources/crew");
|
|
|
24
24
|
const map_1 = require("./resources/map");
|
|
25
25
|
const playlists_1 = require("./resources/playlists");
|
|
26
26
|
const sprites_1 = require("./resources/sprites");
|
|
27
|
+
const powerrankings_1 = require("./resources/powerrankings");
|
|
27
28
|
class FortniteAPI {
|
|
28
29
|
constructor(options) {
|
|
29
30
|
this.apiKey = options.apiKey;
|
|
@@ -52,6 +53,7 @@ class FortniteAPI {
|
|
|
52
53
|
this.map = new map_1.MapResource(this);
|
|
53
54
|
this.playlists = new playlists_1.PlaylistsResource(this);
|
|
54
55
|
this.sprites = new sprites_1.SpritesResource(this);
|
|
56
|
+
this.powerRankings = new powerrankings_1.PowerRankingsResource(this);
|
|
55
57
|
}
|
|
56
58
|
/**
|
|
57
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
|
-
*
|
|
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
|
package/dist/resources/events.js
CHANGED
|
@@ -56,11 +56,33 @@ class EventsResource {
|
|
|
56
56
|
}
|
|
57
57
|
/**
|
|
58
58
|
* Get a player's event participation history.
|
|
59
|
-
*
|
|
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;
|
|
@@ -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
|
package/dist/types/index.d.ts
CHANGED
|
@@ -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;
|