BYTETOOLS

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.

No API key requiredHTTPSFree tier

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
curl 'https://api.opendota.com/api/heroStats'
JavaScript (fetch)
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);
Python (requests)
import requests

res = requests.get("https://api.opendota.com/api/heroStats", timeout=20)
res.raise_for_status()
print(res.json())
Response — HTTP 200 (truncated)
[
  {
    "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_ban

Parameters

ParameterTypeRequiredDescription
heroStatspathOptionalAll heroes with win/pick rates by skill bracket. heroStats
players/<account_id>pathOptionalPlayer profile and statistics. players/88367253
matches/<match_id>pathOptionalFull match detail. matches/1234567890
proMatchespathOptionalRecent 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

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.