---
title: "Battle replay"
method: GET
path: "/{region}/battles/{id}/replay"
tags: ["Players"]
---

# Battle replay

`GET /{region}/battles/{id}/replay`

## Request

- Base URL: `https://unicum.gg/api`
- URL: `https://unicum.gg/api/{region}/battles/{id}/replay`
- Auth: none required

Where every vehicle was through a battle, for the 2D viewer, decoded from the replay file the players' own clients recorded. The decoded positions and nothing else: the file itself carries the whole packet stream the recording client received, the battle chat included, which is not published. 404 when no replay was kept for this battle, which is the ordinary case, since one exists only when a player who was there had recording on and shared it.

## Path parameters

- `region` 'eu' | 'na' | 'asia', required: Game server region.
- `id` string, required: The game's own battle id (`arenaUniqueID`), as digits. A string, not a number: it runs to 19 digits.

## Response `200`

Successful response

- BattleReplayResponse
  - `duration` number, required: How long the recording runs, in seconds.
  - `ticksPerSecond` number, required: Clock ticks a second in each point's first value. Hundredths, so a point's instant in seconds is its tick divided by this.
  - `startsAt` number, required: The clock tick the countdown ends and the battle begins. Zero when it cannot be worked out. Before it every vehicle sits on its spawn without moving, and since positions are only recorded when they change, a reader must treat that stretch as everybody being visible rather than nobody.
  - `chat` BattleReplayChatLine[], required: Every line typed in the battle, in order. Empty for a battle nobody spoke in, which is the commoner case: two of four real recordings carried none at all.
    - `at` number, required: The clock tick the line was sent, in the same clock the tracks use.
    - `from` string, required: Who typed it, with their clan tag when they had one, exactly as the game wrote it into the recording.
    - `vehicle` string, nullable, required: The vehicle they were in, or null when the line carries none.
    - `text` string, required: What they typed, as plain text. The game stores the line as markup; it is taken apart on the way out, so this is never HTML and must never be rendered as any.
    - `ally` boolean, required: Whether the sender was on the recording client's own side, read off the colour the game painted the line, which is the only side information the line carries. Always false for a quick command, which carries no colour.
    - `command` string, nullable, required: The quick command this line is, as the game names it internally (`RELOADINGGUN`, `SOS`, `ATTACK_BASE`), or null for a line somebody typed. The reload callouts, the map pings and the radial menu all travel as an action id on a different packet from the chat, and arrive resolved into the client's own words; repeats inside the game's own five-second cooldown are folded, since a held marker re-sends itself twice a second.
    - `where` object, nullable, required: Where on the map the command pinged, in the arena's own metres, the same frame the tracks use. Null for a command that pings nothing, which is most of them.
      - `x` number, required
      - `z` number, required
    - `target` number, nullable, required: The vehicle a command is about, to match against this battle's own vehicle ids, and null when it is about nobody. The game's messages name it: `Requesting fire at %(target)s!`.
    - `reloadTime` number, nullable, required: Seconds left on a reload, for the callouts whose text says so, rounded.
    - `label` string, nullable, required: A base or objective label the message names, when it names one.
    - `sender` number, nullable, required: Who sent a quick command, as an id to match against this battle's own vehicle ids, and null for a typed line. On a real recording it is the sender's vehicle id, the same one the tracks are keyed by; it is not that for every command, a waypoint's being plainly something else, so it is worth showing only where it names a vehicle that was in this battle.
  - `deaths` BattleReplayDeath[], required: Every vehicle destroyed, in order. The timing is the battle's own, so a tank nobody watched die is still here; the killer is the recording's, so it is null wherever the client could not see the shot.
    - `at` number, required: The clock tick the vehicle was destroyed, in the recording's clock.
    - `victim` number, required: The vehicle that died.
    - `by` number, nullable, required: The vehicle that finished it, or null: either nobody did (fire, drowning, a fall) or the recording client never saw the shot, since damage only reaches a client for a vehicle it can see.
    - `damage` number, nullable, required: What the killing blow took, in hit points, when the recording heard it.
    - `reason` number, nullable, required: How it died, as the game's own `deathReason`: 0 and 30 a shot, 1 fire, 2 ramming, 3 a crash, 5 drowning, 7 overturning, 12 self-destruction, and so on. The game names each one under `common/vehicleState/dead<reason>`, which is what turns a row of this timeline into the sentence the battle results would print.
  - `mapImage` string, nullable, required: The minimap this battle was played on, resolved for its own mode. Here as well as on the battle itself so a caller holding only this answer can draw the positions on something.
  - `mapBounds` object, nullable, required: The arena's extent in metres, which is what turns a position in these tracks into a place on `mapImage`. Same shape as on the battle itself.
    - `bottomLeft` object, required
      - `x` number, required
      - `z` number, required
    - `upperRight` object, required
      - `x` number, required
      - `z` number, required
  - `mapOverlay` unknown, required
  - `tracks` BattleReplayTrack[], required: One entry per vehicle this battle's recording client could see. A vehicle it never spotted has no track, which is honest fog of war rather than a gap.
    - `id` number, required: The battle-scoped vehicle id, the same one the battle's participants are keyed by.
    - `team` number, required: Which side the vehicle fought on, so the tracks can be coloured without loading the battle's own document. 0 when the results name no team for it.
    - `diedAt` number, nullable, required: The clock tick this vehicle was destroyed, or null if it survived or the recording cannot say. In the recording's clock, which runs about fifty seconds ahead of the battle's because it starts during the countdown.
    - `maxHealth` number, required: Hit points at full, zero when the battle's results do not name any.
    - `health` array[], required: Hit points over time, as [clock tick, hit points], one entry per change. Starts implicitly at maxHealth. A vehicle the recording client lost sight of keeps the last value it was told, so a track can end above the health the results record: the same fog of war the positions have.
      - number[]
    - `points` array[], required: The path, as [clock ticks since the battle started, x, z in the arena's own metres]. Every position the recording client was shown, which is about ten a second; only the moments the vehicle actually moved are kept, so between two points it stood still.
      - number[]
  - `loadouts` BattleReplayLoadout[], required: What the player who recorded this had fitted, one entry per life: one for an ordinary battle, one per tank taken out in a mode with respawns. Only ever theirs, and empty for a recording whose client version this cannot be read from.
    - `vehicle` number, required: The vehicle entity this life belongs to. Lives in a respawn mode share a battle but not a tank, so this is what tells them apart.
    - `at` number, required: The clock tick the loadout was sent, in the same clock the tracks use, which places the life within the battle.
    - `optDevices` string[], required: The optional devices fitted, by slot. A free slot is a null in place, because a device's category and grade depend on which slot it sits in. A name this site does not know is also null.
    - `boosters` string[], required: Directives fitted, by slot, a free one being null.
    - `consumables` string[], required: Consumables carried, by slot, a free one being null.
    - `shells` BattleReplayLoadoutShell[], required: The rounds loaded, in the client's own order.
      - `name` string, required: The client's own name for the round, scoped to its nation, the same name the garage loadouts are stored under.
      - `type` string, required: ARMOR_PIERCING, ARMOR_PIERCING_CR, HOLLOW_CHARGE or HIGH_EXPLOSIVE, which is what picks the round's icon.
      - `premium` boolean, required: Whether the round costs gold.
      - `count` number, required: How many of them were loaded.
    - `crew` BattleReplayLoadoutCrew[], required: The crew, one entry per seat, each with its own skills. Kept per seat rather than flattened: for the five skills every seat can learn, how many of the crew trained it is the whole effect, and a deduplicated list cannot say.
      - `role` string, required: commander, gunner, driver, radioman or loader.
      - `skills` string[], required: Skills trained, in the order they were learned.

---

[API](https://skmtc.dev/unicum/apis/unicum-gg-api.md) · [All operations](https://skmtc.dev/unicum/apis/unicum-gg-api/llms.txt) · [OpenAPI document](https://skmtc.dev/unicum/apis/unicum-gg-api/revisions/7a7d79a26001?raw)
