---
title: Darts API
description: PDC darts data — players with ELO ratings, tournaments, matches with set/leg scores, rankings and predictions.
badge: pro
---

# Darts API

The Darts API covers professional darts: players with ELO ratings,
tournaments, matches with set and leg scores, official rankings and
ELO-based win predictions.

Base URL: `https://sports.bzzoiro.com/darts/api/v2/`

## Access

Requires the **Sports Addon** ($5/month) — it unlocks the tennis, CS2, darts,
hockey, basketball and horse racing APIs plus their MCP servers. Get it at
[/addons/](/addons/). You also need a free account token from
[/register/](/register/).

```bash
Authorization: Token YOUR_API_KEY
```

Without a token you get **401**:

```json
{"error": "authentication required", "code": "authentication_required",
 "detail": "Send Authorization: Token <YOUR_TOKEN> on every request.",
 "register": "https://sports.bzzoiro.com/register/"}
```

With a token but no addon you get **402**:

```json
{"error": "Sports Addon required", "code": "addon_required",
 "detail": "Tennis, CS:GO, darts, hockey, basketball and horse racing APIs require the Sports Addon ($5/mo).",
 "pricing_url": "https://sports.bzzoiro.com/pricing/"}
```

List endpoints paginate with `limit` (default 50, max 200) and `offset`, and
return `{count, next, previous, results}`.

## Endpoints

| Endpoint | Description |
|---|---|
| `GET /darts/api/v2/players/` | List/search players with ELO |
| `GET /darts/api/v2/players/{id}/` | Player detail |
| `GET /darts/api/v2/tournaments/` | List tournaments |
| `GET /darts/api/v2/tournaments/{id}/` | Tournament detail |
| `GET /darts/api/v2/matches/` | List matches |
| `GET /darts/api/v2/matches/live/` | Matches in play right now |
| `GET /darts/api/v2/matches/{id}/` | Match detail with legs and current set |
| `GET /darts/api/v2/matches/{id}/odds/` | Per-bookmaker odds, every market |
| `GET /darts/api/v2/matches/{id}/h2h/` | Head-to-head between the two players |
| `GET /darts/api/v2/predictions/` | ELO-based win probabilities |
| `GET /darts/api/v2/predictions/{id}/` | One prediction |
| `GET /darts/api/v2/rankings/` | Official rankings (PDC by default) |

The machine-readable schema is public at `/darts/api/schema/`, with an
interactive UI at [/darts/api/docs/](/darts/api/docs/) and a themed explorer
at [/docs/explorer/darts/](/docs/explorer/darts/).

## Players

**Query parameters**

| Param | Type | Description |
|---|---|---|
| `search` | string | Name search |
| `country` | string | ISO country code |
| `limit` / `offset` | int | Pagination (default 50, max 200) |

Responses are cached ~5 minutes.

```bash
curl -H "Authorization: Token YOUR_API_KEY" \
  "https://sports.bzzoiro.com/darts/api/v2/players/?search=littler"
```

```json
{"count": 1, "results": [
  {"id": 507, "name": "Luke Littler", "country_code": "GB", "elo": 1892}
]}
```

## Tournaments

**Query parameters**

| Param | Type | Description |
|---|---|---|
| `category` | string | Tournament category (e.g. Premier League, World Championship) |
| `include_inactive` | bool | Include past/inactive tournaments |
| `limit` / `offset` | int | Pagination |

```json
{"count": 8, "results": [
  {"id": 44, "name": "World Matchplay 2026", "category": "PDC Major"}
]}
```

## Matches

**Query parameters**

| Param | Type | Description |
|---|---|---|
| `tournament` | int | Filter by tournament id |
| `player` | int | Matches involving this player id |
| `status` | string | `scheduled`, `live`, `finished`, `walkover`, `postponed`, `cancelled` |
| `date_from` / `date_to` | date | `YYYY-MM-DD`. Without either, the list returns the next 7 days, oldest first. Any of the filters above lifts that window and returns the full archive, newest first. |
| `limit` / `offset` | int | Pagination |

```bash
curl -H "Authorization: Token YOUR_API_KEY" \
  "https://sports.bzzoiro.com/darts/api/v2/matches/?player=507&status=finished"
```

```json
{"count": 11, "results": [
  {"id": 20841, "tournament": {"id": 44, "name": "World Matchplay 2026"},
   "player1": {"id": 507, "name": "Luke Littler", "country_code": "GB"},
   "player2": {"id": 312, "name": "Luke Humphries", "country_code": "GB"},
   "match_date": "2026-07-27T20:00:00+00:00", "status": "finished",
   "round_name": "Final", "player1_sets": 6, "player2_sets": 4,
   "sets_detail": "3-1, 1-3, 3-2, 3-0, 1-3, 2-3, 3-1, 3-2, 2-3, 3-1",
   "winner_id": 507, "best_of_legs": 5, "best_of_sets": 11,
   "first_to_throw_id": 507}
]}
```

`best_of_legs` / `best_of_sets` and `first_to_throw_id` are `null` when the
match format wasn't reported upstream.

`GET /matches/live/` returns in-play matches only. `GET /matches/{id}/` adds
`player1_legs`, `player2_legs` and `current_set` for live scoreboards:

```json
{"id": 20855, "status": "live", "player1_sets": 2, "player2_sets": 1,
 "player1_legs": 2, "player2_legs": 1, "current_set": 4}
```

## Odds

`GET /darts/api/v2/matches/{id}/odds/` returns every price we hold for one match: the
match-winner market flattened per bookmaker, and below it every other market the
books offered, grouped by kind, line and period.

```bash
curl -H "Authorization: Token YOUR_API_KEY" \
  "https://sports.bzzoiro.com/darts/api/v2/matches/4664/odds/"
```

```json
{"match_id": 4664, "match_date": "2026-08-14T19:00:00+00:00",
 "player1_name": "Luke Humphries", "player2_name": "Michael van Gerwen",
 "bookmakers_count": 47, "source": "multi",
 "bookmakers": [
   {"bookmaker": "Bet365", "bookmaker_slug": "bet365",
    "odds_player1": 1.25, "movement_player1": "SHORTENING",
    "odds_player2": 3.75, "movement_player2": "DRIFTING",
    "updated_at": "2026-08-14T07:55:44Z"}
 ],
 "markets": [
   {"market_kind": "WINNER", "market_family": "WINNER", "market_line": null,
    "market_period": "FT", "selections": ["P1", "P2"],
    "bookmakers": [
      {"bookmaker": "Bet365", "bookmaker_slug": "bet365",
       "prices": {"P1": {"price": 1.25, "movement": "SHORTENING"},
                  "P2": {"price": 3.75, "movement": "DRIFTING"}},
       "updated_at": "2026-08-14T07:55:44Z"}
    ]}
 ]}
```

| Field | Meaning |
|---|---|
| `source` | `multi` per-bookmaker prices, `consensus` the single stored price when the match is not yet linked to a priced feed event, `none` when nobody has priced it |
| `bookmakers_count` | Bookmakers with at least one match-winner price |
| `movement_*` | `SHORTENING`, `DRIFTING` or `STABLE` against the previous price we saw; `null` when there is no previous price |
| `market_kind` | Market type: `WINNER`, `OU` (total legs or 180s) |
| `market_family` | Distinguishes markets sharing a kind (total goals vs corners vs a single side's total) |
| `market_line` | The handicap or total the market is quoted on; `null` for a plain winner market |
| `market_period` | `FT` for the full match; period codes otherwise |

> Prices come from several sources and are pooled per match. A bookmaker appears
> once per market with its most recent price.

## Predictions

Win probabilities derived from player ELO ratings.

**Query parameters**

| Param | Type | Description |
|---|---|---|
| `upcoming` | bool | Only matches not yet started |
| `limit` / `offset` | int | Pagination |

```json
{"count": 5, "results": [
  {"id": 3308, "match_id": 20860,
   "player1_win_prob": 0.67, "player2_win_prob": 0.33,
   "predicted_winner_id": 507}
]}
```

## Rankings

**Query parameters**

| Param | Type | Description |
|---|---|---|
| `type` | string | Ranking list, default `PDC` (also `ProTour`) |
| `date` | date | Snapshot date (`YYYY-MM-DD`); default latest |
| `limit` / `offset` | int | Pagination |

Cached 5 minutes.

```json
{"count": 128, "results": [
  {"id": 71002, "position": 1, "type": "PDC", "prize_money": 1710000,
   "player": {"id": 312, "name": "Luke Humphries", "country_code": "GB"}}
]}
```

## Head-to-head

`GET /matches/{id}/h2h/` returns every finished meeting between the two players,
whichever side of the board they were on, with their three-dart averages across
those matches. It is computed from the archive, so there is nothing to sync and
nothing to go stale.

```bash
curl -H "Authorization: Token YOUR_API_KEY" \
  "https://sports.bzzoiro.com/darts/api/v2/matches/4410/h2h/"
```

```json
{"match_id": 4410,
 "player1": {"id": 1, "name": "Luke Littler"},
 "player2": {"id": 2, "name": "Luke Humphries"},
 "total_matches": 23, "player1_wins": 15, "player2_wins": 8,
 "player1_avg": 101.37, "player2_avg": 100.94,
 "recent_matches": [
   {"id": 4292, "date": "2026-06-06T19:53:00+00:00",
    "tournament": {"id": 150, "name": "Nordic Darts Masters 2026"},
    "round_name": "Semifinals", "winner": "player2",
    "player1_sets": 5, "player2_sets": 7}
]}
```

`player1` and `player2` always mean the two players of the match you asked
about; meetings stored the other way round are flipped for you.

## Coverage and off-season

The darts calendar is a run of separate tournaments rather than a continuous season, so quiet weeks are normal and the match list is empty during them.

`GET /api/v2/coverage/?sport=darts` says so directly, without a token:

```json
{"sport": "darts", "status": "no_fixtures", "events_next_7d": 0,
 "events_next_30d": 0, "priced_next_7d": 0, "live_now": 0,
 "next_event_at": null, "last_event_at": "2026-08-15T10:23:00+00:00"}
```

`status` is `in_season` (fixtures within seven days), `between_events` (nothing
this week, something later), `off_season` (nothing ahead and the last event is
more than a fortnight old) or `no_fixtures`. Drop the `?sport=` to get every
sport in one call — worth doing before a polling loop decides what to ask for.
