Dota 2 API: Match Details

Getting information about a specific match, so you can show off your 900 GPM on Gyrocopter and 3 divine rapiers

Getting Match Details with GetMatchDetails

Let's say you just played an awesome game of Dota, where you had great itemization, good farm, and a nice kill/death ratio, and you'd like to get the data so that you can use it on a webpage down the line. We can do that by making a call to the Dota 2 web API and getting the match details. We can also combine our previous calls to GetHeroes and GetGameItems with the match details to display the match details in a manner that's not totally hideous.

GetMatchDetails has the common options (discussed in Getting Started) as well as a parameter for match ID: match_id=MATCHID (as an ID), where we replace MATCHID with the ID of the match we would like to see. As noted previously, replace APIKEY with your own API key or the variable storing it. The general format is a GET request as follows:

For our example, we'll use the following match ID: 1973457695. For simplicity, this is a public ranked all-pick match, without a pick/ban series. We'll make a GET request to the previous URL with the substituted match ID and API key. The result is a pretty hefty JSON response:

Breaking Down the GetMatchDetails Response

There's a lot going on in our JSON response, so here's a breakdown of the response that we get and what it all means:


The player slot is represented by an 8-bit unsigned integer. The first bit represents the player's team: if Radiant, then the first bit is 0/false; if Dire, then the first bit is 1/true. The last three bits represent the player's position in the team (decimal 0 - 4). If a player's player_slot is 129 in decimal (which is 10000001 in binary), then they are the second player on the Dire team.


Dota has a system that punishes players that frequently abandon games, as abandoning or disconnecting from games will have a negative impact on your teammates.

tower_status_radiant, tower_status_dire

The tower status is represented by a 16-bit unsigned integer; the rightmost 11 bits represent individual towers for the team. The rightmost 11 bits represent the towers in the following order: ancient top tower, ancient bottom tower, bottom tier 3, bottom tier 2, bottom tier 1, middle tier 3, middle tier 2, middle tier 1, top tier 3, top tier 3, and top tier 1. For example, if the tower_status_radiant is 1572 in decimal (as in the example), then this is 0000011000100100 in binary. The first five bits do not matter, so we have 11000100100. This means that the Radiant still had their ancient top and bottom towers, as well as their middle and top tier 3 towers.

barracks_status_radiant, barracks_status_dire

Each team's barracks status is represented by an 8-bit unsigned integer; the rightmost 6 bits represent individual barracks for the team. The rightmost 6 bits represent the barracks in the following order: bottom ranged, bottom melee, middle ranged, middle melee, top ranged, and top melee. For example, if the barracks_status_dire is 32 (as in the example), then this is 00100000 in binary. The first two bits do not matter, so we have 100000. This means that the Dire still had their bottom ranged barracks at the end of the game, but all others were destroyed.


The cluster indicates the general server the match was played on. This value could be used to download replays, but the ability to download replays has since been removed with the removal of the replay_salt field from the API (see below). The match in our example was played on a Europe West server.


According to this post on the Dota 2 dev forum, the replay_salt field has been removed due to privacy issues. Therefore, the previous method of downloading replays is not available.

Previously, replays were downloaded using the cluster, match_id, and replay_salt using the following URL (replace CLUSTER, MATCHID, and REPLAYSALT accordingly):


Indicates the type of lobby, such as public, practice, ranked, etc. The match in our example was a ranked match.


This field gives additional information about the game mode, such as if a match was single draft, all random, or all pick. The match in our example is a ranked all pick match.

Simple Match Details

Now that we're able to pull match details using an API call, we can attempt to display it in a manner that's easily digestible for users.

This is a fairly brief match summary that displays the match ID, start time, duration, and the winner, as well as the hero portraits for each team. There are two separate functions, convertUnixTime() and findHero(), which are left as exercises for the reader. This example uses Node.js, Express, and Handlebars.

Match ID: 1973457695
Match start: Tue Dec 01 2015 23:14:59 GMT+0000 (Coordinated Universal Time)
Radiant wins!
Duration: 72min 16sec