Replay Parser
Parse Fortnite .replay files to extract match statistics, player lobbies, storm zones, map objects, ground loot, and match timelines. Supports both client replays (uploaded by you) and tournament server replays (fetched from Epic by match ID).
Overview
The Replay Parser reads binary .replay files and returns structured JSON. There are two ways to use it:
- Upload: You supply a
.replayfile asmultipart/form-data. Useful when you have files locally or from your own capture pipeline. - Fetch-and-Parse:You supply a tournament match ID. We call Epic's datastorage API, download the replay, parse it, and return the result. No file handling on your end.
Upload base path
https://prod.api-fortnite.com/api/v1/parsingFetch-and-parse base path
https://prod.api-fortnite.com/api/v1/replaysAll requests require an x-api-key header with a valid API key.
Credit System
Parsing operations consume daily credits from your plan quota. Credits reset at midnight UTC.
| Plan | Credits / Day |
|---|---|
| Free | 10 |
| Starter | 100 |
| Pro | 500 |
| Custom | Unlimited |
Upload endpoint costs
| Endpoint | Cost | Notes |
|---|---|---|
/parsing/stats | 1 | Free plan access — fastest |
/parsing | 5 | Single file, full parse |
/parsing/lobby | 5 | Single file, full parse |
/parsing/map | 5 | Single file, full parse |
/parsing/zones | 5 | Single file, full parse |
/parsing/timeline | 5 | Single file, full parse |
/parsing/loot | 5 | Single file, full parse |
/parsing/multiple/stats | 5 | Batch stats |
/parsing/multiple | 10 | Batch full parse |
/parsing/multiple/map | 10 | Batch map parse |
/parsing/multiple/loot | 10 | Batch loot parse |
/parsing/broadcast | 20 | All data combined |
Fetch-and-parse endpoint costs
| Endpoint | Cost | Notes |
|---|---|---|
/replays/{matchId} | 2 | Raw .replay download |
/replays/{matchId}/metadata | 0 | Chunk manifest, no parsing |
/replays/{matchId}/parse/stats | 1 | Stats only |
/replays/{matchId}/parse | 5 | Full parse |
/replays/{matchId}/parse/lobby | 5 | Full player lobby |
/replays/{matchId}/parse/map | 5 | Map context |
/replays/{matchId}/parse/zones | 5 | Storm zones |
/replays/{matchId}/parse/timeline | 5 | Match timeline |
/replays/{matchId}/parse/loot | 5 | Ground loot |
/replays/{matchId}/parse/broadcast | 20 | Everything — recommended for tournaments |
/parse/broadcast: 6 × 20 = 120 credits consumed out of 500.Server vs Client Replays
This is the most important distinction to understand before building with the parser.
Client replays
Recorded locally by a player's game client. Saved to %LOCALAPPDATA%\FortniteGame\Saved\Demos\on Windows. Contains the recording player's own summary statistics written at match end, plus cosmetic data.
Server replays
Recorded by the game server. Epic stores them centrally for tournament and competitive events. Contains replicated state for all players— not just one player's perspective. No per-client stats like accuracy or materials, but full per-player damage/kills/reboots. The isServerReplay field is true and root-level stats is null.
| Field | Client | Server |
|---|---|---|
| stats.accuracy | ✓ | ✗ |
| stats.matsFarm / matsUsed | ✓ | ✗ |
| stats.damageStructures | ✓ | ✗ |
| stats.assist (revives) | ✓ | ✗ |
| stats.eliminations / damage / placement | ✓ | ✗ (use per-player fields) |
| Per-player kills + placement | Partial | ✓ all players |
| Per-player damageDealt / damageTaken | ✗ | ✓ all players |
| Per-player headshots / teamKills | ✗ | ✓ all players |
| Per-player rebootCount | ✗ | ✓ all players |
| Cosmetics (skin, back bling, etc.) | ✓ | ✗ |
| Storm zones / bus path | ✓ | ✓ |
| Supply drops / llamas / reboot vans | ✓ | ✓ |
| Timeline kill/knock events | ✓ | ✓ |
| Timeline damage cue events | ✓ | ✗ |
How to Obtain Replays
Client replays
Fortnite saves replays automatically. Users can also download them from the in-game Replays menu. For replays stored server-side by Epic, use the Replay Service API (requires OAuth token).
Tournament / server replays
Use the Fetch-and-Parse endpoints— just provide the match ID and we handle the rest. To find match IDs, call Epic's tournament sessions endpoint:
GET https://fngw-mcp-gc-livefn.ol.epicgames.com/fortnite/api/game/v2/events/v2/sessions/{eventId}/{windowId}
?page=0&rank=0&teamAccountIds={accountId}
Each session entry contains a "replayId" field.See EPIC_ENDPOINTS.md for the full list of tournament endpoints and auth requirements. Once you have a match ID, pass it directly to /api/v1/replays/{matchId}/parse/broadcast.
Upload Endpoints
All upload endpoints accept multipart/form-data with the file under the key file.
POST /parsing/stats
Fastest parse — extracts only the summary stats block. Skips all replicated state (players, map, zones). Use when you only need the recording player's final numbers.
stats is null. Use /lobby instead.{
"name": "FNGameUSW_00-...",
"replayId": "...",
"version": "++Fortnite+Release-34.00",
"isServerReplay": false,
"stats": {
"eliminations": 3, "damage": 412, "accuracy": 0.28,
"placement": 4, "assist": 1, "damageTaken": 200,
"damageStructures": 50, "matsFarm": 300, "matsUsed": 150,
"totalPlayers": 100
}
}POST /parsing
Full parse of a single replay. Returns ReplaySnapshot — owner stats for client replays, or per-player stats array for server replays.
POST /parsing/lobby
Full lobby snapshot — all players with stats, cosmetics, death info, and team data. For server replays: damageDealt, damageTaken, headshots, rebootCount populated. Cosmetics null.
POST /parsing/map
Bus flight path, drop window, storm circle positions, supply drops, llamas, and reboot vans.
POST /parsing/zones
All storm phases with timing, circle positions, and damage per tick. Includes one-phase look-ahead.
POST /parsing/timeline
Chronological event feed for the recording player: kills, knocks, own death, damage dealt/taken, heals, item pickups. Times relative to bus drop (referenceTime).
POST /parsing/loot
Ground loot snapshot — all items that existed on the map near the player, with pickup status and timing.
POST /parsing/broadcast
All-in-one payload. Combines every data type in a single request — equivalent to calling all other endpoints simultaneously. Use for tournament broadcasting pipelines or full match archival.
Batch endpoints
Batch full parse — 10 credits
Batch stats only — 5 credits
Batch map parse — 10 credits
Batch ground loot — 10 credits
All batch endpoints accept multiple files in one multipart/form-data request. Files are parsed in parallel. Returns an array in the same order as the files sent.
Fetch-and-Parse Endpoints
Pass a tournament match ID — we call Epic's datastorage API, download the replay chunks, assemble the binary, and parse it. Same response shapes as the upload endpoints. Match IDs come from Epic's tournament events API.
GET /replays/{matchId}
Downloads the raw .replay binary. Returns application/octet-stream with filename {matchId}.replay. Use for archival — store it yourself for later re-parsing or offline analysis.
GET /replays/{matchId}/metadata
Returns Epic's chunk manifest without downloading or parsing. Shows Events, DataChunks, Checkpoints arrays with timing info. Useful for inspecting replay structure.
GET /replays/{matchId}/parse/broadcast
The primary endpoint for tournament pipelines. Downloads the replay from Epic and returns the full broadcast payload — all players, zones, map, loot, and timeline in one call.
curl -H "x-api-key: YOUR_KEY" \
"https://prod.api-fortnite.com/api/v1/replays/FNCOMP-USW1-FNCS-GAME1/parse/broadcast"All parse sub-endpoints
| Endpoint | Cost | Response |
|---|---|---|
/parse/stats | 1 | Stats only |
/parse | 5 | ReplaySnapshot |
/parse/lobby | 5 | ParsedLobby |
/parse/map | 5 | ParsedMap |
/parse/zones | 5 | ParsedZones |
/parse/timeline | 5 | ParsedTimeline |
/parse/loot | 5 | ParsedLoot |
/parse/broadcast | 20 | ParsedBroadcast (everything) |
Data Availability Matrix
| Field | /stats | /parsing | /lobby | /map | /zones | /timeline | /loot | /broadcast |
|---|---|---|---|---|---|---|---|---|
| name / replayId / version | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| isServerReplay | ✓ | ✓ | — | — | — | ✓ | — | ✓ |
| stats (owner summary) | ✓ | ✓ | — | — | — | — | — | ✓ |
| players[] (all players) | — | S | ✓ | — | — | — | — | ✓ |
| players[].cosmetics | — | — | C | — | — | — | — | C |
| players[].damageDealt / rebootCount | — | S | S | — | — | — | — | S |
| Bus path | — | — | — | ✓ | — | — | — | ✓ |
| Storm zones | — | — | — | ✓ | ✓ | — | — | ✓ |
| Supply drops / llamas | — | — | — | ✓ | — | — | — | ✓ |
| Ground loot | — | — | — | — | — | — | ✓ | ✓ |
| Timeline events | — | — | — | — | — | ✓ | — | ✓ |
| Damage cue events | — | — | — | — | — | C | — | C |
✓ = always present · S = server replays only · C = client replays only · — = not included
Response Shape Reference
PlayerStats (owner summary — client replays only)
| Field | Type | Description |
|---|---|---|
eliminations | int | Total kills |
damage | int | Total damage dealt to players |
accuracy | float | Shot accuracy (0.0–1.0) |
placement | int | Final placement (1 = Victory Royale) |
assist | int | Revives given to teammates |
damageTaken | int | Total damage received |
damageStructures | int | Damage dealt to structures |
matsFarm | int | Materials farmed |
matsUsed | int | Materials used for building |
totalPlayers | int | Total players in the match |
LobbyPlayer
| Field | Type | Server | Client | Description |
|---|---|---|---|---|
playerId | string? | ✓ | ✓ | Epic account ID |
displayName | string? | ✓ | ✓ | Display name |
platform | string? | — | ✓ | WIN / PSN / XBL / Switch / Mobile |
isBot | bool | ✓ | ✓ | True for NPC bots |
isReplayOwner | bool | — | ✓ | Recording player |
teamIndex | int? | ✓ | ✓ | Team number (0-based) |
level | int? | — | ✓ | Account level |
placement | int? | ✓ | ✓ | Final placement |
kills | uint? | ✓ | ✓ | Eliminations |
teamKills | uint? | ✓ | — | Team total kills |
damageDealt | float? | ✓ | — | Total damage dealt |
damageTaken | float? | ✓ | — | Total damage taken |
headshots | int? | ✓ | — | Headshot count |
rebootCount | uint? | ✓ | — | Times rebooted teammates |
disconnected | bool? | ✓ | ✓ | Disconnected mid-match |
deathTime | double? | ✓ | ✓ | Seconds from match start |
deathX / deathY | double? | ✓ | ✓ | World coordinates of death |
deathTags | string[]? | ✓ | ✓ | Gameplay tags describing death cause |
cosmetics | object? | — | ✓ | Skin, back bling, glider, pickaxe, emotes |
ZonePhase
| Field | Type | Description |
|---|---|---|
phase | int | Phase number (1–9 typically) |
currentX/Y/Radius | double? | Current safe zone (null for phase 1) |
nextX/Y/Radius | double | Circle this phase shrinks into |
nextNextX/Y/Radius | double? | Following circle (look-ahead) |
startShrinkTime | float | Seconds from replay start when shrinking begins |
finishShrinkTime | float | Seconds from replay start when shrink completes |
damage | float? | Damage per tick outside the zone |
BusPath
| Field | Type | Description |
|---|---|---|
startX / startY | double | Bus entry point |
endX / endY | double | Bus exit point |
dropWindowStartX/Y | double | Start of the player drop window |
dropWindowEndX/Y | double | End of the player drop window |
skin | string? | Bus skin name if a special event is active |
TimelineEvent
Event type values: kill · knock · death · damageDealt · damageTaken · healed · pickup
| Field | Present on | Description |
|---|---|---|
type | all | Event type string |
t | all | Seconds from replay start |
x / y | kill, knock, death, damage, pickup | World position |
victim | kill, knock | Victim display name |
killer | kill, knock, death | Killer display name |
weaponTags | kill, knock, death | Gameplay tags of weapon used |
distance | kill, knock | Distance to victim (Unreal units) |
amount | damageDealt, damageTaken | Damage amount |
isCritical | damageDealt | Headshot |
isShield | damageDealt | Hit shield |
isFatal | damageDealt, damageTaken | Killing blow |
healthDelta / shieldDelta | damageTaken, healed | HP/shield change |
health / shield | damageTaken, healed | Values after event |
itemId | pickup | Item definition ID |
Map Objects
MapSupplyDrop
| Field | Type | Description |
|---|---|---|
x / y | double | World coordinates (landing position) |
looted | bool | Whether the crate was opened |
lootedTime | double? | Seconds from match start when looted |
balloonPopped | bool | Whether the balloon was shot |
balloonPoppedTime | double? | Seconds when balloon was popped |
MapPickup (ground loot)
| Field | Type | Description |
|---|---|---|
itemId | string? | Item definition ID |
x / y / z | double | World coordinates |
pickedUp | bool | Whether this item was picked up |
pickedUpTime | double? | Seconds from match start when picked up |
fromContainer | bool | True if from chest, supply drop, or llama |
count | int | Stack size |
Coordinate System
All x / y values use Unreal Engine world coordinates (Unreal Units). The map is centered at (0, 0). Coordinates range roughly from -131072 to 131072on both axes depending on the season's map bounds.
The worldBounds object in /parsing/map gives the exact bounds for the specific match. To normalize to 0–1 for overlay rendering:
normalizedX = (x - worldBounds.minX) / (worldBounds.maxX - worldBounds.minX)
normalizedY = (y - worldBounds.minY) / (worldBounds.maxY - worldBounds.minY)