Games & Comics — entry 018 of 75

Dota 2

Verified Sep 2026

OpenDota provides open Dota 2 match, player, and hero statistics parsed from Valve's WebAPI and replay files, including hero win rates, benchmarked performance percentiles, and full match/player history. The core API is entirely keyless and free, with a 60-call-per-minute / 3,000-call-per-day limit; registering a free account for an API key only raises those limits, it doesn't gate access.

OpenDota provides open Dota 2 match, player, and hero statistics parsed from Valve's WebAPI. A live GET this run against /players/1 returned a genuine 837 B player profile at HTTP 200, content-type: application/json; charset=utf-8 — fully keyless.

dota-2esportsmatch-statsvalvegame-data
AuthenticationNone requiredCall it straight away — no key, no signup.
HTTPSSupportedTraffic is encrypted in transit.
CORSEnabledCallable directly from browser JavaScript.
PricingFreemiumA usable free tier exists, with paid plans for more volume.
FormatsJSONResponses can be requested as JSON.

GreatAPIs Score

Score91out of 100
Authentication25/25No authentication required
Pricing17/20Freemium tier available
Docs20/20Machine-readable spec file bundled
Formats9/15Single response format
Freshness20/20Verified within 6 months

Embed this badge

Scored 91 on greatapis.com
<a href="https://greatapis.com/api/dota-2/"><img src="https://greatapis.com/badge/dota-2.svg" alt="Scored 91 on greatapis.com"></a>

Auth quickstart

  1. No API key, signup, or credit card required — the live GET above returned real player data with no auth header attached. An optional free API key only raises the rate limit; it never gates access. A keyless request this run carried x-rate-limit-remaining-minute: 57 and x-rate-limit-remaining-day: 2987, consistent with the documented 60/minute, 3,000/day keyless ceiling.
Stored keyNo key stored

Your key is stored only in this browser (localStorage) and sent directly to the API — never to greatapis.

Endpoints

Servers
https://api.opendota.com/api
benchmarks1
GET/benchmarksGET /benchmarks
Parameters
NameInRequiredType
hero_idqueryyesstring
bracketquerynointeger
Responses
StatusDescriptionSchema
200SuccessBenchmarksResponse
constants1
GET/constants/{resource}GET /constants
Parameters
NameInRequiredType
resourcepathyesstring
Responses
StatusDescriptionSchema
200Success—
distributions1
GET/distributionsGET /distributions
Responses
StatusDescriptionSchema
200SuccessDistributionsResponse
explorer1
GET/explorerGET /explorer
Parameters
NameInRequiredType
sqlquerynostring
Responses
StatusDescriptionSchema
200Success—
findMatches1
GET/findMatchesGET /
Parameters
NameInRequiredType
teamAquerynoarray
teamBquerynoarray
Responses
StatusDescriptionSchema
200Success—
health1
GET/healthGET /health
Responses
StatusDescriptionSchema
200Success—
hero stats1
GET/heroStatsGET /heroStats
Responses
StatusDescriptionSchema
200Success—
heroes6
GET/heroesGET /heroes
Responses
StatusDescriptionSchema
200Success—
GET/heroes/{hero_id}/durationsGET /heroes/{hero_id}/durations
Parameters
NameInRequiredType
hero_idpathyesinteger
Responses
StatusDescriptionSchema
200Success—
GET/heroes/{hero_id}/itemPopularityGET /heroes/{hero_id}/itemPopularity
Parameters
NameInRequiredType
hero_idpathyesinteger
Responses
StatusDescriptionSchema
200SuccessHeroItemPopularityResponse
GET/heroes/{hero_id}/matchesGET /heroes/{hero_id}/matches
Parameters
NameInRequiredType
hero_idpathyesinteger
Responses
StatusDescriptionSchema
200Success—
GET/heroes/{hero_id}/matchupsGET /heroes/{hero_id}/matchups
Parameters
NameInRequiredType
hero_idpathyesinteger
Responses
StatusDescriptionSchema
200Success—
GET/heroes/{hero_id}/playersGET /heroes/{hero_id}/players
Parameters
NameInRequiredType
hero_idpathyesinteger
Responses
StatusDescriptionSchema
200Success—
leagues5
GET/leaguesGET /leagues
Responses
StatusDescriptionSchema
200Success—
GET/leagues/{league_id}GET /leagues/{league_id}
Parameters
NameInRequiredType
league_idpathyesinteger
Responses
StatusDescriptionSchema
200Success—
GET/leagues/{league_id}/matchIdsGET /leagues/{league_id}/matchIds
Parameters
NameInRequiredType
league_idpathyesinteger
Responses
StatusDescriptionSchema
200Success—
GET/leagues/{league_id}/matchesGET /leagues/{league_id}/matches
Parameters
NameInRequiredType
league_idpathyesinteger
Responses
StatusDescriptionSchema
200SuccessMatchObjectResponse
GET/leagues/{league_id}/teamsGET /leagues/{league_id}/teams
Parameters
NameInRequiredType
league_idpathyesinteger
Responses
StatusDescriptionSchema
200SuccessTeamObjectResponse
live1
GET/liveGET /live
Responses
StatusDescriptionSchema
200Success—
matches1
GET/matches/{match_id}GET /matches/{match_id}
Parameters
NameInRequiredType
match_idpathyesinteger
Responses
StatusDescriptionSchema
200SuccessMatchResponse
metadata1
GET/metadataGET /metadata
Responses
StatusDescriptionSchema
200SuccessMetadataResponse
parsed matches1
GET/parsedMatchesGET /parsedMatches
Parameters
NameInRequiredType
less_than_match_idquerynointeger
Responses
StatusDescriptionSchema
200Success—
players15
GET/players/{account_id}GET /players/{account_id}
Parameters
NameInRequiredType
account_idpathyesinteger
Responses
StatusDescriptionSchema
200SuccessPlayersResponse
GET/players/{account_id}/countsGET /players/{account_id}/counts
Parameters
NameInRequiredType
account_idpathyesinteger
limitquerynointeger
offsetquerynointeger
winquerynointeger
patchquerynointeger
game_modequerynointeger
lobby_typequerynointeger
regionquerynointeger
datequerynointeger
lane_rolequerynointeger
hero_idquerynointeger
is_radiantquerynointeger
included_account_idquerynointeger
excluded_account_idquerynointeger
with_hero_idquerynointeger
against_hero_idquerynointeger
significantquerynointeger
havingquerynointeger
sortquerynostring
Responses
StatusDescriptionSchema
200SuccessPlayerCountsResponse
GET/players/{account_id}/heroesGET /players/{account_id}/heroes
Parameters
NameInRequiredType
account_idpathyesinteger
limitquerynointeger
offsetquerynointeger
winquerynointeger
patchquerynointeger
game_modequerynointeger
lobby_typequerynointeger
regionquerynointeger
datequerynointeger
lane_rolequerynointeger
hero_idquerynointeger
is_radiantquerynointeger
included_account_idquerynointeger
excluded_account_idquerynointeger
with_hero_idquerynointeger
against_hero_idquerynointeger
significantquerynointeger
havingquerynointeger
sortquerynostring
Responses
StatusDescriptionSchema
200Success—
GET/players/{account_id}/histograms/{field}GET /players/{account_id}/histograms
Parameters
NameInRequiredType
account_idpathyesinteger
limitquerynointeger
offsetquerynointeger
winquerynointeger
patchquerynointeger
game_modequerynointeger
lobby_typequerynointeger
regionquerynointeger
datequerynointeger
lane_rolequerynointeger
hero_idquerynointeger
is_radiantquerynointeger
included_account_idquerynointeger
excluded_account_idquerynointeger
with_hero_idquerynointeger
against_hero_idquerynointeger
significantquerynointeger
havingquerynointeger
sortquerynostring
fieldpathyesstring
Responses
StatusDescriptionSchema
200Success—
GET/players/{account_id}/matchesGET /players/{account_id}/matches
Parameters
NameInRequiredType
account_idpathyesinteger
limitquerynointeger
offsetquerynointeger
winquerynointeger
patchquerynointeger
game_modequerynointeger
lobby_typequerynointeger
regionquerynointeger
datequerynointeger
lane_rolequerynointeger
hero_idquerynointeger
is_radiantquerynointeger
included_account_idquerynointeger
excluded_account_idquerynointeger
with_hero_idquerynointeger
against_hero_idquerynointeger
significantquerynointeger
havingquerynointeger
sortquerynostring
projectquerynostring
Responses
StatusDescriptionSchema
200Success—
GET/players/{account_id}/peersGET /players/{account_id}/peers
Parameters
NameInRequiredType
account_idpathyesinteger
limitquerynointeger
offsetquerynointeger
winquerynointeger
patchquerynointeger
game_modequerynointeger
lobby_typequerynointeger
regionquerynointeger
datequerynointeger
lane_rolequerynointeger
hero_idquerynointeger
is_radiantquerynointeger
included_account_idquerynointeger
excluded_account_idquerynointeger
with_hero_idquerynointeger
against_hero_idquerynointeger
significantquerynointeger
havingquerynointeger
sortquerynostring
Responses
StatusDescriptionSchema
200Success—
GET/players/{account_id}/prosGET /players/{account_id}/pros
Parameters
NameInRequiredType
account_idpathyesinteger
limitquerynointeger
offsetquerynointeger
winquerynointeger
patchquerynointeger
game_modequerynointeger
lobby_typequerynointeger
regionquerynointeger
datequerynointeger
lane_rolequerynointeger
hero_idquerynointeger
is_radiantquerynointeger
included_account_idquerynointeger
excluded_account_idquerynointeger
with_hero_idquerynointeger
against_hero_idquerynointeger
significantquerynointeger
havingquerynointeger
sortquerynostring
Responses
StatusDescriptionSchema
200Success—
GET/players/{account_id}/rankingsGET /players/{account_id}/rankings
Parameters
NameInRequiredType
account_idpathyesinteger
Responses
StatusDescriptionSchema
200Success—
GET/players/{account_id}/ratingsGET /players/{account_id}/ratings
Parameters
NameInRequiredType
account_idpathyesinteger
Responses
StatusDescriptionSchema
200Success—
GET/players/{account_id}/recentMatchesGET /players/{account_id}/recentMatches
Parameters
NameInRequiredType
account_idpathyesinteger
Responses
StatusDescriptionSchema
200Success—
POST/players/{account_id}/refreshPOST /players/{account_id}/refresh
Parameters
NameInRequiredType
account_idpathyesinteger
Responses
StatusDescriptionSchema
200Success—
GET/players/{account_id}/totalsGET /players/{account_id}/totals
Parameters
NameInRequiredType
account_idpathyesinteger
limitquerynointeger
offsetquerynointeger
winquerynointeger
patchquerynointeger
game_modequerynointeger
lobby_typequerynointeger
regionquerynointeger
datequerynointeger
lane_rolequerynointeger
hero_idquerynointeger
is_radiantquerynointeger
included_account_idquerynointeger
excluded_account_idquerynointeger
with_hero_idquerynointeger
against_hero_idquerynointeger
significantquerynointeger
havingquerynointeger
sortquerynostring
Responses
StatusDescriptionSchema
200Success—
GET/players/{account_id}/wardmapGET /players/{account_id}/wardmap
Parameters
NameInRequiredType
account_idpathyesinteger
limitquerynointeger
offsetquerynointeger
winquerynointeger
patchquerynointeger
game_modequerynointeger
lobby_typequerynointeger
regionquerynointeger
datequerynointeger
lane_rolequerynointeger
hero_idquerynointeger
is_radiantquerynointeger
included_account_idquerynointeger
excluded_account_idquerynointeger
with_hero_idquerynointeger
against_hero_idquerynointeger
significantquerynointeger
havingquerynointeger
sortquerynostring
Responses
StatusDescriptionSchema
200SuccessPlayerWardMapResponse
GET/players/{account_id}/wlGET /players/{account_id}/wl
Parameters
NameInRequiredType
account_idpathyesinteger
limitquerynointeger
offsetquerynointeger
winquerynointeger
patchquerynointeger
game_modequerynointeger
lobby_typequerynointeger
regionquerynointeger
datequerynointeger
lane_rolequerynointeger
hero_idquerynointeger
is_radiantquerynointeger
included_account_idquerynointeger
excluded_account_idquerynointeger
with_hero_idquerynointeger
against_hero_idquerynointeger
significantquerynointeger
havingquerynointeger
sortquerynostring
Responses
StatusDescriptionSchema
200SuccessPlayerWinLossResponse
GET/players/{account_id}/wordcloudGET /players/{account_id}/wordcloud
Parameters
NameInRequiredType
account_idpathyesinteger
limitquerynointeger
offsetquerynointeger
winquerynointeger
patchquerynointeger
game_modequerynointeger
lobby_typequerynointeger
regionquerynointeger
datequerynointeger
lane_rolequerynointeger
hero_idquerynointeger
is_radiantquerynointeger
included_account_idquerynointeger
excluded_account_idquerynointeger
with_hero_idquerynointeger
against_hero_idquerynointeger
significantquerynointeger
havingquerynointeger
sortquerynostring
Responses
StatusDescriptionSchema
200SuccessPlayerWordCloudResponse
pro matches1
GET/proMatchesGET /proMatches
Parameters
NameInRequiredType
less_than_match_idquerynointeger
Responses
StatusDescriptionSchema
200Success—
pro players1
GET/proPlayersGET /proPlayers
Responses
StatusDescriptionSchema
200Success—
public matches1
GET/publicMatchesGET /publicMatches
Parameters
NameInRequiredType
less_than_match_idquerynointeger
min_rankquerynointeger
max_rankquerynointeger
Responses
StatusDescriptionSchema
200Success—
rankings1
GET/rankingsGET /rankings
Parameters
NameInRequiredType
hero_idqueryyesstring
Responses
StatusDescriptionSchema
200SuccessRankingsResponse
records1
GET/records/{field}GET /records/{field}
Parameters
NameInRequiredType
fieldpathyesstring
Responses
StatusDescriptionSchema
200Success—
request2
GET/request/{jobId}GET /request/{jobId}
Parameters
NameInRequiredType
jobIdpathyesstring
Responses
StatusDescriptionSchema
200Success—
POST/request/{match_id}POST /request/{match_id}
Parameters
NameInRequiredType
match_idpathyesinteger
Responses
StatusDescriptionSchema
200Success—
scenarios3
GET/scenarios/itemTimingsGET /scenarios/itemTimings
Parameters
NameInRequiredType
itemquerynostring
hero_idquerynointeger
Responses
StatusDescriptionSchema
200Success—
GET/scenarios/laneRolesGET /scenarios/laneRoles
Parameters
NameInRequiredType
lane_rolequerynostring
hero_idquerynointeger
Responses
StatusDescriptionSchema
200Success—
GET/scenarios/miscGET /scenarios/misc
Parameters
NameInRequiredType
scenarioquerynostring
Responses
StatusDescriptionSchema
200Success—
schema1
GET/schemaGET /schema
Responses
StatusDescriptionSchema
200Success—
search1
GET/searchGET /search
Parameters
NameInRequiredType
qqueryyesstring
Responses
StatusDescriptionSchema
200Success—
teams5
GET/teamsGET /teams
Parameters
NameInRequiredType
pagequerynointeger
Responses
StatusDescriptionSchema
200Success—
GET/teams/{team_id}GET /teams/{team_id}
Parameters
NameInRequiredType
team_idpathyesinteger
Responses
StatusDescriptionSchema
200SuccessTeamObjectResponse
GET/teams/{team_id}/heroesGET /teams/{team_id}/heroes
Parameters
NameInRequiredType
team_idpathyesinteger
Responses
StatusDescriptionSchema
200SuccessTeamHeroesResponse
GET/teams/{team_id}/matchesGET /teams/{team_id}/matches
Parameters
NameInRequiredType
team_idpathyesinteger
Responses
StatusDescriptionSchema
200SuccessTeamMatchObjectResponse
GET/teams/{team_id}/playersGET /teams/{team_id}/players
Parameters
NameInRequiredType
team_idpathyesinteger
Responses
StatusDescriptionSchema
200SuccessTeamPlayersResponse
top players1
GET/topPlayersGET /topPlayers
Parameters
NameInRequiredType
turboquerynointeger
Responses
StatusDescriptionSchema
200Success—

Try it

Developer reference

Base URLhttps://api.opendota.com/api
Rate limit

60 requests/minute and 3,000 requests/day per IP, unauthenticated (an API key raises the limit) -- live x-rate-limit-remaining-minute/x-rate-limit-remaining-day headers on api.opendota.com/api/status.

Key endpoints
  • GET/players/{account_id}
  • GET/heroStats
  • GET/heroes
  • GET/matches/{match_id}

Gotchas & limits

  • CORS echoes the caller's Origin instead of a wildcard — a live GET this run with Origin: https://greatapis.com returned access-control-allow-origin: https://greatapis.com, access-control-allow-credentials: true, and vary: Origin; the same GET with no Origin header carried no access-control-allow-origin at all (though access-control-allow-credentials: true was still present either way). A bare curl with no Origin showing no ACAO is expected behavior, not an outage.
  • Rate-limit headers use a non-standard hyphenation — a live GET this run returned x-rate-limit-remaining-minute and x-rate-limit-remaining-day (not the conventional x-ratelimit-* spelling), and there is no x-rate-limit-limit and no retry-after header. The only way to infer the ceiling is by watching the remaining count decrement across calls.
  • Unknown IDs return a clean 404, not an empty or malformed body — live GETs this run against both /players/999999999 and /matches/1 returned HTTP 404 with the identical 21 B body {"error":"Not Found"}. A valid low account ID still resolves normally, confirmed live above with /players/1 — a small numeric ID is not itself a sign of an invalid one.
  • /players/{account_id} takes the 32-bit Dota account ID, not the 64-bit Steam ID — confirmed live above: the same profile carries account_id: 1 and steamid: "76561197960265729" side by side, and only the former works in the path.
  • The free tier is not a trial — a live keyless GET this run to /heroStats (164,790 B) and /heroes (21,804 B) both returned full HTTP 200 datasets with no key, no truncation, and no upsell fields; registering a key only raises the 60/min, 3,000/day ceiling reported in the rate-limit headers above, it doesn't unlock additional data.

Availability

Uptime100%
Median latency179 ms
Last checkUp · 200 · Sep 2026

15 checks since Aug 2026. A person runs this check by hand, not an automated monitor.

Changelog

Spec version31.1.0
Tracked paths55
  • Sep 2026gained an OpenAPI spec

Tracking since Sep 2026. See every tracked change ↗ ·Subscribe with RSS ↗