# Dota 2 webhooks

Signed POST requests to your URL when Dota 2 events happen. Signing, retries, pauses and catch-up are the same for every sport: https://citoapi.com/docs/webhooks.md

Live catalog for this sport, with current status and volume: https://api.citoapi.com/api/v1/webhooks/events?game=dota2
Human docs: https://citoapi.com/docs/api/dota-2/webhooks/
Status below was measured at 2026-11-08T20:30:57.835Z. Trust the live catalog over this file.

## Which events to subscribe to

- Live scoreboard: dota2.draft.updated. Picks and bans. For the in-game score, poll /dota2/matches/live: there is no in-game score event.
- Settle bets: Dota 2 has no result event yet to subscribe to. Poll /dota2/matches/recent for finished matches.
- Results only: Dota 2 has no result event yet to subscribe to. Poll /dota2/matches/recent for finished matches.
- Alerts: dota2.draft.updated. The draft of each game. Overwrite your message: it can repeat as the draft fills in.

## Filters

- `matchId`: Only this match. Take the id from the schedule or live routes.
- `gameId`: Only one game inside a series.

## Events

### dota2.draft.updated

The picks and bans of a Dota 2 game, with hero names and team ids.

- When: When a draft is seen for a game. Can repeat for one game as it fills in.
- Status: Active. Sent during the last 7 days.
- Frequency: about 22 per day across all matches (about 3 per match)
- Plan: Pro and Scale
- Filters: matchId, gameId
- Use it to: Show picks and bans. It can repeat for one game as the draft fills in, so overwrite rather than append.

| Field | Type | Meaning |
|---|---|---|
| `bans` | array | Banned heroes with order, phase, hero id, hero name and team id. |
| `direTeam` | string | Team on Dire. |
| `draftRows` | number | Number of picks and bans so far. It grows as the draft fills in. |
| `gameId` | string | One game inside a series. |
| `gameNumber` | number | Which game of the series, from 1. |
| `matchId` | string | The match id. Works on the match routes for this sport. |
| `picks` | array | Picked heroes with order, hero id, hero name and team id. |
| `radiantTeam` | string | Team on Radiant. |
| `teams` | array | The teams in this match. |

```json
{
  "event": "dota2.draft.updated",
  "id": "a1b2c3d4-0000-4000-8000-000000000000",
  "timestamp": "2026-11-08T10:57:12.737Z",
  "event_type": "dota2.draft.updated",
  "match_id": "663676",
  "previous_state": null,
  "data": {
    "bans": [
      {
        "order": 0,
        "phase": 1,
        "heroId": 33,
        "teamId": "cyberhero",
        "heroName": "Enigma"
      },
      {
        "order": 1,
        "phase": 1,
        "heroId": 100,
        "teamId": "cyberhero",
        "heroName": "Tusk"
      },
      {
        "order": 2,
        "phase": 1,
        "heroId": 62,
        "teamId": "angry",
        "heroName": "Bounty Hunter"
      },
      {
        "order": 3,
        "phase": 1,
        "heroId": 105,
        "teamId": "angry",
        "heroName": "Techies"
      },
      {
        "order": 4,
        "phase": 1,
        "heroId": 50,
        "teamId": "cyberhero",
        "heroName": "Dazzle"
      },
      {
        "order": 5,
        "phase": 1,
        "heroId": 155,
        "teamId": "angry",
        "heroName": "Largo"
      },
      {
        "order": 6,
        "phase": 1,
        "heroId": 112,
        "teamId": "angry",
        "heroName": "Winter Wyvern"
      },
      {
        "order": 9,
        "phase": 2,
        "heroId": 55,
        "teamId": "cyberhero",
        "heroName": "Dark Seer"
      },
      {
        "order": 10,
        "phase": 2,
        "heroId": 135,
        "teamId": "cyberhero",
        "heroName": "Dawnbreaker"
      },
      {
        "order": 11,
        "phase": 2,
        "heroId": 106,
        "teamId": "angry",
        "heroName": "Ember Spirit"
      },
      {
        "order": 18,
        "phase": 3,
        "heroId": 77,
        "teamId": "cyberhero",
        "heroName": "Lycan"
      },
      {
        "order": 19,
        "phase": 3,
        "heroId": 21,
        "teamId": "angry",
        "heroName": "Windranger"
      },
      {
        "order": 20,
        "phase": 3,
        "heroId": 78,
        "teamId": "cyberhero",
        "heroName": "Brewmaster"
      },
      {
        "order": 21,
        "phase": 3,
        "heroId": 18,
        "teamId": "angry",
        "heroName": "Sven"
      }
    ],
    "picks": [
      {
        "order": 7,
        "phase": 2,
        "heroId": 49,
        "teamId": "cyberhero",
        "heroName": "Dragon Knight"
      },
      {
        "order": 8,
        "phase": 2,
        "heroId": 107,
        "teamId": "angry",
        "heroName": "Earth Spirit"
      },
      {
        "order": 12,
        "phase": 2,
        "heroId": 30,
        "teamId": "angry",
        "heroName": "Witch Doctor"
      },
      {
        "order": 13,
        "phase": 2,
        "heroId": 123,
        "teamId": "cyberhero",
        "heroName": "Hoodwink"
      },
      {
        "order": 14,
        "phase": 2,
        "heroId": 43,
        "teamId": "cyberhero",
        "heroName": "Death Prophet"
      },
      {
        "order": 15,
        "phase": 2,
        "heroId": 119,
        "teamId": "angry",
        "heroName": "Dark Willow"
      },
      {
        "order": 16,
        "phase": 2,
        "heroId": 80,
        "teamId": "angry",
        "heroName": "Lone Druid"
      },
      {
        "order": 17,
        "phase": 3,
        "heroId": 7,
        "teamId": "cyberhero",
        "heroName": "Earthshaker"
      },
      {
        "order": 22,
        "phase": 3,
        "heroId": 76,
        "teamId": "cyberhero",
        "heroName": "Outworld Devourer"
      },
      {
        "order": 23,
        "phase": 3,
        "heroId": 47,
        "teamId": "angry",
        "heroName": "Viper"
      }
    ],
    "teams": [
      "Angry Birds",
      "CyberHero"
    ],
    "gameId": "valve-live-663676-g1",
    "matchId": "663676",
    "direTeam": "Angry Birds",
    "draftRows": 24,
    "gameNumber": 1,
    "radiantTeam": "CyberHero"
  }
}
```
