How to Build a Fortnite Discord Bot with the API
Step-by-step guide to building a Fortnite Discord bot that posts daily item shop updates and looks up player stats using the real Fortnite API endpoints.
Why Build a Fortnite Discord Bot?
Discord bots are one of the most popular use cases for the Fortnite API. They let your gaming community check player stats, see the daily item shop, and get notified about updates — all without leaving Discord.
Prerequisites
Setup
npm install discord.js node-cron dotenvCreate a .env file:
DISCORD_TOKEN=your_discord_bot_token
FORTNITE_API_KEY=your_api_key
SHOP_CHANNEL_ID=your_channel_idKey Concept: Stats Use Account IDs
The stats endpoint requires an Epic account ID, not a display name. You always resolve the display name first:
GET /api/v1/account/displayName/{displayName}
→ returns { id: "...", displayName: "..." }
GET /api/v2/stats/{accountId}
→ returns player statsSlash Command: /stats
const { SlashCommandBuilder } = require("discord.js");
const BASE_URL = "https://prod.api-fortnite.com";
const HEADERS = { "x-api-key": process.env.FORTNITE_API_KEY };
module.exports = {
data: new SlashCommandBuilder()
.setName("stats")
.setDescription("Look up Fortnite player stats")
.addStringOption((opt) =>
opt.setName("username").setDescription("Epic Games display name").setRequired(true)
),
async execute(interaction) {
const displayName = interaction.options.getString("username");
await interaction.deferReply();
try {
// Step 1: resolve display name → account ID
const accountRes = await fetch(
`${BASE_URL}/api/v1/account/displayName/${encodeURIComponent(displayName)}`,
{ headers: HEADERS }
);
if (!accountRes.ok) {
return interaction.editReply(`Player **${displayName}** not found.`);
}
const account = await accountRes.json();
// Step 2: fetch stats
const statsRes = await fetch(
`${BASE_URL}/api/v2/stats/${account.id}`,
{ headers: HEADERS }
);
const stats = await statsRes.json();
await interaction.editReply(
`**${displayName}** — stats loaded!`
// Adapt to the actual fields in the stats response
);
} catch (err) {
await interaction.editReply("Could not retrieve stats. The player may have private stats.");
}
},
};Daily Item Shop Notification
Post the shop automatically every day at reset (00:05 UTC):
const cron = require("node-cron");
cron.schedule("5 0 * * *", async () => {
const res = await fetch("https://prod.api-fortnite.com/api/v1/shop", {
headers: { "x-api-key": process.env.FORTNITE_API_KEY },
});
const shop = await res.json();
const channel = await client.channels.fetch(process.env.SHOP_CHANNEL_ID);
await channel.send("**The item shop has reset!** Check today's rotation.");
});Other Useful Endpoints for Bots
| Command idea | Endpoint |
|---|---|
| /news — latest BR news | GET /api/v1/news/br |
| /map — current map info | GET /api/v1/map |
| /season — current season | GET /api/v1/season |
| /cosmetic — search a skin | GET /api/v2/cosmetics/search?q=Raven |
| /weapons — weapon stats | GET /api/v2/weapons |