Dota 2 API: Hero Details

116 heroes and counting

Getting Hero Details with GetHeroes

This section will have us start making calls to the Dota 2 API provided by Steam. We'll begin with a fairly straightforward call to GetHeroes, which will return a list of all available heroes in Dota at the moment. Then, we can use the data that we get in response and a URL for images to display hero portraits. Let's start with a simple GET request to the following URL:

https://api.steampowered.com/IEconDOTA2_570/GetHeroes/v0001/?key=APIKEY

As noted previously, replace APIKEY with your own API key or the variable storing it. We can use it in our server-side code, as detailed below. This request also takes the common options listed in the Getting Started section.

Sample Server-Side Code

An example follows of how the JavaScript might look if using Node.js, Express, and Express Handlebars. You can use this as a template for your GET requests. This example will simply put a huge wall of text (the JSON object as plaintext) on a page named test and prints the JSON response to the console, which isn't of much use to us right now, but we can tweak it down the line for our purposes, which we will see at the end of this section. For this sample code, your test.handlebars should have {{stuff}} in it. You can store your API key outside of the function as a string global variable.

The result is a list of all 116 current heroes. For those that have played the game for a while, that Skeleton King is still Skeleton King (THE ONE TRUE KING), despite Valve changing his in-game name to Wraith King (for pressing ceremonial reasons).

For fun, let's try using the language option (one of the common options outlined above) to get the heroes in Simplified Chinese (using zh_cn for the language).

https://api.steampowered.com/IEconDOTA2_570/GetHeroes/v0001/?key=APIKEY&language=zh_cn

The result now includes a localized name (in Simplified Chinese) for each hero! Tiny is literally "little little".

Breaking Down the GetHeroes Response

The response is fairly straightforward, and there aren't a lot of different keys to deal with in the response object. Here's a breakdown of the response that we get:

Hero Images

Using the information from our response from GetHeroes, we can get hero portraits from Valve's servers. The URL for the images follows the following format:

http://cdn.dota2.com/apps/dota2/images/heroes/HERONAME_SUFFIX

Replace HERONAME with the name of the hero obtained from the response to the GetHeroes call, but with the prefix npc_dota_hero_ removed. For example, use witch_doctor instead of npc_dota_hero_witch_doctor.

Replace SUFFIX with one of the four following options:

Displaying Hero Images

Armed with our JSON response and a URL for images, let's combine what we know and display small horizontal portraits for all the heroes. Using our example_request.js from above, let's modify it to append images for each hero to an array, which can then be displayed on the page called test. Note that we have parsed the response body using JSON.parse(body). We then go through the list of heroes and get the hero name by stripping off the npc_dota_hero_ prefix, then adding the HTML img tag to the array. Our test page should have the following lines in it: {{#each dataList}} {{{this}}} {{/each}}; note the use of three curly braces for {{{this}}}, which will render the HTML img tags. The end result is a colorful block of small horizontal hero portraits.

A Note

While we can make a GET request every time we want load our page with the hero images, since we know that the list of heroes changes very infrequently (thanks, Valve), it's probably best to refrain from making unnecessary requests to the API. To avoid making extra calls, I saved the JSON response of all the heroes from one API call and saved that on my server as a separate JSON file, from which I can get the data to use in future functions. However, if you know that the request you're making has the potential to have different responses depending on when you're calling it (such as when we make calls later to GetMatchHistory), and you want your page to stay up-to-date, you may need to make API calls every time your page is loaded. Another option would be to make the API call outside of the call to app.get(), so that the call is made only one time every time the script is run (such as when you start your server).