@yaelouuu/fortnite-api 9.1.1 → 9.2.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 +34 -17
- package/dist/resources/battlepass.d.ts +4 -1
- package/dist/resources/battlepass.js +4 -1
- package/dist/resources/news.d.ts +22 -14
- package/dist/resources/news.js +37 -21
- package/dist/resources/tournaments.d.ts +2 -2
- package/dist/resources/tournaments.js +2 -2
- package/dist/types/index.d.ts +64 -25
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -47,16 +47,17 @@ const leaderboard = await client.tournaments.getLeaderboard({
|
|
|
47
47
|
|
|
48
48
|
### Shop
|
|
49
49
|
|
|
50
|
-
Access the Fortnite Item Shop
|
|
50
|
+
Access the current Fortnite Item Shop.
|
|
51
51
|
|
|
52
52
|
```typescript
|
|
53
53
|
// Get current item shop
|
|
54
54
|
const shop = await client.shop.getCurrent();
|
|
55
|
-
|
|
56
|
-
// Get current Battle Pass
|
|
57
|
-
const battlePass = await client.battlepass.getBattlePass();
|
|
58
55
|
```
|
|
59
56
|
|
|
57
|
+
> `client.battlepass.getBattlePass()` is deprecated: the endpoint behind it
|
|
58
|
+
> (`/api/v1/shop/battlepass`) never returned the Battle Pass, only Epic's legacy 2021 news block.
|
|
59
|
+
> For the Battle Pass call `GET /api/v2/battlepass`.
|
|
60
|
+
|
|
60
61
|
---
|
|
61
62
|
|
|
62
63
|
### Tournaments
|
|
@@ -158,7 +159,7 @@ if (session.inMatch && session.playlist === "playlist_showdown_cts_solo") {
|
|
|
158
159
|
}
|
|
159
160
|
```
|
|
160
161
|
|
|
161
|
-
Read before building on it: the token flow authenticates as the Fortnite client, not as your application — Epic warns the player accordingly, and if you ship an Epic Account Services application its developer terms do not allow routing your users through it (suited to tools a player runs for themselves, not third-party apps asking other players to log in); the token must be that player's **own** (verified — any other account's token is `403`); Fortnite kills every other session of an account when the game launches, so
|
|
162
|
+
Read before building on it: the token flow authenticates as the Fortnite client, not as your application — Epic warns the player accordingly, and if you ship an Epic Account Services application its developer terms do not allow routing your users through it (suited to tools a player runs for themselves, not third-party apps asking other players to log in); the token must be that player's **own** (verified — any other account's token is `403`); Fortnite kills every other session of an account when the game launches, so store the `deviceAuth` that `/oauth/complete` returns and re-authenticate with `/oauth/refresh-device` on `401`; the response is cached 10 s per account and Epic's party state lags the real match by about 1–2 minutes; the custom key is never returned (`hasCustomKey` only) and teammates appear as account ids only.
|
|
162
163
|
|
|
163
164
|
#### Check Tournament Eligibility
|
|
164
165
|
Verify if a player meets requirements for major tournaments (e.g., 14 tournaments in 180 days):
|
|
@@ -438,26 +439,34 @@ const psnAuth = await client.account.getExternalAuth('accountId123', 'psn');
|
|
|
438
439
|
|
|
439
440
|
---
|
|
440
441
|
|
|
441
|
-
### News
|
|
442
|
+
### News
|
|
442
443
|
|
|
443
|
-
|
|
444
|
+
The in-game lobby news carousel (Epic's "message of the day"), fetched live from Epic as a
|
|
445
|
+
generic account and cached 10 minutes, plus the emergency notices. Pro and Custom plans.
|
|
444
446
|
|
|
445
447
|
```typescript
|
|
446
|
-
//
|
|
447
|
-
const
|
|
448
|
-
|
|
448
|
+
// Battle Royale lobby news — optional language and platform (default en / Windows)
|
|
449
|
+
const br = await client.news.getBRNews();
|
|
450
|
+
const brFr = await client.news.getBRNews("fr", "PS5");
|
|
451
|
+
// br.motds[0] → { id, position, title, body, tileTitle, image, tileImage,
|
|
452
|
+
// images, tileImages, buttons: [{ text, action, offerId, linkId }], contentHash }
|
|
453
|
+
|
|
454
|
+
// Fortnite Festival has its own rotation
|
|
455
|
+
const festival = await client.news.getFestivalNews();
|
|
449
456
|
|
|
450
|
-
//
|
|
451
|
-
const
|
|
457
|
+
// Save the World / Creative: Epic currently serves its general lobby rotation for both
|
|
458
|
+
const stw = await client.news.getSTWNews();
|
|
459
|
+
const creative = await client.news.getCreativeNews();
|
|
452
460
|
|
|
453
|
-
//
|
|
454
|
-
const
|
|
461
|
+
// Emergency notices (warning banners), e.g. a mode leaving
|
|
462
|
+
const notices = await client.news.getNotices();
|
|
455
463
|
|
|
456
|
-
//
|
|
457
|
-
const
|
|
458
|
-
// Returns: { br, stw, creative, lastModified }
|
|
464
|
+
// Everything at once: { br, stw, creative, festival, notices }
|
|
465
|
+
const all = await client.news.getAllNews("en", "Android");
|
|
459
466
|
```
|
|
460
467
|
|
|
468
|
+
Epic personalises the carousel per player, so a real account may see a slightly different set.
|
|
469
|
+
|
|
461
470
|
---
|
|
462
471
|
|
|
463
472
|
### Cosmetics - **NEW**
|
|
@@ -736,6 +745,14 @@ MIT
|
|
|
736
745
|
|
|
737
746
|
## 🆕 Changelog
|
|
738
747
|
|
|
748
|
+
### v9.2.0 (2026-09-27)
|
|
749
|
+
- 🐛 **News now returns the live lobby news.** `/api/v1/news*` used to return Epic's legacy CMS
|
|
750
|
+
news blocks, which Epic stopped updating in 2020–2023. They now return the carousel the game
|
|
751
|
+
shows today, with a new shape (`NewsFeed`: `motds[]` with title, body, images, shop/island
|
|
752
|
+
buttons). The old `NewsResponse`/`BRNews`/`STWNews`/`CreativeNews` types are deprecated aliases.
|
|
753
|
+
- ✨ `news.getFestivalNews()`, `news.getNotices()`; every news method takes an optional `platform`.
|
|
754
|
+
- ⚠️ `battlepass.getBattlePass()` deprecated — its endpoint never returned the Battle Pass.
|
|
755
|
+
|
|
739
756
|
### v4.3.0 (2026-01-08)
|
|
740
757
|
- ✨ **NEW** `NewsResource` with 4 methods:
|
|
741
758
|
- Battle Royale news
|
|
@@ -4,7 +4,10 @@ export declare class BattlePassResource {
|
|
|
4
4
|
private client;
|
|
5
5
|
constructor(client: FortniteAPI);
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
7
|
+
* @deprecated Despite its name, GET /api/v1/shop/battlepass never returned the Battle Pass:
|
|
8
|
+
* it returns Epic's legacy "battleroyalenews" CMS block, which Epic stopped updating in 2021.
|
|
9
|
+
* For current lobby news use `client.news.getBRNews()`; for the Battle Pass call
|
|
10
|
+
* GET /api/v2/battlepass.
|
|
8
11
|
* @param lang - Language code (default: en)
|
|
9
12
|
*/
|
|
10
13
|
getBattlePass(lang?: string): Promise<BattlePass>;
|
|
@@ -6,7 +6,10 @@ class BattlePassResource {
|
|
|
6
6
|
this.client = client;
|
|
7
7
|
}
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
9
|
+
* @deprecated Despite its name, GET /api/v1/shop/battlepass never returned the Battle Pass:
|
|
10
|
+
* it returns Epic's legacy "battleroyalenews" CMS block, which Epic stopped updating in 2021.
|
|
11
|
+
* For current lobby news use `client.news.getBRNews()`; for the Battle Pass call
|
|
12
|
+
* GET /api/v2/battlepass.
|
|
10
13
|
* @param lang - Language code (default: en)
|
|
11
14
|
*/
|
|
12
15
|
async getBattlePass(lang) {
|
package/dist/resources/news.d.ts
CHANGED
|
@@ -1,26 +1,34 @@
|
|
|
1
1
|
import { FortniteAPI } from "../client";
|
|
2
|
-
import {
|
|
2
|
+
import { NewsFeed, NewsNotice, NewsPlatform, AllNews } from "../types";
|
|
3
|
+
/**
|
|
4
|
+
* The in-game lobby news carousel, fetched live from Epic as a generic account (no Battle
|
|
5
|
+
* Pass, US / NA-East) and cached 10 minutes. Epic personalises the carousel per player, so a
|
|
6
|
+
* real account may see a slightly different set. Pro and Custom plans.
|
|
7
|
+
*/
|
|
3
8
|
export declare class NewsResource {
|
|
4
9
|
private client;
|
|
5
10
|
constructor(client: FortniteAPI);
|
|
11
|
+
private query;
|
|
6
12
|
/**
|
|
7
|
-
*
|
|
13
|
+
* Battle Royale lobby news
|
|
8
14
|
* @param lang - Language code (default: en)
|
|
15
|
+
* @param platform - Platform (default: Windows); Epic varies some entries by platform
|
|
9
16
|
*/
|
|
10
|
-
getBRNews(lang?: string): Promise<
|
|
17
|
+
getBRNews(lang?: string, platform?: NewsPlatform | string): Promise<NewsFeed>;
|
|
11
18
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
19
|
+
* Lobby news Epic serves for Save the World. As of September 2026 Epic runs no separate
|
|
20
|
+
* rotation for it: this is Epic's general lobby rotation (same entries as getCreativeNews).
|
|
14
21
|
*/
|
|
15
|
-
getSTWNews(lang?: string): Promise<
|
|
22
|
+
getSTWNews(lang?: string, platform?: NewsPlatform | string): Promise<NewsFeed>;
|
|
16
23
|
/**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*/
|
|
20
|
-
getCreativeNews(lang?: string): Promise<NewsResponse<CreativeNews>>;
|
|
21
|
-
/**
|
|
22
|
-
* Get all news (BR, STW, Creative)
|
|
23
|
-
* @param lang - Language code (default: en)
|
|
24
|
+
* Lobby news Epic serves for Creative. As of September 2026 Epic runs no separate rotation
|
|
25
|
+
* for it: this is Epic's general lobby rotation (same entries as getSTWNews).
|
|
24
26
|
*/
|
|
25
|
-
|
|
27
|
+
getCreativeNews(lang?: string, platform?: NewsPlatform | string): Promise<NewsFeed>;
|
|
28
|
+
/** Fortnite Festival lobby news. */
|
|
29
|
+
getFestivalNews(lang?: string, platform?: NewsPlatform | string): Promise<NewsFeed>;
|
|
30
|
+
/** Current emergency notices (in-game warning banners). Empty when Epic has none up. */
|
|
31
|
+
getNotices(lang?: string): Promise<NewsNotice[]>;
|
|
32
|
+
/** Every mode's lobby news plus the emergency notices, in one call. */
|
|
33
|
+
getAllNews(lang?: string, platform?: NewsPlatform | string): Promise<AllNews>;
|
|
26
34
|
}
|
package/dist/resources/news.js
CHANGED
|
@@ -1,41 +1,57 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.NewsResource = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* The in-game lobby news carousel, fetched live from Epic as a generic account (no Battle
|
|
6
|
+
* Pass, US / NA-East) and cached 10 minutes. Epic personalises the carousel per player, so a
|
|
7
|
+
* real account may see a slightly different set. Pro and Custom plans.
|
|
8
|
+
*/
|
|
4
9
|
class NewsResource {
|
|
5
10
|
constructor(client) {
|
|
6
11
|
this.client = client;
|
|
7
12
|
}
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
query(lang, platform) {
|
|
14
|
+
const params = new URLSearchParams();
|
|
15
|
+
if (lang)
|
|
16
|
+
params.set("lang", lang);
|
|
17
|
+
if (platform)
|
|
18
|
+
params.set("platform", platform);
|
|
19
|
+
const q = params.toString();
|
|
20
|
+
return q ? `?${q}` : "";
|
|
15
21
|
}
|
|
16
22
|
/**
|
|
17
|
-
*
|
|
23
|
+
* Battle Royale lobby news
|
|
18
24
|
* @param lang - Language code (default: en)
|
|
25
|
+
* @param platform - Platform (default: Windows); Epic varies some entries by platform
|
|
19
26
|
*/
|
|
20
|
-
async
|
|
21
|
-
|
|
22
|
-
return this.client.request(`/news/stw${query}`);
|
|
27
|
+
async getBRNews(lang, platform) {
|
|
28
|
+
return this.client.request(`/news/br${this.query(lang, platform)}`);
|
|
23
29
|
}
|
|
24
30
|
/**
|
|
25
|
-
*
|
|
26
|
-
*
|
|
31
|
+
* Lobby news Epic serves for Save the World. As of September 2026 Epic runs no separate
|
|
32
|
+
* rotation for it: this is Epic's general lobby rotation (same entries as getCreativeNews).
|
|
27
33
|
*/
|
|
28
|
-
async
|
|
29
|
-
|
|
30
|
-
return this.client.request(`/news/creative${query}`);
|
|
34
|
+
async getSTWNews(lang, platform) {
|
|
35
|
+
return this.client.request(`/news/stw${this.query(lang, platform)}`);
|
|
31
36
|
}
|
|
32
37
|
/**
|
|
33
|
-
*
|
|
34
|
-
*
|
|
38
|
+
* Lobby news Epic serves for Creative. As of September 2026 Epic runs no separate rotation
|
|
39
|
+
* for it: this is Epic's general lobby rotation (same entries as getSTWNews).
|
|
35
40
|
*/
|
|
36
|
-
async
|
|
37
|
-
|
|
38
|
-
|
|
41
|
+
async getCreativeNews(lang, platform) {
|
|
42
|
+
return this.client.request(`/news/creative${this.query(lang, platform)}`);
|
|
43
|
+
}
|
|
44
|
+
/** Fortnite Festival lobby news. */
|
|
45
|
+
async getFestivalNews(lang, platform) {
|
|
46
|
+
return this.client.request(`/news/festival${this.query(lang, platform)}`);
|
|
47
|
+
}
|
|
48
|
+
/** Current emergency notices (in-game warning banners). Empty when Epic has none up. */
|
|
49
|
+
async getNotices(lang) {
|
|
50
|
+
return this.client.request(`/news/notices${this.query(lang)}`);
|
|
51
|
+
}
|
|
52
|
+
/** Every mode's lobby news plus the emergency notices, in one call. */
|
|
53
|
+
async getAllNews(lang, platform) {
|
|
54
|
+
return this.client.request(`/news${this.query(lang, platform)}`);
|
|
39
55
|
}
|
|
40
56
|
}
|
|
41
57
|
exports.NewsResource = NewsResource;
|
|
@@ -282,8 +282,8 @@ export declare class TournamentsResource {
|
|
|
282
282
|
* Requires that player's OWN Fortnite token: it is verified against `accountId` before
|
|
283
283
|
* anything is forwarded (any other account's token returns **403**). Fortnite kills every
|
|
284
284
|
* other session of an account when the game launches, so a token obtained before the
|
|
285
|
-
* player started playing is dead by the time they play —
|
|
286
|
-
*
|
|
285
|
+
* player started playing is dead by the time they play — store the `deviceAuth` that
|
|
286
|
+
* `/oauth/complete` returns and re-authenticate with `/oauth/refresh-device` on 401.
|
|
287
287
|
*
|
|
288
288
|
* While the player is in a game, `sessionId` is the replay match ID: pass it to the
|
|
289
289
|
* replay endpoints once the match has ended. `playlist` lets you filter (e.g. scrims)
|
|
@@ -375,8 +375,8 @@ class TournamentsResource {
|
|
|
375
375
|
* Requires that player's OWN Fortnite token: it is verified against `accountId` before
|
|
376
376
|
* anything is forwarded (any other account's token returns **403**). Fortnite kills every
|
|
377
377
|
* other session of an account when the game launches, so a token obtained before the
|
|
378
|
-
* player started playing is dead by the time they play —
|
|
379
|
-
*
|
|
378
|
+
* player started playing is dead by the time they play — store the `deviceAuth` that
|
|
379
|
+
* `/oauth/complete` returns and re-authenticate with `/oauth/refresh-device` on 401.
|
|
380
380
|
*
|
|
381
381
|
* While the player is in a game, `sessionId` is the replay match ID: pass it to the
|
|
382
382
|
* replay endpoints once the match has ended. `playlist` lets you filter (e.g. scrims)
|
package/dist/types/index.d.ts
CHANGED
|
@@ -887,38 +887,77 @@ export interface EventRewards {
|
|
|
887
887
|
currency?: string;
|
|
888
888
|
}>;
|
|
889
889
|
}
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
890
|
+
/** Platforms accepted by the news endpoints (aliases pc, playstation, xbox also work). */
|
|
891
|
+
export type NewsPlatform = "Windows" | "Mac" | "PS4" | "PS5" | "XboxOneGDK" | "XSX" | "Switch" | "Switch2" | "Android" | "IOS";
|
|
892
|
+
export interface NewsImage {
|
|
893
|
+
width: number;
|
|
894
|
+
height: number;
|
|
895
|
+
url: string;
|
|
896
|
+
}
|
|
897
|
+
/**
|
|
898
|
+
* A call-to-action button. `action` is "shop" (see `offerId`), "island" (see `linkId`: an
|
|
899
|
+
* island code like "0017-2877-1308" or a playlist id like "playlist_juno"), or Epic's raw
|
|
900
|
+
* action type when it is neither.
|
|
901
|
+
*/
|
|
902
|
+
export interface NewsButton {
|
|
903
|
+
text: string | null;
|
|
904
|
+
action: "shop" | "island" | string;
|
|
905
|
+
offerId: string | null;
|
|
906
|
+
linkId: string | null;
|
|
893
907
|
}
|
|
908
|
+
/** One entry of the lobby news carousel. */
|
|
894
909
|
export interface MOTD {
|
|
895
910
|
id: string;
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
911
|
+
position: number;
|
|
912
|
+
/** Full-screen title. */
|
|
913
|
+
title: string | null;
|
|
914
|
+
/** Full-screen body text. */
|
|
915
|
+
body: string | null;
|
|
916
|
+
/** Title shown on the carousel tile. */
|
|
917
|
+
tileTitle: string | null;
|
|
918
|
+
/** Largest full-screen image. */
|
|
919
|
+
image: string | null;
|
|
920
|
+
/** Largest tile image. */
|
|
921
|
+
tileImage: string | null;
|
|
922
|
+
images: NewsImage[];
|
|
923
|
+
tileImages: NewsImage[];
|
|
924
|
+
buttons: NewsButton[];
|
|
925
|
+
contentHash: string | null;
|
|
926
|
+
}
|
|
927
|
+
/** The lobby news carousel for one mode, as a generic account sees it. */
|
|
928
|
+
export interface NewsFeed {
|
|
929
|
+
mode: "br" | "stw" | "creative" | "festival";
|
|
930
|
+
/** Epic product tag queried, e.g. "Product.BR". */
|
|
931
|
+
tag: string;
|
|
932
|
+
language: string;
|
|
933
|
+
platform: NewsPlatform;
|
|
934
|
+
fetchedAt: string;
|
|
904
935
|
motds: MOTD[];
|
|
905
|
-
platform_motds?: MOTD[];
|
|
906
|
-
[key: string]: any;
|
|
907
936
|
}
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
937
|
+
/** An in-game emergency notice banner. */
|
|
938
|
+
export interface NewsNotice {
|
|
939
|
+
title: string | null;
|
|
940
|
+
body: string | null;
|
|
941
|
+
/** Playlists or experiences the notice is shown in. */
|
|
942
|
+
playlists: string[];
|
|
943
|
+
/** When present, the notice is limited to these platforms. */
|
|
944
|
+
platforms: string[] | null;
|
|
915
945
|
}
|
|
916
946
|
export interface AllNews {
|
|
917
|
-
br:
|
|
918
|
-
stw:
|
|
919
|
-
creative:
|
|
920
|
-
|
|
921
|
-
|
|
947
|
+
br: NewsFeed;
|
|
948
|
+
stw: NewsFeed;
|
|
949
|
+
creative: NewsFeed;
|
|
950
|
+
festival: NewsFeed;
|
|
951
|
+
notices: NewsNotice[];
|
|
952
|
+
}
|
|
953
|
+
/** @deprecated The API never wrapped news in { status, data }; this is now just `T`. */
|
|
954
|
+
export type NewsResponse<T> = T;
|
|
955
|
+
/** @deprecated Use NewsFeed. */
|
|
956
|
+
export type BRNews = NewsFeed;
|
|
957
|
+
/** @deprecated Use NewsFeed. */
|
|
958
|
+
export type STWNews = NewsFeed;
|
|
959
|
+
/** @deprecated Use NewsFeed. */
|
|
960
|
+
export type CreativeNews = NewsFeed;
|
|
922
961
|
export interface CosmeticsResponse<T> {
|
|
923
962
|
status: number;
|
|
924
963
|
data: T;
|