OpenDota API
Free Dota 2 API with no key for basic use: matches, players, heroes, pro teams and detailed statistics from parsed replays. CORS enabled. Tested example.
Endpoint tested and returned HTTP 200 on 2026-08-19
What is the OpenDota API?
OpenDota is a free, key-free API providing Dota 2 data — match details, player statistics, hero data, professional teams and analysis derived from parsed game replays.
OpenDota goes considerably deeper than Valve's own API because it parses match replays, exposing detail Valve does not publish directly: item timings, ward placements, damage breakdowns and lane outcomes.
The hero statistics endpoint is a good starting point — it returns every hero with win rates broken down by skill bracket, which is the raw material for tier lists and drafting tools.
Quick facts
- Base URL
https://api.opendota.com/api- Authentication
- Free tier works without a key. An optional free key raises limits.
- Rate limit
- 2,000 requests per day and 60 per minute without a key.
- Pricing
- Free tier; paid plans for higher volume.
- CORS
- Not enabled — call it from your server
- Official docs
- Read the docs
How to use the OpenDota API
Every request below was executed against the live API on 2026-08-19, and the response shown is the real body it returned — not an illustration.
1. Fetch Dota 2 hero statistics
GET https://api.opendota.com/api/heroStats
curl 'https://api.opendota.com/api/heroStats'const res = await fetch("https://api.opendota.com/api/heroStats");
if (!res.ok) throw new Error(`Request failed: ${res.status}`);
const data = await res.json();
console.log(data);import requests
res = requests.get("https://api.opendota.com/api/heroStats", timeout=20)
res.raise_for_status()
print(res.json())[
{
"id": 1,
"name": "npc_dota_hero_antimage",
"primary_attr": "agi",
"attack_type": "Melee",
"roles": [
"Carry",
"Escape",
"Nuker"
],
"img": "/apps/dota2/images/dota_react/heroes/antimage.png?",
"icon": "/apps/dota2/images/dota_react/heroes/icons/antimage.png?",
"base_health": 120,
"base_health_regen": 1,
"base_mana": 75,
"base_mana_regen": 0,
"base_armor": 2,
"base_mr": 25,
"base_attack_min": 29,
"base_attack_max": 33,
"base_str": 21,
"base_agi": 24,
"base_int": 12,
"str_gain": 1.6,
"agi_gain": 2.8,
"int_gain": 1.8,
"attack_range": 150,
"projectile_speed": 0,
"attack_rate": 1.4,
"base_attack_time": 100,
"attack_point": 0.3,
"move_speed": 310,
"turn_rate": null,
"cm_enabled": true,
"legs": 2,
"day_vision": 1800,
"night_vision": 800,
"localized_name": "Anti-Mage",
"1_pick": 19028,
"1_win": 9425,
"2_pick": 61535,
"2_win": 30758,
"3_pick": 93301,
"3_win": 46566,
"4_pick": 106756,
"4_win": 53396,
"5_pick": 85959,
"5_win": 42800,
"6_pick": 47613,
"6_win": 23661,
"7_pick": 28348,
"7_win": 14155,
"8_pick": 0,
"8_win": 0,
"turbo_picks": 234480,
"turbo_picks_trend": [
32157,
31689,
38289,
37836,
35123,
33010,
26376
],
"turbo_wins": 117028,
"turbo_wins_trend": [
16088,
15840,
19137,
18701,
17483,
16518,
13261
],
"pro_pick": 0,
"pro_win": 0,
"pro_banParameters
| Parameter | Type | Required | Description |
|---|---|---|---|
heroStats | path | Optional | All heroes with win/pick rates by skill bracket. heroStats |
players/<account_id> | path | Optional | Player profile and statistics. players/88367253 |
matches/<match_id> | path | Optional | Full match detail. matches/1234567890 |
proMatches | path | Optional | Recent professional matches. proMatches |
Response fields
idinteger- Hero identifier.
localized_namestring- Display name of the hero.
primary_attrstring- str, agi, int or all.
attack_typestring- Melee or Ranged.
rolesarray- Role tags such as Carry, Support or Nuker.
<bracket>_pick / <bracket>_wininteger- Picks and wins per skill bracket, e.g. 1_pick, 8_win.
What you can build with the OpenDota API
- Build a Dota 2 hero tier list from real win rates
- Analyse a player's match history and performance
- Create drafting tools using pick and win statistics
- Track professional match results and team standings
Common errors and how to fix them
429
Exceeded 60 requests per minute or 2,000 per day.
Fix: Register for a free key, and cache hero stats — they change slowly.
Match not parsed
Detailed replay data is only available for parsed matches.
Fix: Check the `version` field; unparsed matches lack item timings and ward data.
Cryptic bracket field names
Fields like 7_pick refer to skill brackets.
Fix: The number is the rank tier; consult the docs to map them to Herald through Immortal.
OpenDota API — frequently asked questions
Is the OpenDota API free?
Yes, the free tier works with no API key at 2,000 requests per day and 60 per minute. An optional free key and paid plans raise the limits.
How is it different from Valve's official API?
OpenDota parses match replays, exposing detail Valve does not publish — item timings, ward placements, damage breakdowns and lane outcomes.
What do field names like 7_pick mean?
They are per-skill-bracket pick and win counts, where the number is the rank tier. The documentation maps those numbers to Herald through Immortal.
Why is some match data missing?
Detailed data requires the replay to have been parsed. Unparsed matches return basic results only — check the `version` field to tell.
Tools that pair with this API
JSON Formatter
Format, beautify and minify JSON online with 2-space, 4-space or tab indentation. Sort keys alphabetically and catch syntax errors instantly — free and private.
Percentage Calculator
Calculate what X% of a number is, what percent one number is of another, and percentage increase or decrease between two values — instantly and free.
OpenDota is an independent third-party service and is not affiliated with ByteTools or ByteVancer. Details on this page were verified on 2026-08-19; always check the official documentation before relying on this API in production, as terms and limits can change.