Patch 6.2.0 is live — Clean up of duplicated endpoints & improvement of Typescript SDK.
api-fortnite
← Back to Blog

Fortnite API with Python - Complete Tutorial

Learn how to use the Fortnite API with Python. Covers account resolution, stats, shop, cosmetics, and building a simple CLI tool.

pythontutorialplayer-stats

Python + Fortnite API


Python is a natural fit for the Fortnite API — whether you're building a Discord bot with discord.py, a data pipeline, or a quick CLI tool.


Installation


pip install requests httpx python-dotenv

Create a .env file:


FORTNITE_API_KEY=your_key_here

Base Setup


import os
import requests
from dotenv import load_dotenv

load_dotenv()

BASE_URL = "https://prod.api-fortnite.com"
HEADERS = {"x-api-key": os.getenv("FORTNITE_API_KEY")}

Resolving a Display Name to Account ID


Stats use Epic account IDs, not display names. Always resolve first:


def get_account_by_display_name(display_name: str) -> dict:
    """Resolve a display name to an Epic account."""
    url = f"{BASE_URL}/api/v1/account/displayName/{requests.utils.quote(display_name)}"
    response = requests.get(url, headers=HEADERS)
    response.raise_for_status()
    return response.json()  # contains 'id', 'displayName'

def get_player_stats(account_id: str, stat_keys: str = None) -> dict:
    """Fetch stats for an Epic account ID."""
    params = {}
    if stat_keys:
        params["stats"] = stat_keys
    url = f"{BASE_URL}/api/v2/stats/{account_id}"
    response = requests.get(url, headers=HEADERS, params=params)
    response.raise_for_status()
    return response.json()

Item Shop


def get_item_shop(lang: str = "en", rarity: str = None) -> dict:
    params = {"lang": lang}
    if rarity:
        params["rarity"] = rarity
    response = requests.get(f"{BASE_URL}/api/v1/shop", headers=HEADERS, params=params)
    response.raise_for_status()
    return response.json()

Cosmetics Search


def search_cosmetics(query: str, cosmetic_type: str = None, lang: str = "en") -> dict:
    params = {"q": query, "lang": lang}
    if cosmetic_type:
        params["type"] = cosmetic_type
    response = requests.get(
        f"{BASE_URL}/api/v2/cosmetics/search", headers=HEADERS, params=params
    )
    response.raise_for_status()
    return response.json()

Weapon Stats


def get_weapons(category: str = None, gamemode: str = None, patch: str = None) -> dict:
    params = {}
    if category:
        params["category"] = category
    if gamemode:
        params["gamemode"] = gamemode
    if patch:
        params["patch"] = patch
    response = requests.get(f"{BASE_URL}/api/v2/weapons", headers=HEADERS, params=params)
    response.raise_for_status()
    return response.json()

CLI Stats Tool


import sys

def main():
    if len(sys.argv) < 2:
        print("Usage: python stats.py <display_name>")
        sys.exit(1)

    display_name = sys.argv[1]

    try:
        account = get_account_by_display_name(display_name)
        print(f"Account ID: {account['id']}")

        stats = get_player_stats(account["id"])
        print(f"Stats: {stats}")
    except requests.HTTPError as e:
        if e.response.status_code == 404:
            print(f"Player '{display_name}' not found.")
        else:
            print(f"Error: {e.response.status_code}")

if __name__ == "__main__":
    main()

Run it:


python stats.py Ninja

Async Version with httpx


import httpx
import asyncio

async def get_stats_async(display_name: str) -> dict:
    async with httpx.AsyncClient(headers=HEADERS) as client:
        # Resolve account ID
        account_res = await client.get(
            f"{BASE_URL}/api/v1/account/displayName/{display_name}"
        )
        account_res.raise_for_status()
        account_id = account_res.json()["id"]

        # Fetch stats
        stats_res = await client.get(f"{BASE_URL}/api/v2/stats/{account_id}")
        stats_res.raise_for_status()
        return stats_res.json()

result = asyncio.run(get_stats_async("Ninja"))

Related Guides


  • Getting Started with the Fortnite API
  • How to Track Fortnite Player Stats in Real-Time