Oddin.gg Bragi - Game-specific schemas: Dota 2
This article is section 6.2 of Oddin.gg Bragi - Data Feed documentation. Sections 1 to 5 there cover general information, the match timeline, processing the data feed, match events and team profiles.
Other game schemas: Counter-Strike 2 · League of Legends · Valorant · eBasketball · eFootball · eCricket
6.2. Dota 2
The Dota 2 schema models a Dota 2 match as a series of maps (games). Each map has two teams (Radiant and Dire), five players per team, towers and barracks for each lane, a Roshan, and a draft phase of picks and bans before the map begins. State is kept for the match overall, for the current map, for each team, and for each player.
6.2.1. Top-level Dota 2 messages
Dota2MatchMessage
A concrete implementation of the (Game)MatchMessage pattern (see section 3.5.2.2).
| Field | Type | Description |
match_urn |
string |
Match identifier. |
sequence |
uint64 |
Sequence number; must be exactly cached sequence + 1. |
timestamp |
google.protobuf.Timestamp |
Time the message was produced. |
data_status |
DataStatus |
Quality flag for the underlying data. |
payload |
Dota2MatchMessage.Payload |
Oneof: snapshot (Dota2MatchSnapshot) or update (Dota2MatchUpdate). |
Dota2MatchSnapshot
A concrete implementation of the (Game)MatchSnapshot pattern. Cache the snapshot in memory and apply later update messages to it.
| Field | Type | Description |
match_urn |
string |
Match identifier. |
sequence |
uint64 |
Initial sequence number. |
timestamp |
google.protobuf.Timestamp |
Snapshot timestamp. |
data_status |
DataStatus |
Quality flag for the underlying data. |
announcements |
repeated Announcement |
Operational announcements for the match. |
match_state |
Dota2MatchState |
Full current state of the match. |
tournament |
Tournament |
Tournament the match belongs to. |
Dota2MatchUpdate
Carries either a full replacement of the match state or a list of partial updates.
| Field | Type | Description |
payload |
Dota2MatchUpdate.Payload |
Oneof: match_state (Dota2MatchState) or partial_updates (Dota2MatchStatePartialUpdates). |
Dota2MatchStatePartialUpdates
| Field | Type | Description |
updates |
repeated Dota2MatchStatePartialUpdate |
Non-empty list of partial updates to apply to the cached match state. |
6.2.2. Match-level state
Dota2MatchStatePartialUpdate
A oneof wrapper that targets a specific part of the cached match state.
| Field | Type | Description |
score |
Dota2MatchScoreState |
Replaces the score property in Dota2MatchState. |
current_map_state |
Dota2CurrentMapState |
Replaces the current_map_state property in Dota2MatchState. Sent periodically as a safety idempotent update. |
current_map_state_partial_update |
Dota2CurrentMapStatePartialUpdate |
Applies a partial update inside the current map state. |
picks_and_bans_selections |
PicksAndBansSelections |
Deprecated. Replaces the picks_and_bans_selections property. Use picks_and_bans_selections_per_team instead. |
picks_and_bans_selections_per_team |
PicksAndBansSelectionsPerTeam |
Replaces the picks_and_bans_selections_per_team property in Dota2MatchState. |
Dota2MatchState
| Field | Type | Description |
match_urn |
string |
Match identifier. |
match_type |
BestOfType |
Match format (best of N). |
home_team |
Team |
Home team. |
away_team |
Team |
Away team. |
score |
Dota2MatchScoreState |
Map score for the match. |
match_status |
MatchStatusType |
Lifecycle status of the match. |
current_map |
Dota2CurrentMapState |
State of the map currently being played. |
previous_maps |
repeated Dota2PreviousMapState |
Summary of all completed maps in the match. |
picks_and_bans_selections |
PicksAndBansSelections |
Deprecated. Use picks_and_bans_selections_per_team. |
picks_and_bans_selections_per_team |
PicksAndBansSelectionsPerTeam |
Draft state for the current map. |
Dota2MatchScoreState
| Field | Type | Description |
home_score |
uint32 |
Maps won by the home team. |
away_score |
uint32 |
Maps won by the away team. |
6.2.3. Picks and bans
Two representations are available for the draft phase. PicksAndBansSelectionsPerTeam is the recommended one: it splits picks and bans by team and guarantees correct ordering regardless of connection time or short data-collection gaps. PicksAndBansSelections is the older sequential representation; it is kept for backwards compatibility, but its sequence may become inconsistent if the upstream data has gaps.
PicksAndBansSelectionsPerTeam
| Field | Type | Description |
state |
PicksAndBansSelectionsPerTeam.State |
Overall draft state (in progress, ended). |
active_team |
PicksAndBansSelectionsPerTeam.TeamType |
Team currently selecting (Radiant or Dire). |
selection_type |
PicksAndBansSelectionsPerTeam.SelectionType |
Whether the active team is picking or banning. |
active_team_time_remaining |
int32 |
Seconds left for the current selection. |
radiant_bonus_time |
int32 |
Reserved bonus seconds for the Radiant team. |
dire_bonus_time |
int32 |
Reserved bonus seconds for the Dire team. |
radiant_selections |
PicksAndBansSelectionsPerTeam.RadiantSelections |
Picks and bans made by the Radiant team so far. |
dire_selections |
PicksAndBansSelectionsPerTeam.DireSelections |
Picks and bans made by the Dire team so far. |
PicksAndBansSelectionsPerTeam.HeroSelection
| Field | Type | Description |
hero_steam_id |
uint32 |
Numeric Steam hero ID. |
hero_key |
string |
Hero key (short, machine-friendly name). |
PicksAndBansSelectionsPerTeam.RadiantSelections / DireSelections
| Field | Type | Description |
bans |
repeated HeroSelection |
Heroes banned by this team. |
picks |
repeated HeroSelection |
Heroes picked by this team. |
PicksAndBansSelections (deprecated)
| Field | Type | Description |
current_hero_selection |
PicksAndBansSelections.CurrentHeroSelection |
Information about the selection currently in progress. |
picks_and_bans |
repeated PicksAndBansSelections.PickOrBan |
Sequential list of all picks and bans made so far. |
state |
PicksAndBansSelections.State |
Overall draft state. |
PicksAndBansSelections.CurrentHeroSelection
| Field | Type | Description |
active_team |
PicksAndBansSelections.TeamType |
Team currently selecting. |
pick |
bool |
true if the team is picking, false if banning. |
active_team_time_remaining |
int32 |
Seconds left for the current selection. |
radiant_bonus_time |
int32 |
Reserved bonus seconds for the Radiant team. |
dire_bonus_time |
int32 |
Reserved bonus seconds for the Dire team. |
PicksAndBansSelections.PickOrBan
| Field | Type | Description |
team |
PicksAndBansSelections.TeamType |
Team that made the action. |
pick |
bool |
true for a pick, false for a ban. |
hero_steam_id |
uint32 |
Numeric Steam hero ID. |
hero_key |
string |
Hero key. |
6.2.4. Current map state
Dota2CurrentMapStatePartialUpdate
Oneof that targets a specific area inside the current map.
| Field | Type | Description |
game_time |
Dota2CurrentMapTimeState |
Replaces the game_time property. |
team_current_map_state |
Dota2TeamCurrentMapState |
Replaces a team's entry inside the teams map (keyed by team URN). |
team_current_map_partial_update |
Dota2TeamCurrentMapStatePartialUpdate |
Applies a partial update inside a team's current-map state. |
towers |
Dota2Towers |
Replaces the towers property. |
barracks |
Dota2Barracks |
Replaces the barracks property. |
roshan |
Roshan |
Replaces the roshan property. |
Dota2CurrentMapState
| Field | Type | Description |
map_order |
uint32 |
Position of this map in the match (1, 2, 3...). |
map_paused |
bool |
true if the map is paused. |
game_time |
Dota2CurrentMapTimeState |
In-game clock state. |
teams |
map<string, Dota2TeamCurrentMapState> |
Per-team state, keyed by team URN. |
towers |
Dota2Towers |
State of all towers on the map. |
barracks |
Dota2Barracks |
State of all barracks on the map. |
roshan |
Roshan |
State of Roshan. |
day_time |
bool |
true if it is day in the game world, false if night. |
Dota2CurrentMapTimeState
| Field | Type | Description |
game_time |
google.protobuf.Duration |
Time elapsed in the current game. |
Dota2PreviousMapState
| Field | Type | Description |
map_order |
uint32 |
Position of this map in the match. |
teams |
map<string, Dota2TeamPreviousMapState> |
End-of-map team summary, keyed by team URN. |
6.2.5. Per-team current-map state
Dota2TeamCurrentMapStatePartialUpdate
Targets a specific team (by team URN) inside the current map.
| Field | Type | Description |
team_urn |
string |
Team identifier the update applies to. |
payload |
Dota2TeamCurrentMapStatePartialUpdate.Payload |
Oneof: statistics, player_current_map_state, or player_current_map_partial_update. |
Dota2TeamCurrentMapState
| Field | Type | Description |
team_urn |
string |
Team identifier. |
faction |
Dota2Faction |
Radiant or Dire. |
statistics |
Dota2TeamCurrentMapStatisticsState |
Team-level numbers (kills, towers, etc.). |
won |
optional bool |
Whether this team won the map. Unset while the map is still in progress. |
players |
map<string, Dota2PlayerCurrentMapState> |
Per-player state, keyed by player URN. |
Dota2TeamCurrentMapStatisticsState
| Field | Type | Description |
team_urn |
string |
Team identifier. |
barracks |
uint32 |
Number of barracks the team still holds. |
kills |
uint32 |
Total kills made by the team this map. |
net_worth |
uint32 |
Sum of net worth across all players. |
roshans |
uint32 |
Number of Roshans killed by the team. Treat as unknown when has_roshans is false. |
towers |
uint32 |
Number of towers the team still holds. |
has_roshans |
bool |
true if the roshans field carries a real value; false means it is unknown. |
Dota2TeamPreviousMapState
| Field | Type | Description |
team_urn |
string |
Team identifier. |
faction |
Dota2Faction |
Faction played by this team on the map. |
barracks |
uint32 |
Number of barracks held at the end of the map. |
kills |
uint32 |
Total kills. |
net_worth |
uint32 |
Final net worth. |
roshans |
uint32 |
Roshans killed. Treat as unknown when has_roshans is false. |
towers |
uint32 |
Towers held at the end of the map. |
won |
optional bool |
Whether the team won the map. |
players |
map<string, Dota2PlayerPreviousMapState> |
Per-player end-of-map summary, keyed by player URN. |
has_roshans |
bool |
true if the roshans field is reliable. |
6.2.6. Per-player current-map state
Dota2PlayerCurrentMapStatePartialUpdate
Targets a specific player (by player URN) inside the current map.
| Field | Type | Description |
player_urn |
string |
Player identifier the update applies to. |
payload |
Dota2PlayerCurrentMapStatePartialUpdate.Payload |
Oneof: player_info, timers, statistics, map_statistics, position, items, or abilities. |
Dota2PlayerCurrentMapState
| Field | Type | Description |
player_urn |
string |
Player identifier. |
player_info |
Dota2PlayerInfoState |
Identity and hero pick. |
timers |
Dota2PlayerCurrentMapTimersState |
Respawn and buyback timers. |
statistics |
Dota2PlayerStatisticsState |
Kills, deaths, assists across the map. |
map_statistics |
Dota2PlayerCurrentMapStatisticsState |
Live in-game numbers (health, gold, mana, etc.). |
position |
Dota2Position |
Position of the player on the map. |
items |
Dota2Items |
Items the player is carrying. |
abilities |
Dota2Abilities |
Abilities and their status. |
Dota2PlayerInfoState
| Field | Type | Description |
player_urn |
string |
Player identifier. |
slot_id |
uint32 |
Slot number inside the match (1-10). |
ext_name |
string |
External display name from the data source. |
ext_id |
string |
External identifier from the data source. |
hero_id |
optional uint32 |
Steam hero ID. Unset while no hero is locked in. |
Dota2PlayerCurrentMapTimersState
| Field | Type | Description |
player_urn |
string |
Player identifier. |
respawn_timer |
optional google.protobuf.Duration |
Time left until respawn. Unset while alive. |
buyback_cooldown |
google.protobuf.Duration |
Cooldown left before buyback can be used. |
Dota2PlayerStatisticsState
| Field | Type | Description |
player_urn |
string |
Player identifier. |
kills |
uint32 |
Kills made by the player. |
deaths |
uint32 |
Times the player has died. |
assists |
uint32 |
Kill assists by the player. |
Dota2PlayerCurrentMapStatisticsState
| Field | Type | Description |
player_urn |
string |
Player identifier. |
alive |
bool |
true if the player is currently alive. |
health |
uint32 |
Current HP. |
max_health |
uint32 |
Maximum HP. |
current_gold |
uint32 |
Liquid gold the player can spend. |
net_worth |
uint32 |
Current gold plus buy-back value of items in inventory and on the courier. |
buyback_cost |
uint32 |
Gold needed to use buyback. |
has_buyback |
bool |
true if the player can buy back. |
has_aegis |
bool |
true if the player is holding the Aegis of the Immortal. |
mana |
uint32 |
Current mana. |
max_mana |
uint32 |
Maximum mana. |
gold_reliable |
uint32 |
Amount of reliable gold. |
gold_unreliable |
uint32 |
Amount of unreliable gold. |
denies |
uint32 |
Friendly creeps denied (last-hit by own side to prevent enemy gold). |
last_hits |
uint32 |
Enemy creeps last-hit by the player. |
level |
uint32 |
Hero level. |
Dota2PlayerPreviousMapState
| Field | Type | Description |
player_urn |
string |
Player identifier. |
player_info |
Dota2PlayerInfoState |
Identity and hero played. |
statistics |
Dota2PlayerStatisticsState |
Final kill/death/assist line for the map. |
6.2.7. Map objects
Dota2Towers
| Field | Type | Description |
towers |
repeated Dota2Tower |
All towers on the map. |
Dota2Tower
| Field | Type | Description |
lane |
Dota2Lane |
Lane the tower is on. |
faction |
Dota2Faction |
Faction that owns the tower. |
tier |
Dota2TowerTier |
Tower tier (1-4). |
alive |
bool |
true if the tower is still standing. |
Dota2Barracks
| Field | Type | Description |
barracks |
repeated Dota2Barrack |
All barracks on the map. |
Dota2Barrack
| Field | Type | Description |
lane |
Dota2Lane |
Lane the barrack is on. |
faction |
Dota2Faction |
Faction that owns the barrack. |
type |
Dota2BarrackType |
Ranged or melee barrack. |
alive |
bool |
true if the barrack is still standing. |
Roshan
| Field | Type | Description |
alive |
bool |
true if Roshan is alive. |
respawnTime |
uint32 |
Seconds until Roshan respawns. |
position |
Dota2Position |
Roshan's current position on the minimap. |
Dota2Position
| Field | Type | Description |
x |
float |
X coordinate on the minimap. |
y |
float |
Y coordinate on the minimap. |
Dota2Items
| Field | Type | Description |
items |
repeated Dota2Item |
Items carried by the player. |
Dota2Item
| Field | Type | Description |
name |
string |
Item name. |
cooldown |
optional int32 |
Seconds left on cooldown, if any. |
position |
Dota2ItemPosition |
Where the item is held (inventory slot, stash, courier, etc.). |
level |
uint32 |
Item level (for items that level up). |
Dota2Abilities
| Field | Type | Description |
abilities |
repeated Dota2Ability |
Abilities the hero has. |
Dota2Ability
| Field | Type | Description |
name |
string |
Ability name. |
cooldown |
optional int32 |
Seconds left on cooldown, if any. |
ultimate |
bool |
true if this is the hero's ultimate. |
passive |
bool |
true if the ability is passive. |
can_cast |
bool |
true if the ability can be cast right now. |
6.2.8. Dota 2 enums
Dota2Faction
| Value | Description |
| DOTA2_FACTION_UNSPECIFIED | Default; faction is not known. |
| DOTA2_FACTION_RADIANT | Radiant side. |
| DOTA2_FACTION_DIRE | Dire side. |
Dota2Lane
| Value | Description |
| DOTA2_LANE_UNSPECIFIED | Default; lane is not known. |
| DOTA2_LANE_TOP | Top lane. |
| DOTA2_LANE_MID | Mid lane. |
| DOTA2_LANE_BOT | Bottom lane. |
Dota2TowerTier
| Value | Description |
| DOTA2_TOWER_TIER_UNSPECIFIED | Default; tower tier is not known. |
| DOTA2_TOWER_TIER_1 | Tier 1 tower (outermost). |
| DOTA2_TOWER_TIER_2 | Tier 2 tower. |
| DOTA2_TOWER_TIER_3 | Tier 3 tower. |
| DOTA2_TOWER_TIER_4 | Tier 4 tower (base). |
Dota2BarrackType
| Value | Description |
| DOTA2_BARRACK_TYPE_UNSPECIFIED | Default; barrack type is not known. |
| DOTA2_BARRACK_TYPE_RANGED | Ranged barrack. |
| DOTA2_BARRACK_TYPE_MELEE | Melee barrack. |
Dota2ItemPosition
| Value | Description |
| DOTA2_ITEM_POSITION_UNSPECIFIED | Default; position is not known. |
| DOTA2_ITEM_POSITION_NEUTRAL | Neutral item slot. |
| DOTA2_ITEM_POSITION_STASH0 ... STASH5 | Stash positions on the courier (0-5). |
| DOTA2_ITEM_POSITION_TELEPORT | Teleport scroll slot. |
| DOTA2_ITEM_POSITION_SLOT0 ... SLOT8 | Inventory slots (0-8). |
6.2.9. Dota2MatchSnapshot JSON example
{
"match_urn": "od:match:9000",
"sequence": 1,
"timestamp": "2026-05-27T19:30:00.000Z",
"data_status": "DATA_STATUS_OK",
"announcements": [],
"match_state": {
"match_urn": "od:match:9000",
"match_type": "BEST_OF_TYPE_BO3",
"home_team": { "urn": "od:competitor:201", "name": "Team Alpha" },
"away_team": { "urn": "od:competitor:202", "name": "Team Beta" },
"score": { "home_score": 1, "away_score": 0 },
"match_status": "MATCH_STATUS_TYPE_LIVE",
"current_map": {
"map_order": 2,
"map_paused": false,
"game_time": { "game_time": "1820s" },
"day_time": true,
"teams": {
"od:competitor:201": {
"team_urn": "od:competitor:201",
"faction": "DOTA2_FACTION_RADIANT",
"statistics": {
"team_urn": "od:competitor:201",
"barracks": 6,
"kills": 14,
"net_worth": 32500,
"roshans": 1,
"towers": 9,
"has_roshans": true
},
"players": {}
}
},
"towers": { "towers": [] },
"barracks": { "barracks": [] },
"roshan": {
"alive": false,
"respawnTime": 360,
"position": { "x": 0.71, "y": 0.69 }
}
},
"previous_maps": [],
"picks_and_bans_selections_per_team": {
"state": "STATE_ENDED",
"active_team": "TEAM_TYPE_UNSPECIFIED",
"selection_type": "SELECTION_TYPE_UNSPECIFIED",
"active_team_time_remaining": 0,
"radiant_bonus_time": 0,
"dire_bonus_time": 0,
"radiant_selections": { "bans": [], "picks": [] },
"dire_selections": { "bans": [], "picks": [] }
}
},
"tournament": { "urn": "od:tournament:2001", "name": "The International" }
}