# Darts API complete reference

One REST API over professional darts since 1994: results with each player's statistics, fixtures and live scores, ratings, closing prices and a probability model.

- **Base URL:** `https://api.dartsapi.com/v1`
- **Authentication:** `Authorization: Bearer da_live_...` (or `X-API-Key`), never in the address
- **Site:** https://dartsapi.com
- **Endpoints:** 52, 16 on the free key
- **Generated:** 2026-10-08 (the newest change to the sources this is built from)
- **This file:** https://dartsapi.com/documentation/manual.md
- **Operator:** DeveloperData.net

## Before anything else

- **Factual data only.** No endpoint gives tips or betting advice. The probability endpoints are a model's estimate, labelled as such, never a recommendation.
- **What the data does not hold, on any plan:** a live bookmaker price feed (closing prices are history and stop at the last match priced), prize money, venues and broadcasters, and visit-by-visit scoring.
- **The envelope.** Every answer is `{"data": ..., "meta": {...}}`. `meta` carries `request_id`, `data_as_of` (how fresh the archive was when it answered), on lists `next_cursor`, and on the free key `window`.
- **Ids carry their type:** `pl_` a player, `mt_` a match, `cp_` a competition, `ev_` an edition. Times are UTC.

## Plans

| Plan | Price | Reads | Rate limit | Calls |
| --- | --- | --- | --- | --- |
| Free key | $0 | Every free endpoint, on results at least seven days old | 60 a minute | 500 a day |
| Live | $39 a month | In-play and the last thirty days | 120 a minute | 250,000 a month |
| Archive | $79 a month | The whole archive, but nothing in play | 120 a minute | 250,000 a month |
| Complete | $99 a month | In-play and the whole archive | 180 a minute | 600,000 a month |
| Analyst | $149 a month | Everything, including the model endpoints | 240 a minute | 1,000,000 a month |

Prices and limits: https://dartsapi.com/pricing

## Coverage

Counted from the archive, not claimed, as of 2026-10-12:

- **Matches:** 447,448, from 1994-01-02 to 2026-10-10
- **Players:** 43,761
- **Events:** 9,869 across 1,965 competitions
- **World championships the archive does not hold** (the BDO's from 1978, the WDF's of 2023 and 2024, men's and women's): `GET /v1/history/world-championships`

`GET /v1/coverage` returns the same figures, season by season, with close seasons told apart from real gaps.

## Endpoints

### Reference and coverage

What the archive holds, and the competitions and calendar it holds them in.

#### `GET /v1/coverage`

Coverage. Measured coverage, with close seasons told apart from real gaps.

Plans: Free key, Live, Archive, Complete, Analyst. Page: https://dartsapi.com/documentation/endpoints/coverage

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `season` | query | int | no | Just one season, such as 2025. Leave it out for every season. |
| `competition_id` | query | id | no | Just one competition. |

Errors: 401 `no_key`, `bad_key`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

```json
{
    "data": {
        "held": {
            "matches": 437996,
            "players": 37973,
            "players_with_full_statistics": 10106,
            "competitions": 1015,
            "events": 5120,
            "first_match": "1994-01-02",
            "last_match": "2026-09-30",
            "statistics": [
                "three_dart_avg",
                "first_9_avg"
            ]
        },
        "by_season": [
            {
                "season": 2025,
                "matches": 65925,
                "events": 701,
                "three_dart_avg": {
                    "both_players_pct": 100
                },
                "full_statistics": {
                    "either_player_pct": 94.6,
                    "both_players_pct": 76.7
                }
            }
        ],
        "note": "The three-dart average is held for almost every match. The full set of statistics is held for players with 25 or more matches, and for anyone who has played a major, so a match between two newcomers carries a result and averages but not the rest."
    },
    "meta": {
        "plan": "analyst",
        "window": "everything, including the model endpoints",
        "measured_at": "2026-09-30T18:08:03Z",
        "data_as_of": "2026-09-30T18:38:31Z"
    }
}
```

#### `GET /v1/organisers` (paid plans)

Organisers. Tour bodies and what each runs.

Plans: Live, Archive, Complete, Analyst. Page: https://dartsapi.com/documentation/endpoints/organisers

Errors: 401 `no_key`, `bad_key`; 402 `upgrade_required`; 429 over the rate or allowance.

```json
{
    "data": [
        {
            "organiser": "unattributed",
            "competitions": 1004,
            "events": 5013,
            "first_event": "1994-01-02",
            "last_event": "2026-10-04"
        },
        {
            "organiser": "pdc_development",
            "competitions": 4,
            "events": 48,
            "first_event": "2021-07-02",
            "last_event": "2021-11-07"
        }
    ],
    "meta": {
        "count": 5,
        "plan": "analyst",
        "data_as_of": "2026-09-30T18:38:31Z"
    }
}
```

#### `GET /v1/competitions`

Competitions. Every competition with its tier and format.

Plans: Free key, Live, Archive, Complete, Analyst. Page: https://dartsapi.com/documentation/endpoints/competitions

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `organiser` | query | string | no | Only this tour body, as /v1/organisers names it: pdc, pdc_development, pdc_affiliate, bdo or unattributed. |
| `tier` | query | enum | no | Only this tier: majors, players_championship, european_tour, world_series, qualifiers, development_tour, challenge_tour, womens_series, junior, regional, wdf_platinum, wdf_gold, wdf_silver, wdf_bronze, and so on. |
| `q` | query | string | no | Search text. Accents and particles are folded, so "van gerwen" finds Michael van Gerwen. |
| `limit` | query | int | no | How many to return. Default 50, at most 200. |
| `cursor` | query | cursor | no | Carry on from here: pass back meta.next_cursor exactly as it came. |

Errors: 401 `no_key`, `bad_key`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

```json
{
    "data": [
        {
            "competition_id": "cp_X63B14",
            "name": "25 Bull Darts UK Open Qualifier",
            "organiser": null,
            "tier": "qualifiers",
            "editions": 9,
            "first_event": "2024-12-14",
            "last_event": "2025-02-15"
        },
        {
            "competition_id": "cp_QEA2F5",
            "name": "AB Darts Open Men",
            "organiser": null,
            "tier": "wdf_bronze",
            "editions": 1,
            "first_event": "2026-03-22",
            "last_event": "2026-03-22"
        }
    ],
    "meta": {
        "count": 3,
        "next_cursor": "c_gAYXRfVSTL1nvUIddwq7",
        "plan": "analyst",
        "data_as_of": "2026-09-30T18:38:31Z"
    }
}
```

#### `GET /v1/competitions/{id}` (paid plans)

A competition. One competition, its editions and how its market behaves.

Plans: Live, Archive, Complete, Analyst. Page: https://dartsapi.com/documentation/endpoints/competition

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `competition_id` | path | id | yes | A competition, as cp_ followed by six characters. |

Errors: 401 `no_key`, `bad_key`; 402 `upgrade_required`; 404 `not_found`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

```json
{
    "data": {
        "competition_id": "cp_2YJ4TA",
        "name": "European Tour",
        "editions": [
            {
                "event_id": "ev_9A6CF7",
                "date": "2026-09-13",
                "organiser": null,
                "tier": "european_tour",
                "matches": 47
            },
            {
                "event_id": "ev_15WNS6",
                "date": "2026-09-06",
                "organiser": null,
                "tier": "european_tour",
                "matches": 47
            }
        ]
    },
    "meta": {
        "count": 100,
        "plan": "analyst",
        "data_as_of": "2026-09-30T18:38:31Z"
    }
}
```

#### `GET /v1/calendar`

Calendar. Editions across a date range with status.

Plans: Free key, Live, Archive, Complete, Analyst. Page: https://dartsapi.com/documentation/endpoints/calendar

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `from` | query | date | no | Earliest date to include, YYYY-MM-DD. |
| `to` | query | date | no | Latest date to include, YYYY-MM-DD. |
| `status` | query | enum | no | completed, scheduled or no_results_held. |
| `organiser` | query | string | no | Only this tour body, as /v1/organisers names it: pdc, pdc_development, pdc_affiliate, bdo or unattributed. |
| `limit` | query | int | no | How many to return. Default 50, at most 200. |
| `cursor` | query | cursor | no | Carry on from here: pass back meta.next_cursor exactly as it came. |

Errors: 401 `no_key`, `bad_key`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

```json
{
    "data": [
        {
            "event_id": "ev_0ATG2W",
            "competition_id": "cp_7B1KJZ",
            "name": "World Grand Prix",
            "date": "2026-10-04",
            "organiser": null,
            "tier": "tour_other",
            "matches": 12,
            "status": "completed"
        },
        {
            "event_id": "ev_H1H9W3",
            "competition_id": "cp_2WREDF",
            "name": "MODUS Super Series #15 Week",
            "date": "2026-10-03",
            "organiser": null,
            "tier": "regional",
            "matches": 15,
            "status": "completed"
        }
    ],
    "meta": {
        "count": 3,
        "next_cursor": "c_VSwJ283LAW1dp4pnhR-OcFIOmWfR2ihM",
        "plan": "analyst",
        "data_as_of": "2026-09-30T18:38:31Z"
    }
}
```

#### `GET /v1/major-editions`

major_editions. Every edition of the main tournaments since 1994: dates, venue, town and country, organiser, sponsor, field size and prize pool, with our edition ids. major= for one.

Plans: Free key, Live, Archive, Complete, Analyst. Page: https://dartsapi.com/documentation/endpoints/major-editions

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `major` | query | string | no |  |

Errors: 401 `no_key`, `bad_key`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

#### `GET /v1/major-editions/{year}` (paid plans)

major_edition_year. Each edition of that year in full, with the prize for each stage reached (champion, runner-up, semi finals and on). major= for one.

Plans: Live, Archive, Complete, Analyst. Page: https://dartsapi.com/documentation/endpoints/major-edition-year

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `year` | path | int | yes |  |
| `major` | query | string | no |  |

Errors: 401 `no_key`, `bad_key`; 402 `upgrade_required`; 404 `not_found`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

### Editions

One staging of a competition: its field, its tables and the odds over its draw.

#### `GET /v1/editions/{id}` (paid plans)

An edition. One staging: field, winner and completeness. Matches are grouped by round where the draw is complete, by day otherwise.

Plans: Live, Archive, Complete, Analyst. Page: https://dartsapi.com/documentation/endpoints/edition

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `edition_id` | path | id | yes | One staging of a competition, as ev_ followed by six characters. |

Errors: 401 `no_key`, `bad_key`; 402 `upgrade_required`; 404 `not_found`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

```json
{
    "data": {
        "event_id": "ev_FTY24C",
        "competition_id": "cp_X645YM",
        "name": "World Series of Darts Finals",
        "date": "2026-09-20",
        "organiser": "pdc",
        "tier": "majors",
        "matches": 31,
        "field": 32,
        "last_match": {
            "match_id": "mt_0WFNJWN226KKHKW9AGN7",
            "played_on": "2026-09-20",
            "round": "quarter_final",
            "winner": {
                "player_id": "pl_EWH24M",
                "name": "Gian van Veen",
                "score": 10
            },
            "loser": {
                "player_id": "pl_0886SR",
                "name": "Dirk van Duijvenbode",
                "score": 8
            },
            "event": {
                "event_id": "ev_FTY24C",
                "competition_id": "cp_X645YM",
                "name": "World Series of Darts Finals",
                "date": "2026-09-20",
                "tier": "majors"
            }
        }
    },
    "meta": {
        "plan": "analyst",
        "window": "everything, including the model endpoints",
        "data_as_of": "2026-09-30T18:38:31Z"
    }
}
```

#### `GET /v1/editions/{id}/standings` (paid plans)

Standings. League and group tables, Premier League nights included.

Plans: Live, Archive, Complete, Analyst. Page: https://dartsapi.com/documentation/endpoints/edition-standings

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `edition_id` | path | id | yes | One staging of a competition, as ev_ followed by six characters. |

Errors: 401 `no_key`, `bad_key`; 402 `upgrade_required`; 404 `not_found`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

```json
{
    "data": [
        {
            "position": 1,
            "player_id": "pl_VEB8HM",
            "name": "Luke Littler",
            "won": 26,
            "lost": 10,
            "legs": {
                "for": 199,
                "against": 169,
                "difference": 30
            }
        },
        {
            "position": 2,
            "player_id": "pl_NWEKMD",
            "name": "Jonny Clayton",
            "won": 20,
            "lost": 13,
            "legs": {
                "for": 163,
                "against": 149,
                "difference": 14
            }
        }
    ],
    "meta": {
        "count": 8,
        "plan": "analyst",
        "note": "Built from the matches held for this edition, so a knockout reads as a run rather than a league table.",
        "data_as_of": "2026-09-30T18:38:31Z"
    }
}
```

#### `GET /v1/editions/{id}/outrights` (Analyst)

Outrights. Exact title and round-reaching probabilities over the known draw.

Plans: Analyst. Page: https://dartsapi.com/documentation/endpoints/edition-outrights

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `edition_id` | path | id | yes | One staging of a competition, as ev_ followed by six characters. |
| `simulations` | query | int | no | Not needed: the odds are worked out exactly through the draw, so nothing is simulated. |

Errors: 401 `no_key`, `bad_key`; 402 `upgrade_required`; 404 `not_found`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

```json
{
    "data": {
        "edition": {
            "event_id": "ev_FTY24C",
            "name": "World Series of Darts Finals",
            "date": "2026-09-20"
        },
        "field": 32,
        "champion": "pl_60EH4D",
        "champion_title_pct_beforehand": 3.67,
        "favourite_won": false,
        "players": [
            {
                "player_id": "pl_VEB8HM",
                "name": "Luke Littler",
                "rating": 2428.3,
                "title_pct": 38.65,
                "fair_odds": 2.59,
                "reach": [
                    {
                        "stage": "last 32",
                        "reach_pct": 100
                    },
                    {
                        "stage": "last 16",
                        "reach_pct": 85.59
                    }
                ],
                "went_out_at": "quarter-finals"
            },
            {
                "player_id": "pl_PMAW5J",
                "name": "Luke Humphries",
                "rating": 2319,
                "title_pct": 19.58,
                "fair_odds": 5.11,
                "reach": [
                    {
                        "stage": "last 32",
                        "reach_pct": 100
                    },
                    {
                        "stage": "last 16",
                        "reach_pct": 77.1
                    }
                ],
                "went_out_at": "last 16"
            }
        ]
    },
    "meta": {
        "plan": "analyst",
        "exact": true,
        "model": {
            "ratings_as_of": "2026-09-30",
            "length_effect": {
                "baseline_race": 6,
                "gamma": 0,
                "verdict": "No length adjustment beat the rating alone, so every format gets the rating's own probability."
            },
            "log_loss": {
                "chosen": 0.58968,
                "rating_alone": 0.58968
            },
            "how": "The rating's probability, adjusted for the length of the format only as far as the archive shows length matters, then turned into a per-leg chance to give scores and legs."
        },
        "how": "The draw is recovered from the results, tracing the champion back through every match. Each match is priced at the length it was actually played, from the ratings each player carried into the edition, so nothing learned during it is used.",
        "data_as_of": "2026-09-30T18:38:31Z"
    }
}
```

#### `POST /v1/simulate/bracket` (Analyst)

Simulate bracket. The same calculation over a draw the caller supplies, so outrights exist before a draw reaches the archive.

Plans: Analyst. Page: https://dartsapi.com/documentation/endpoints/simulate-bracket

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `body` | body | json | yes | A JSON body: draw is a list of player ids in draw order, a power of two long, with null for a bye; format or rounds give the match length. |

Errors: 401 `no_key`, `bad_key`; 402 `upgrade_required`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

```json
{
    "data": {
        "field": 8,
        "rounds": [
            {
                "stage": "quarter-finals",
                "format": "First to 6 legs"
            },
            {
                "stage": "semi-finals",
                "format": "First to 7 legs"
            }
        ],
        "players": [
            {
                "player_id": "pl_VEB8HM",
                "name": "Luke Littler",
                "rating": 2415.6,
                "title_pct": 42.27,
                "fair_odds": 2.37,
                "reach": [
                    {
                        "stage": "quarter-finals",
                        "reach_pct": 100
                    },
                    {
                        "stage": "semi-finals",
                        "reach_pct": 79.97
                    }
                ]
            },
            {
                "player_id": "pl_PMAW5J",
                "name": "Luke Humphries",
                "rating": 2312.4,
                "title_pct": 18.8,
                "fair_odds": 5.32,
                "reach": [
                    {
                        "stage": "quarter-finals",
                        "reach_pct": 100
                    },
                    {
                        "stage": "semi-finals",
                        "reach_pct": 65.68
                    }
                ]
            }
        ]
    },
    "meta": {
        "plan": "analyst",
        "exact": true,
        "ratings_as_of": "2026-09-30",
        "model": {
            "ratings_as_of": "2026-09-30",
            "length_effect": {
                "baseline_race": 6,
                "gamma": 0,
                "verdict": "No length adjustment beat the rating alone, so every format gets the rating's own probability."
            },
            "log_loss": {
                "chosen": 0.58968,
                "rating_alone": 0.58968
            },
            "how": "The rating's probability, adjusted for the length of the format only as far as the archive shows length matters, then turned into a per-leg chance to give scores and legs."
        },
        "how": "Worked exactly through the draw from the current ratings: every node holds each player's chance of coming out of it, so no simulation is needed.",
        "data_as_of": "2026-09-30T18:38:31Z"
    }
}
```

### Players

Every player, their record, form, splits, scoring and rating.

#### `GET /v1/players`

Players. Search and list, with accents and particles folded.

Plans: Free key, Live, Archive, Complete, Analyst. Page: https://dartsapi.com/documentation/endpoints/players

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `q` | query | string | no | Search text. Accents and particles are folded, so "van gerwen" finds Michael van Gerwen. |
| `country_code` | query | string | no | An ISO 3166 country code, lower case, such as nl or de; the home nations are gb-eng, gb-sct, gb-wls and gb-nir. |
| `active` | query | bool | no | true for players who played this year or last; false for the rest. |
| `limit` | query | int | no | How many to return. Default 50, at most 200. |
| `page` | query | int | no | A page number, for a pager in a UI. Use this or cursor, not both. |
| `cursor` | query | cursor | no | Carry on from here: pass back meta.next_cursor exactly as it came. |

Errors: 401 `no_key`, `bad_key`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

```json
{
    "data": [
        {
            "player_id": "pl_60FSJP",
            "name": "Keenan Littler",
            "country_code": "za",
            "first_year": 2023,
            "last_year": 2025,
            "matches": 37
        },
        {
            "player_id": "pl_0A1EQ8",
            "name": "Leon Littler",
            "country_code": null,
            "first_year": 2019,
            "last_year": 2019,
            "matches": 16
        }
    ],
    "meta": {
        "count": 2,
        "next_cursor": "c_m8dKmBUIJ_00smsXiWLW",
        "plan": "analyst",
        "window": "everything, including the model endpoints",
        "data_as_of": "2026-09-30T18:38:38Z"
    }
}
```

#### `GET /v1/players/{id}`

A player. Profile.

Plans: Free key, Live, Archive, Complete, Analyst. Page: https://dartsapi.com/documentation/endpoints/player

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `player_id` | path | id | yes | A player, as pl_ followed by six characters. |

Errors: 401 `no_key`, `bad_key`; 404 `not_found`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

```json
{
    "data": {
        "player_id": "pl_VEB8HM",
        "name": "Luke Littler",
        "country_code": "gb-eng",
        "first_year": 2019,
        "last_year": 2026,
        "matches": null,
        "record": {
            "matches": 1066,
            "won": 872,
            "lost": 194,
            "win_pct": 81.8,
            "first_match": "2019-01-12",
            "last_match": "2026-09-20"
        }
    },
    "meta": {
        "plan": "analyst",
        "window": "everything, including the model endpoints",
        "data_as_of": "2026-09-30T18:38:38Z"
    }
}
```

#### `GET /v1/players/{id}/matches` (paid plans)

Player matches. Match log with the market and rating beside every result.

Plans: Live, Archive, Complete, Analyst. Page: https://dartsapi.com/documentation/endpoints/player-matches

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `player_id` | path | id | yes | A player, as pl_ followed by six characters. |
| `from` | query | date | no | Earliest date to include, YYYY-MM-DD. |
| `to` | query | date | no | Latest date to include, YYYY-MM-DD. |
| `competition_id` | query | id | no | Only matches in this competition. |
| `limit` | query | int | no | How many to return. Default 50, at most 200. |
| `cursor` | query | cursor | no | Carry on from here: pass back meta.next_cursor exactly as it came. |

Errors: 401 `no_key`, `bad_key`; 402 `upgrade_required`; 404 `not_found`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

```json
{
    "data": [
        {
            "match_id": "mt_0CWS66BSK1H725020W3E",
            "played_on": "2026-09-20",
            "round": "quarter_final",
            "winner": {
                "player_id": "pl_NWEKMD",
                "name": "Jonny Clayton",
                "score": 10
            },
            "loser": {
                "player_id": "pl_VEB8HM",
                "name": "Luke Littler",
                "score": 4
            },
            "event": {
                "event_id": "ev_FTY24C",
                "competition_id": "cp_X645YM",
                "name": "World Series of Darts Finals",
                "date": "2026-09-20",
                "tier": "majors"
            },
            "result": "lost"
        },
        {
            "match_id": "mt_035G2W0G8FVGH0PPB5XD",
            "played_on": "2026-09-19",
            "round": "last_16",
            "winner": {
                "player_id": "pl_VEB8HM",
                "name": "Luke Littler",
                "score": 10
            },
            "loser": {
                "player_id": "pl_RNBEW9",
                "name": "Nathan Aspinall",
                "score": 9
            },
            "event": {
                "event_id": "ev_FTY24C",
                "competition_id": "cp_X645YM",
                "name": "World Series of Darts Finals",
                "date": "2026-09-20",
                "tier": "majors"
            },
            "result": "won"
        }
    ],
    "meta": {
        "count": 2,
        "next_cursor": "c_wNtb1hAe7JeTmTE0b7_JOxd-O_9qjVH0ImWP2tfhAvAT-UQ",
        "plan": "analyst",
        "window": "everything, including the model endpoints",
        "data_as_of": "2026-09-30T18:38:38Z"
    }
}
```

#### `GET /v1/players/{id}/form` (paid plans)

Player form. Recent form measured against expectation.

Plans: Live, Archive, Complete, Analyst. Page: https://dartsapi.com/documentation/endpoints/player-form

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `player_id` | path | id | yes | A player, as pl_ followed by six characters. |
| `matches` | query | int | no | How many recent matches to measure form over: 5 to 100, default 20. |

Errors: 401 `no_key`, `bad_key`; 402 `upgrade_required`; 404 `not_found`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

```json
{
    "data": {
        "player_id": "pl_VEB8HM",
        "over": "20 matches",
        "won": 17,
        "lost": 3,
        "win_pct": 85,
        "legs": {
            "for": 134,
            "against": 86,
            "difference": 48
        },
        "three_dart_avg": 100.07,
        "run": "LWWWWWWWLWWWWWWWLWWW",
        "from": "2026-07-26",
        "to": "2026-09-20"
    },
    "meta": {
        "plan": "analyst",
        "window": "everything, including the model endpoints",
        "data_as_of": "2026-09-30T18:38:38Z"
    }
}
```

#### `GET /v1/players/{id}/splits` (paid plans)

Player splits. Record split by tier, format length, year, price band or competition. Every row carries A/E and level-stakes P/L at best price.

Plans: Live, Archive, Complete, Analyst. Page: https://dartsapi.com/documentation/endpoints/player-splits

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `player_id` | path | id | yes | A player, as pl_ followed by six characters. |
| `by` | query | enum | no | Split the record by year, tier, race_to or round. Leave it out for year, tier and race_to together. |
| `from` | query | date | no | Earliest date to include, YYYY-MM-DD. |
| `to` | query | date | no | Latest date to include, YYYY-MM-DD. |

Errors: 401 `no_key`, `bad_key`; 402 `upgrade_required`; 404 `not_found`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

```json
{
    "data": {
        "player_id": "pl_VEB8HM",
        "splits": {
            "tier": [
                {
                    "key": "regional",
                    "label": "Regional and affiliate events",
                    "matches": 290,
                    "won": 240,
                    "lost": 50,
                    "win_pct": 82.8,
                    "legs": {
                        "for": 1077,
                        "against": 531,
                        "difference": 546
                    },
                    "three_dart_avg": 88.99,
                    "competitions": [
                        {
                            "name": "MODUS Super Series",
                            "matches": 110
                        },
                        {
                            "name": "JDC Advanced Tour",
                            "matches": 105
                        }
                    ]
                },
                {
                    "key": "tour_other",
                    "label": "Other tour events",
                    "matches": 200,
                    "won": 158,
                    "lost": 42,
                    "win_pct": 79,
                    "legs": {
                        "for": 1140,
                        "against": 776,
                        "difference": 364
                    },
                    "three_dart_avg": 100.76,
                    "competitions": [
                        {
                            "name": "Premier League",
                            "matches": 112
                        },
                        {
                            "name": "World Series of Darts",
                            "matches": 37
                        }
                    ]
                }
            ]
        }
    },
    "meta": {
        "plan": "analyst",
        "window": "everything, including the model endpoints",
        "race_to": "The winning score of each match. For set-play formats it counts sets, not legs.",
        "data_as_of": "2026-09-30T18:38:38Z"
    }
}
```

#### `GET /v1/players/{id}/scoring` (paid plans)

Player scoring. Scoring and finishing profile.

Plans: Live, Archive, Complete, Analyst. Page: https://dartsapi.com/documentation/endpoints/player-scoring

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `player_id` | path | id | yes | A player, as pl_ followed by six characters. |
| `from` | query | date | no | Earliest date to include, YYYY-MM-DD. |
| `to` | query | date | no | Latest date to include, YYYY-MM-DD. |

Errors: 401 `no_key`, `bad_key`; 402 `upgrade_required`; 404 `not_found`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

```json
{
    "data": {
        "player_id": "pl_VEB8HM",
        "matches_with_figures": 1055,
        "from": "2019-01-12",
        "to": "2026-09-06",
        "statistics": {
            "scoring": {
                "three_dart_avg": {
                    "value": 93.91,
                    "matches": 1055
                },
                "first_9_avg": {
                    "value": 104.76,
                    "matches": 963
                },
                "first_3_avg": {
                    "value": 104.58,
                    "matches": 964
                },
                "avg_with_throw": {
                    "value": 92.96,
                    "matches": 964
                },
                "avg_vs_throw": {
                    "value": 95.65,
                    "matches": 964
                }
            },
            "big_scores": {
                "count_180": {
                    "total": 3118,
                    "per_match": 2.96,
                    "matches": 1055
                },
                "visits_171_180": {
                    "total": 3285,
                    "per_match": 3.41,
                    "matches": 964
                },
                "visits_140": {
                    "total": 4505,
                    "per_match": 4.27,
                    "matches": 1056
                },
                "visits_131_140": {
                    "total": 6997,
                    "per_match": 7.26,
                    "matches": 964
                }
            },
            "finishing": {
                "checkout_pct": {
                    "value": 42.58,
                    "matches": 1055
                },
                "highest_checkout": {
                    "best": 170,
                    "matches": 1055
                },
                "functional_doubles": {
                    "value": 53.28,
                    "matches": 901
                }
            },
            "legs": {
                "legs_won_pct": {
                    "value": 67.65,
                    "matches": 1056
                },
                "won_on_throw_pct": {
                    "value": 77.84,
                    "matches": 963
                },
                "won_vs_throw_pct": {
                    "value": 57.66,
                    "matches": 963
                }
            }
        },
        "records": {
            "best_match_avg": 122.96,
            "lowest_match_avg": 54,
            "darts_thrown": 127294
        }
    },
    "meta": {
        "plan": "analyst",
        "window": "everything, including the model endpoints",
        "how": "Averages and percentages are the mean of each match's figure; counts are summed and given per match; highest_checkout is the best single match.",
        "data_as_of": "2026-09-30T18:38:38Z"
    }
}
```

#### `GET /v1/players/{id}/ratings` (paid plans)

Player ratings. Rating history.

Plans: Live, Archive, Complete, Analyst. Page: https://dartsapi.com/documentation/endpoints/player-ratings

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `player_id` | path | id | yes | A player, as pl_ followed by six characters. |
| `from` | query | date | no | Earliest date to include, YYYY-MM-DD. |
| `to` | query | date | no | Latest date to include, YYYY-MM-DD. |

Errors: 401 `no_key`, `bad_key`; 402 `upgrade_required`; 404 `not_found`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

```json
{
    "data": {
        "player": {
            "player_id": "pl_VEB8HM",
            "name": "Luke Littler",
            "country_code": "gb-eng",
            "rating": 2415.6,
            "change_30d": 8.5,
            "matches": 1066,
            "last_match": "2026-09-20",
            "peak": {
                "rating": 2438.5,
                "on": "2026-05-07"
            }
        },
        "provisional": false,
        "history": [
            {
                "match_id": "mt_19RDBD5DHG09G6C5YP58",
                "played_on": "2025-10-07",
                "result": "won",
                "opponent_id": "pl_47SWAC",
                "before": 2322,
                "after": 2330.1,
                "change": 8.1
            },
            {
                "match_id": "mt_02F7V92M5HER1MGVGY5F",
                "played_on": "2025-10-07",
                "result": "won",
                "opponent_id": "pl_EWH24M",
                "before": 2330.1,
                "after": 2338.5,
                "change": 8.4
            }
        ]
    },
    "meta": {
        "count": 137,
        "capped_at": 1000,
        "plan": "analyst",
        "window": "everything, including the model endpoints",
        "data_as_of": "2026-09-30T18:38:38Z"
    }
}
```

#### `GET /v1/head-to-head`

Head to head. A full rivalry.

Plans: Free key, Live, Archive, Complete, Analyst. Page: https://dartsapi.com/documentation/endpoints/head-to-head

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `player_id` | query | id | no | A player, as pl_ followed by six characters. |
| `opponent_id` | query | id | no | The other player, as pl_ followed by six characters. |
| `from` | query | date | no | Earliest date to include, YYYY-MM-DD. |
| `to` | query | date | no | Latest date to include, YYYY-MM-DD. |

Errors: 401 `no_key`, `bad_key`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

```json
{
    "data": {
        "players": [
            {
                "player_id": "pl_VEB8HM",
                "name": "Luke Littler",
                "wins": 24,
                "legs": 239
            },
            {
                "player_id": "pl_PMAW5J",
                "name": "Luke Humphries",
                "wins": 15,
                "legs": 217
            }
        ],
        "meetings": 39,
        "first_meeting": "2024-01-03",
        "last_meeting": "2026-09-06",
        "matches": [
            {
                "match_id": "mt_085F4YW2FH0RXX98F6TD",
                "played_on": "2026-09-06",
                "round": "final",
                "winner": {
                    "player_id": "pl_VEB8HM",
                    "name": "Luke Littler",
                    "score": 8
                },
                "loser": {
                    "player_id": "pl_PMAW5J",
                    "name": "Luke Humphries",
                    "score": 6
                },
                "event": {
                    "event_id": "ev_15WNS6",
                    "competition_id": "cp_2YJ4TA",
                    "name": "European Tour",
                    "date": "2026-09-06",
                    "tier": "european_tour"
                }
            },
            {
                "match_id": "mt_1VJRZXN584YBD4QP08DM",
                "played_on": "2026-06-26",
                "round": "final",
                "winner": {
                    "player_id": "pl_PMAW5J",
                    "name": "Luke Humphries",
                    "score": 8
                },
                "loser": {
                    "player_id": "pl_VEB8HM",
                    "name": "Luke Littler",
                    "score": 7
                },
                "event": {
                    "event_id": "ev_JCT7FZ",
                    "competition_id": "cp_GE7BFK",
                    "name": "World Series of Darts",
                    "date": "2026-06-26",
                    "tier": "world_series"
                }
            }
        ]
    },
    "meta": {
        "count": 39,
        "plan": "analyst",
        "window": "everything, including the model endpoints",
        "data_as_of": "2026-09-30T18:38:38Z"
    }
}
```

### Matches

Fixtures, results, live scores and everything held about one match.

#### `GET /v1/fixtures`

Fixtures. Upcoming matches, with the best price only where one was held: no live prices are held since 20 March 2026.

Plans: Free key, Live, Archive, Complete, Analyst. Page: https://dartsapi.com/documentation/endpoints/fixtures

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `from` | query | date | no | Earliest fixture date to include. |
| `to` | query | date | no | Latest fixture date to include. |
| `competition_id` | query | id | no | A competition, as cp_ followed by six characters. |
| `player_id` | query | id | no | A player, as pl_ followed by six characters. |
| `limit` | query | int | no | How many to return. Default 100, at most 500. |
| `cursor` | query | cursor | no | Carry on from here: pass back meta.next_cursor exactly as it came. |

Errors: 401 `no_key`, `bad_key`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

```json
{
    "data": [
        {
            "fixture_id": "fx_f9ca28d20999df4e",
            "competition": "",
            "round": null,
            "date": "2026-09-30",
            "date_confirmed": false,
            "starts_at": "2026-09-30T19:00:00Z",
            "players": [
                {
                    "player_id": "pl_YERQEQ",
                    "name": "Danny Noppert",
                    "known": true
                },
                {
                    "player_id": "pl_KZWF7B",
                    "name": "Ryan Joyce",
                    "known": true
                }
            ],
            "price": null
        },
        {
            "fixture_id": "fx_01f0fa053b7d6e6b",
            "competition": "World Grand Prix 2026",
            "round": "last_16",
            "date": "2026-09-30",
            "date_confirmed": false,
            "starts_at": "2026-09-30T19:00:00Z",
            "players": [
                {
                    "player_id": "pl_YERQEQ",
                    "name": "Danny Noppert",
                    "known": true
                },
                {
                    "player_id": "pl_KZWF7B",
                    "name": "Ryan Joyce",
                    "known": true
                }
            ],
            "price": null
        }
    ],
    "meta": {
        "plan": "analyst",
        "count": 2,
        "total": 8,
        "next_cursor": "c_d28vce_d3b85f5b",
        "freshness": {
            "captured_at": "2026-09-30T18:35:06Z",
            "age_seconds": 214,
            "refreshed": "every 5 minutes",
            "behind": false
        },
        "notes": [
            "starts_at is UTC, and null where the order of play gives no time yet. A date marked unconfirmed is not yet fixed by the organiser.",
            "price is empty until live prices are collected again; /v1/probability prices any fixture whose players are both known."
        ],
        "data_as_of": "2026-09-30T18:38:38Z"
    }
}
```

#### `GET /v1/results`

Results. Settled matches.

Plans: Free key, Live, Archive, Complete, Analyst. Page: https://dartsapi.com/documentation/endpoints/results

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `from` | query | date | no | Earliest date to include, YYYY-MM-DD. |
| `to` | query | date | no | Latest date to include, YYYY-MM-DD. |
| `competition_id` | query | id | no | Only matches in this competition. |
| `player_id` | query | id | no | Only matches this player played. |
| `limit` | query | int | no | How many to return. Default 50, at most 200. |
| `page` | query | int | no | A page number, for a pager in a UI. Use this or cursor, not both. |
| `cursor` | query | cursor | no | Carry on from here: pass back meta.next_cursor exactly as it came. |

Errors: 401 `no_key`, `bad_key`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

```json
{
    "data": [
        {
            "match_id": "mt_0CWS66BSK1H725020W3E",
            "played_on": "2026-09-20",
            "round": "quarter_final",
            "winner": {
                "player_id": "pl_NWEKMD",
                "name": "Jonny Clayton",
                "score": 10
            },
            "loser": {
                "player_id": "pl_VEB8HM",
                "name": "Luke Littler",
                "score": 4
            },
            "event": {
                "event_id": "ev_FTY24C",
                "competition_id": "cp_X645YM",
                "name": "World Series of Darts Finals",
                "date": "2026-09-20",
                "tier": "majors"
            }
        },
        {
            "match_id": "mt_035G2W0G8FVGH0PPB5XD",
            "played_on": "2026-09-19",
            "round": "last_16",
            "winner": {
                "player_id": "pl_VEB8HM",
                "name": "Luke Littler",
                "score": 10
            },
            "loser": {
                "player_id": "pl_RNBEW9",
                "name": "Nathan Aspinall",
                "score": 9
            },
            "event": {
                "event_id": "ev_FTY24C",
                "competition_id": "cp_X645YM",
                "name": "World Series of Darts Finals",
                "date": "2026-09-20",
                "tier": "majors"
            }
        }
    ],
    "meta": {
        "count": 2,
        "next_cursor": "c_wNtb1hAe7JeTmTE0b7_JOxd-O_9qjVH0ImWP2tfhAvAT-UQ",
        "plan": "analyst",
        "window": "everything, including the model endpoints",
        "data_as_of": "2026-09-30T18:38:38Z"
    }
}
```

#### `GET /v1/results/yesterday`

Yesterday. Every match settled yesterday, UTC, on every plan including the free key.

Plans: Free key, Live, Archive, Complete, Analyst. Page: https://dartsapi.com/documentation/endpoints/results-yesterday

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `competition_id` | query | id | no | Only matches in this competition. |
| `player_id` | query | id | no | Only matches this player played. |
| `limit` | query | int | no | How many to return. Default 50, at most 200. |
| `cursor` | query | cursor | no | Carry on from here: pass back meta.next_cursor exactly as it came. |

Errors: 401 `no_key`, `bad_key`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

```json
{
    "data": [
        {
            "match_id": "mt_1TBCSWQVAGYETS5N1WK5",
            "played_on": "2026-09-29",
            "round": "last_32",
            "winner": {
                "player_id": "pl_EWH24M",
                "name": "Gian van Veen",
                "score": 2
            },
            "loser": {
                "player_id": "pl_0886SR",
                "name": "Dirk van Duijvenbode",
                "score": 0
            },
            "event": {
                "event_id": "ev_0ATG2W",
                "competition_id": "cp_7B1KJZ",
                "name": "World Grand Prix",
                "date": "2026-10-04",
                "tier": "tour_other"
            }
        },
        {
            "match_id": "mt_0MDDYQ445TWCY1KQ7E5C",
            "played_on": "2026-09-29",
            "round": "round_robin",
            "winner": {
                "player_id": "pl_HCKF7Z",
                "name": "Jim Widmayer",
                "score": 4
            },
            "loser": {
                "player_id": "pl_6M913B",
                "name": "Jamie Atkins",
                "score": 3
            },
            "event": {
                "event_id": "ev_H1H9W3",
                "competition_id": "cp_2WREDF",
                "name": "MODUS Super Series #15 Week",
                "date": "2026-10-03",
                "tier": "regional"
            }
        }
    ],
    "meta": {
        "count": 2,
        "date": "2026-09-29",
        "next_cursor": "c_JC_-22FVO0n56c0FrbQstb6rsxBbvBhVrcKJeDQzGSBCyw8",
        "plan": "analyst",
        "window": "yesterday, UTC, on every plan",
        "data_as_of": "2026-09-30T18:38:38Z"
    }
}
```

#### `GET /v1/live` (paid plans)

Live. Matches in play, with freshness reported explicitly.

Plans: Live, Complete, Analyst. Page: https://dartsapi.com/documentation/endpoints/live

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `competition_id` | query | id | no | Only matches in this competition. |

Errors: 401 `no_key`, `bad_key`; 402 `upgrade_required`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

```json
{
    "data": [],
    "meta": {
        "plan": "analyst",
        "count": 0,
        "freshness": {
            "captured_at": "2026-09-30T18:35:06Z",
            "age_seconds": 214,
            "refreshed": "every 5 minutes",
            "behind": false
        },
        "notes": [
            "Scores as of the snapshot time in freshness.captured_at, which is refreshed every 5 minutes: a score here can be a few minutes behind the board.",
            "Nothing is in play right now."
        ],
        "data_as_of": "2026-09-30T18:38:38Z"
    }
}
```

#### `GET /v1/matches/{id}` (paid plans)

A match. The full record.

Plans: Live, Archive, Complete, Analyst. Page: https://dartsapi.com/documentation/endpoints/match

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `match_id` | path | id | yes | A match, as mt_ followed by six characters. |

Errors: 401 `no_key`, `bad_key`; 402 `upgrade_required`; 404 `not_found`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

```json
{
    "data": {
        "match_id": "mt_1MW2NW9SQ8JZ9HP9M6JE",
        "played_on": "2026-09-06",
        "round": "semi_final",
        "winner": {
            "player_id": "pl_VEB8HM",
            "name": "Luke Littler",
            "score": 7
        },
        "loser": {
            "player_id": "pl_8HN4TH",
            "name": "Michael van Gerwen",
            "score": 3
        },
        "event": {
            "event_id": "ev_15WNS6",
            "competition_id": "cp_2YJ4TA",
            "name": "European Tour",
            "date": "2026-09-06",
            "tier": "european_tour"
        },
        "statistics_held": true
    },
    "meta": {
        "plan": "analyst",
        "window": "everything, including the model endpoints",
        "data_as_of": "2026-09-30T18:38:38Z"
    }
}
```

#### `GET /v1/matches/{id}/preview` (paid plans)

Match preview. The one call a preview writer needs.

Plans: Live, Archive, Complete, Analyst. Page: https://dartsapi.com/documentation/endpoints/match-preview

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `match_id` | path | id | yes | A match, as mt_ followed by six characters. |

Errors: 401 `no_key`, `bad_key`; 402 `upgrade_required`; 404 `not_found`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

```json
{
    "data": {
        "match": {
            "match_id": "mt_1MW2NW9SQ8JZ9HP9M6JE",
            "played_on": "2026-09-06",
            "round": "semi_final",
            "winner": {
                "player_id": "pl_VEB8HM",
                "name": "Luke Littler",
                "score": 7
            },
            "loser": {
                "player_id": "pl_8HN4TH",
                "name": "Michael van Gerwen",
                "score": 3
            },
            "event": {
                "event_id": "ev_15WNS6",
                "competition_id": "cp_2YJ4TA",
                "name": "European Tour",
                "date": "2026-09-06",
                "tier": "european_tour"
            }
        },
        "as_of": "2026-09-06",
        "players": [
            {
                "player_id": "pl_VEB8HM",
                "name": "Luke Littler",
                "country_code": "gb-eng",
                "rating_before": 2409.3,
                "form": {
                    "last": 10,
                    "run": "WLWWWWWWWL",
                    "won": 8,
                    "lost": 2,
                    "win_pct": 80
                },
                "last_12_months": {
                    "matches_with_figures": 140,
                    "three_dart_avg": 101.04,
                    "count_180_per_match": 5.31,
                    "checkout_pct": 47
                }
            },
            {
                "player_id": "pl_8HN4TH",
                "name": "Michael van Gerwen",
                "country_code": "nl",
                "rating_before": 2124.3,
                "form": {
                    "last": 10,
                    "run": "WLWWLWLLWW",
                    "won": 6,
                    "lost": 4,
                    "win_pct": 60
                },
                "last_12_months": {
                    "matches_with_figures": 136,
                    "three_dart_avg": 97.15,
                    "count_180_per_match": 3.13,
                    "checkout_pct": 40.51
                }
            }
        ],
        "head_to_head": {
            "meetings": 27,
            "wins": {
                "pl_VEB8HM": 17,
                "pl_8HN4TH": 10
            },
            "last": {
                "match_id": "mt_0TN6WK3K2QH55GR122K8",
                "played_on": "2026-05-07",
                "round": "weekly_quarter_final",
                "winner": {
                    "player_id": "pl_VEB8HM",
                    "name": "Luke Littler",
                    "score": 6
                },
                "loser": {
                    "player_id": "pl_8HN4TH",
                    "name": "Michael van Gerwen",
                    "score": 5
                },
                "event": {
                    "event_id": "ev_AANAFE",
                    "competition_id": "cp_ATC49K",
                    "name": "Premier League",
                    "date": "2026-05-28",
                    "tier": "tour_other"
                }
            }
        },
        "rating_edge": {
            "favourite": "pl_VEB8HM",
            "expected_pct": 83.8,
            "how": "From the two ratings as they stood before the match. Format-aware probability is on /v1/matches/{id}/probability."
        }
    },
    "meta": {
        "plan": "analyst",
        "measured": "everything in this preview stops the day before the match was played",
        "data_as_of": "2026-09-30T18:38:38Z"
    }
}
```

#### `GET /v1/matches/{id}/statistics` (paid plans)

Match statistics. Per-player statistics, on the detail route only, never on lists.

Plans: Live, Archive, Complete, Analyst. Page: https://dartsapi.com/documentation/endpoints/match-statistics

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `match_id` | path | id | yes | A match, as mt_ followed by six characters. |

Errors: 401 `no_key`, `bad_key`; 402 `upgrade_required`; 404 `not_found`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

```json
{
    "data": {
        "players": [
            {
                "player_id": "pl_VEB8HM",
                "name": "Luke Littler",
                "statistics": {
                    "scoring": {
                        "three_dart_avg": 106.64,
                        "first_9_avg": 119.03,
                        "first_3_avg": 110.2,
                        "avg_with_throw": 115.62,
                        "avg_vs_throw": 98.54
                    },
                    "big_scores": {
                        "count_180": 6,
                        "visits_171_180": 6,
                        "visits_140": 5,
                        "visits_131_140": 11
                    },
                    "finishing": {
                        "checkout_pct": 46.67,
                        "highest_checkout": 167,
                        "functional_doubles": 50
                    },
                    "legs": {
                        "legs_won_pct": 70,
                        "won_on_throw_pct": 100,
                        "won_vs_throw_pct": 40
                    }
                }
            },
            {
                "player_id": "pl_8HN4TH",
                "name": "Michael van Gerwen",
                "statistics": {
                    "scoring": {
                        "three_dart_avg": 83.53,
                        "first_9_avg": 86.07,
                        "first_3_avg": 106.3,
                        "avg_with_throw": 80.05,
                        "avg_vs_throw": 88.61
                    },
                    "big_scores": {
                        "count_180": 2,
                        "visits_171_180": 3,
                        "visits_140": 4,
                        "visits_131_140": 5
                    },
                    "finishing": {
                        "checkout_pct": 30,
                        "highest_checkout": 62,
                        "functional_doubles": 33.33
                    },
                    "legs": {
                        "legs_won_pct": 30,
                        "won_on_throw_pct": 60,
                        "won_vs_throw_pct": 0
                    }
                }
            }
        ]
    },
    "meta": {
        "count": 2,
        "plan": "analyst",
        "data_as_of": "2026-09-30T18:38:38Z"
    }
}
```

#### `GET /v1/matches/{id}/prices` (paid plans)

Match prices. Every reading held, for every market held. Prices are history: held from 2016 to 20 March 2026, with no live prices since.

Plans: Live, Archive, Complete, Analyst. Page: https://dartsapi.com/documentation/endpoints/match-prices

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `match_id` | path | id | yes | A match, as mt_ followed by six characters. |
| `market` | query | enum | no | match_winner, the one market held for darts. |

Errors: 401 `no_key`, `bad_key`; 402 `upgrade_required`; 404 `not_found`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

```json
{
    "data": {
        "match": {
            "match_id": "mt_1WPYX3K955Y1R2BZBNKP",
            "played_on": "2026-03-20",
            "round": "last_48",
            "winner": {
                "player_id": "pl_ZDYYD1",
                "name": "Boris Krčmar",
                "score": 6
            },
            "loser": {
                "player_id": "pl_X29RN1",
                "name": "Raymond van Barneveld",
                "score": 1
            },
            "event": {
                "event_id": "ev_MX0A6T",
                "competition_id": "cp_2YJ4TA",
                "name": "European Tour",
                "date": "2026-03-22",
                "tier": "european_tour"
            }
        },
        "starts_at": "2026-03-20T20:00:00Z",
        "readings": [
            {
                "taken_at": "2026-03-20T17:17:59Z",
                "before_start": true,
                "decimal": {
                    "pl_ZDYYD1": 1.58,
                    "pl_X29RN1": 2.58
                },
                "implied_pct": {
                    "pl_ZDYYD1": 62.02,
                    "pl_X29RN1": 37.98
                },
                "book_pct": 102.05,
                "best_from": {
                    "pl_ZDYYD1": "cashwin",
                    "pl_X29RN1": "pinnacle"
                },
                "the_price": true
            }
        ]
    },
    "meta": {
        "plan": "analyst",
        "window": "everything, including the model endpoints",
        "market": "match_winner",
        "prices": "The best price across bookmakers at the last reading before the start, or the first reading after it where none came before. A best-of-market price: not one bookmaker's line and not a closing line.",
        "odds_archive": {
            "priced_matches": 10222,
            "first": "2016-01-03",
            "last": "2026-03-20"
        },
        "count": 1,
        "note": "the_price marks the reading every other endpoint uses for this match.",
        "data_as_of": "2026-09-30T18:38:38Z"
    }
}
```

### Ratings

The table, as it stands and as it stood on any date.

#### `GET /v1/ratings` (paid plans)

Ratings. The current table.

Plans: Live, Archive, Complete, Analyst. Page: https://dartsapi.com/documentation/endpoints/ratings

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `limit` | query | int | no | How many to return. Default 50, at most 200. |
| `cursor` | query | cursor | no | Carry on from here: pass back meta.next_cursor exactly as it came. |

Errors: 401 `no_key`, `bad_key`; 402 `upgrade_required`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

```json
{
    "data": [
        {
            "rank": 1,
            "player_id": "pl_VEB8HM",
            "name": "Luke Littler",
            "country_code": "gb-eng",
            "rating": 2415.6,
            "change_30d": 8.5,
            "matches": 1066,
            "last_match": "2026-09-20",
            "peak": {
                "rating": 2438.5,
                "on": "2026-05-07"
            }
        },
        {
            "rank": 2,
            "player_id": "pl_PMAW5J",
            "name": "Luke Humphries",
            "country_code": "gb-eng",
            "rating": 2312.4,
            "change_30d": 9.7,
            "matches": 1355,
            "last_match": "2026-09-29",
            "peak": {
                "rating": 2338,
                "on": "2026-06-26"
            }
        }
    ],
    "meta": {
        "count": 3,
        "next_cursor": "c_4o0e8q_c5d102df",
        "active": "players with 20 or more matches who have played since 2025-09-30",
        "model": {
            "measured_on": 225550,
            "favourite_won_pct": 68,
            "brier": 0.2028,
            "by_gap": [
                {
                    "gap": "0-50",
                    "matches": 51045,
                    "expected_pct": 53.6,
                    "actual_pct": 53.4
                },
                {
                    "gap": "50-100",
                    "matches": 46788,
                    "expected_pct": 60.5,
                    "actual_pct": 60.4
                }
            ],
            "how": "Every match between two established players, predicted from the ratings as they stood before it was played."
        },
        "as_of": "2026-09-30",
        "plan": "analyst",
        "data_as_of": "2026-09-30T18:38:38Z"
    }
}
```

#### `GET /v1/ratings/snapshot` (Analyst)

Ratings snapshot. The table exactly as it stood on a date, built only from matches that started before it.

Plans: Analyst. Page: https://dartsapi.com/documentation/endpoints/ratings-snapshot

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `on` | query | date | no | The date to rebuild the table as of, YYYY-MM-DD. Only matches that started before it count. |
| `limit` | query | int | no | How many to return. Default 50, at most 200. |

Errors: 401 `no_key`, `bad_key`; 402 `upgrade_required`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

```json
{
    "data": [
        {
            "rank": 1,
            "player_id": "pl_VEB8HM",
            "name": "Luke Littler",
            "country_code": "gb-eng",
            "rating": 2268,
            "matches": 797,
            "last_match": "2025-01-01"
        },
        {
            "rank": 2,
            "player_id": "pl_PMAW5J",
            "name": "Luke Humphries",
            "country_code": "gb-eng",
            "rating": 2219.3,
            "matches": 1094,
            "last_match": "2024-12-29"
        }
    ],
    "meta": {
        "on": "2025-01-01",
        "active": "players with 20 or more matches who had played since 2024-01-02",
        "count": 3,
        "plan": "analyst",
        "data_as_of": "2026-09-30T18:38:38Z"
    }
}
```

#### `GET /v1/ratings/movers` (paid plans)

Ratings movers. Biggest risers and fallers.

Plans: Live, Archive, Complete, Analyst. Page: https://dartsapi.com/documentation/endpoints/ratings-movers

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `days` | query | int | no | How far back movement is measured, in days: 7 to 365, default 30. |
| `limit` | query | int | no | How many to return. Default 50, at most 200. |

Errors: 401 `no_key`, `bad_key`; 402 `upgrade_required`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

```json
{
    "data": {
        "span": {
            "days": 60,
            "from": "2026-08-01",
            "to": "2026-09-30"
        },
        "risers": [
            {
                "player_id": "pl_K45R32",
                "name": "Ron Leon Kolberg",
                "country_code": "de",
                "rating": 1714.4,
                "change_30d": 18.2,
                "matches": 80,
                "last_match": "2026-09-03",
                "peak": {
                    "rating": 1717.3,
                    "on": "2026-09-03"
                },
                "moved": 329.8,
                "matches_in_span": 61
            },
            {
                "player_id": "pl_DD6PD4",
                "name": "Soren Gobel",
                "country_code": null,
                "rating": 1777.8,
                "change_30d": 29.7,
                "matches": 37,
                "last_match": "2026-09-06",
                "peak": {
                    "rating": 1777.8,
                    "on": "2026-09-06"
                },
                "moved": 301.4,
                "matches_in_span": 31
            }
        ],
        "fallers": [
            {
                "player_id": "pl_R26FEJ",
                "name": "Dominik Borer",
                "country_code": "ch",
                "rating": 1192.8,
                "change_30d": -30.2,
                "matches": 29,
                "last_match": "2026-09-18",
                "peak": {
                    "rating": 1214.9,
                    "on": "2026-09-11"
                },
                "moved": -279.7,
                "matches_in_span": 26
            },
            {
                "player_id": "pl_DRSSJQ",
                "name": "Joel Rappo",
                "country_code": "ch",
                "rating": 1260,
                "change_30d": 0,
                "matches": 33,
                "last_match": "2026-08-26",
                "peak": {
                    "rating": 1305.7,
                    "on": "2026-08-13"
                },
                "moved": -218,
                "matches_in_span": 30
            }
        ]
    },
    "meta": {
        "counted": "established players with three or more matches in the span",
        "plan": "analyst",
        "data_as_of": "2026-09-30T18:38:43Z"
    }
}
```

### Markets

Closing prices, and how the market has done against what happened.

#### `GET /v1/prices/bulk` (paid plans)

Prices in bulk. Priced history in bulk for model builders. Prices are history: held from 2016 to 20 March 2026, with no live prices since.

Plans: Live, Archive, Complete, Analyst. Page: https://dartsapi.com/documentation/endpoints/prices-bulk

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `from` | query | date | no | Earliest date to include, YYYY-MM-DD. |
| `to` | query | date | no | Latest date to include, YYYY-MM-DD. |
| `market` | query | enum | no | match_winner, the one market held for darts. |
| `limit` | query | int | no | How many to return. Default 50, at most 200. |
| `cursor` | query | cursor | no | Carry on from here: pass back meta.next_cursor exactly as it came. |

Errors: 401 `no_key`, `bad_key`; 402 `upgrade_required`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

```json
{
    "data": [
        {
            "match": {
                "match_id": "mt_0HMAEKY1109KNWVSP02A",
                "played_on": "2026-03-20",
                "round": "last_48",
                "winner": {
                    "player_id": "pl_KZWF7B",
                    "name": "Ryan Joyce",
                    "score": 6
                },
                "loser": {
                    "player_id": "pl_KZ3YMS",
                    "name": "Adam Gawlas",
                    "score": 4
                },
                "event": {
                    "event_id": "ev_MX0A6T",
                    "competition_id": "cp_2YJ4TA",
                    "name": "European Tour",
                    "date": "2026-03-22",
                    "tier": "european_tour"
                }
            },
            "tier": {
                "key": "european_tour",
                "name": "European Tour"
            },
            "price": {
                "market": "match_winner",
                "taken_at": "2026-03-20T17:17:59Z",
                "reading": "first_after_start",
                "decimal": {
                    "pl_KZWF7B": 1.952,
                    "pl_KZ3YMS": 2
                },
                "implied_pct": {
                    "pl_KZWF7B": 50.61,
                    "pl_KZ3YMS": 49.39
                },
                "book_pct": 101.23
            },
            "favourite": "pl_KZWF7B",
            "favourite_won": true,
            "model": {
                "source": "ratings as they stood before the match",
                "win_pct": {
                    "pl_KZWF7B": 51.4,
                    "pl_KZ3YMS": 48.6
                }
            }
        },
        {
            "match": {
                "match_id": "mt_0PT10676KFQNRMGWPKEM",
                "played_on": "2026-03-20",
                "round": "last_48",
                "winner": {
                    "player_id": "pl_D0J15E",
                    "name": "Sebastian Bialecki",
                    "score": 6
                },
                "loser": {
                    "player_id": "pl_EYX327",
                    "name": "Wessel Nijman",
                    "score": 3
                },
                "event": {
                    "event_id": "ev_MX0A6T",
                    "competition_id": "cp_2YJ4TA",
                    "name": "European Tour",
                    "date": "2026-03-22",
                    "tier": "european_tour"
                }
            },
            "tier": {
                "key": "european_tour",
                "name": "European Tour"
            },
            "price": {
                "market": "match_winner",
                "taken_at": "2026-03-20T17:17:59Z",
                "reading": "last_before_start",
                "decimal": {
                    "pl_D0J15E": 4.5,
                    "pl_EYX327": 1.25
                },
                "implied_pct": {
                    "pl_D0J15E": 21.74,
                    "pl_EYX327": 78.26
                },
                "book_pct": 102.22
            },
            "favourite": "pl_EYX327",
            "favourite_won": false,
            "model": {
                "source": "ratings as they stood before the match",
                "win_pct": {
                    "pl_D0J15E": 18.74,
                    "pl_EYX327": 81.26
                }
            }
        }
    ],
    "meta": {
        "plan": "analyst",
        "window": "everything, including the model endpoints",
        "market": "match_winner",
        "prices": "The best price across bookmakers at the last reading before the start, or the first reading after it where none came before. A best-of-market price: not one bookmaker's line and not a closing line.",
        "odds_archive": {
            "priced_matches": 10222,
            "first": "2016-01-03",
            "last": "2026-03-20"
        },
        "count": 2,
        "next_cursor": "c_qVzCdZolj6DTCsn3ZYWQOLL-3Eo60lnNjrLou_KGgzc4OQU",
        "data_as_of": "2026-09-30T18:38:43Z"
    }
}
```

#### `GET /v1/markets/calibration` (paid plans)

Calibration. Implied probability against what actually happened, by price band. Prices are history: held from 2016 to 20 March 2026, with no live prices since.

Plans: Live, Archive, Complete, Analyst. Page: https://dartsapi.com/documentation/endpoints/markets-calibration

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `from` | query | date | no | Earliest date to include, YYYY-MM-DD. |
| `to` | query | date | no | Latest date to include, YYYY-MM-DD. |
| `bucket` | query | enum | no | The width of each price band in percentage points: 5 or 10. |
| `tier` | query | enum | no | Only this tier: majors, players_championship, european_tour, world_series, qualifiers, development_tour, challenge_tour, womens_series, junior, regional, wdf_platinum, wdf_gold, wdf_silver, wdf_bronze, and so on. |

Errors: 401 `no_key`, `bad_key`; 402 `upgrade_required`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

```json
{
    "data": {
        "bands": [
            {
                "band": "50-60",
                "matches": 3417,
                "implied_pct": 55.1,
                "actual_pct": 56,
                "difference": 0.9
            },
            {
                "band": "60-70",
                "matches": 3172,
                "implied_pct": 64.8,
                "actual_pct": 65.7,
                "difference": 0.9
            }
        ],
        "all": {
            "matches": 10171,
            "level_prices_left_out": 51,
            "favourite_won_pct": 67,
            "brier": 0.2098,
            "log_loss": 0.60609
        }
    },
    "meta": {
        "plan": "analyst",
        "window": "everything, including the model endpoints",
        "market": "match_winner",
        "prices": "The best price across bookmakers at the last reading before the start, or the first reading after it where none came before. A best-of-market price: not one bookmaker's line and not a closing line.",
        "odds_archive": {
            "priced_matches": 10222,
            "first": "2016-01-03",
            "last": "2026-03-20"
        },
        "bucket_points": 10,
        "tier": null,
        "how": "Each match read from the favourite's side: the market's chance, with the bookmakers' margin taken out, against how often the favourite actually won.",
        "data_as_of": "2026-09-30T18:38:43Z"
    }
}
```

#### `GET /v1/markets/favourites` (paid plans)

Favourites. Favourite win rate and level-stakes return by price and format. Prices are history: held from 2016 to 20 March 2026, with no live prices since.

Plans: Live, Archive, Complete, Analyst. Page: https://dartsapi.com/documentation/endpoints/markets-favourites

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `from` | query | date | no | Earliest date to include, YYYY-MM-DD. |
| `to` | query | date | no | Latest date to include, YYYY-MM-DD. |
| `tier` | query | enum | no | Only this tier: majors, players_championship, european_tour, world_series, qualifiers, development_tour, challenge_tour, womens_series, junior, regional, wdf_platinum, wdf_gold, wdf_silver, wdf_bronze, and so on. |

Errors: 401 `no_key`, `bad_key`; 402 `upgrade_required`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

```json
{
    "data": {
        "by_price": [
            {
                "band": "1 to 1.2",
                "matches": 1148,
                "implied_pct": 86.4,
                "won_pct": 87.7,
                "average_price": 1.12,
                "level_stakes_return_pct": -2
            },
            {
                "band": "1.2 to 1.4",
                "matches": 2408,
                "implied_pct": 74.8,
                "won_pct": 74,
                "average_price": 1.3,
                "level_stakes_return_pct": -4.2
            }
        ],
        "by_format": [
            {
                "band": "first to 1-3",
                "matches": 31,
                "implied_pct": 66.3,
                "won_pct": 71,
                "average_price": 1.5,
                "level_stakes_return_pct": 1.2
            },
            {
                "band": "first to 4-5",
                "matches": 791,
                "implied_pct": 67.5,
                "won_pct": 68.4,
                "average_price": 1.49,
                "level_stakes_return_pct": -1
            }
        ],
        "all": {
            "favourites": {
                "band": "every favourite",
                "matches": 10171,
                "implied_pct": 66.4,
                "won_pct": 67,
                "average_price": 1.51,
                "level_stakes_return_pct": -1.6
            },
            "outsiders": {
                "band": "every outsider",
                "matches": 10171,
                "implied_pct": 33.6,
                "won_pct": 33,
                "average_price": 3.48,
                "level_stakes_return_pct": -5.1
            }
        }
    },
    "meta": {
        "plan": "analyst",
        "window": "everything, including the model endpoints",
        "market": "match_winner",
        "prices": "The best price across bookmakers at the last reading before the start, or the first reading after it where none came before. A best-of-market price: not one bookmaker's line and not a closing line.",
        "odds_archive": {
            "priced_matches": 10222,
            "first": "2016-01-03",
            "last": "2026-03-20"
        },
        "tier": null,
        "returns": "Returns are level stakes at the best price across bookmakers, which flatters any approach compared with what one bookmaker would have paid.",
        "how": "Favourite bands are by the favourite's price. Format bands read the race from the winning score; set-play events are kept apart as sets.",
        "data_as_of": "2026-09-30T18:38:43Z"
    }
}
```

#### `GET /v1/markets/upsets` (paid plans)

Upsets. The longest-priced winners and upset rates. Prices are history: held from 2016 to 20 March 2026, with no live prices since.

Plans: Live, Archive, Complete, Analyst. Page: https://dartsapi.com/documentation/endpoints/markets-upsets

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `from` | query | date | no | Earliest date to include, YYYY-MM-DD. |
| `to` | query | date | no | Latest date to include, YYYY-MM-DD. |
| `min_price` | query | float | no | Only winners at this decimal price or longer. Default 3.0. |
| `limit` | query | int | no | How many to return. Default 50, at most 200. |

Errors: 401 `no_key`, `bad_key`; 402 `upgrade_required`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

```json
{
    "data": {
        "longest_priced_winners": [
            {
                "match": {
                    "match_id": "mt_0KEYXBX9AR3Z95VZXKN0",
                    "played_on": "2025-12-18",
                    "round": "last_128",
                    "winner": {
                        "player_id": "pl_705SC9",
                        "name": "David Munyua",
                        "score": 3
                    },
                    "loser": {
                        "player_id": "pl_GGFTQP",
                        "name": "Mike De Decker",
                        "score": 2
                    },
                    "event": {
                        "event_id": "ev_CBJAWE",
                        "competition_id": "cp_P0X9NS",
                        "name": "World Championship",
                        "date": "2026-01-03",
                        "tier": "tour_other"
                    }
                },
                "tier": {
                    "key": "tour_other",
                    "name": "Other tour events"
                },
                "price": {
                    "market": "match_winner",
                    "taken_at": "2026-03-20T17:36:27Z",
                    "reading": "first_after_start",
                    "decimal": {
                        "pl_705SC9": 17,
                        "pl_GGFTQP": 1.035
                    },
                    "implied_pct": {
                        "pl_705SC9": 5.74,
                        "pl_GGFTQP": 94.26
                    },
                    "book_pct": 102.5
                },
                "favourite": "pl_GGFTQP",
                "favourite_won": false
            },
            {
                "match": {
                    "match_id": "mt_03AG4PH63HJM85HV75NC",
                    "played_on": "2022-12-15",
                    "round": "last_96",
                    "winner": {
                        "player_id": "pl_P76KPC",
                        "name": "Grant Sampson",
                        "score": 3
                    },
                    "loser": {
                        "player_id": "pl_15JJZ0",
                        "name": "Keane Barry",
                        "score": 1
                    },
                    "event": {
                        "event_id": "ev_W315CK",
                        "competition_id": "cp_P0X9NS",
                        "name": "World Championship",
                        "date": "2023-01-03",
                        "tier": "tour_other"
                    }
                },
                "tier": {
                    "key": "tour_other",
                    "name": "Other tour events"
                },
                "price": {
                    "market": "match_winner",
                    "taken_at": "2026-03-20T17:36:43Z",
                    "reading": "first_after_start",
                    "decimal": {
                        "pl_P76KPC": 15.31,
                        "pl_15JJZ0": 1.1
                    },
                    "implied_pct": {
                        "pl_P76KPC": 6.7,
                        "pl_15JJZ0": 93.3
                    },
                    "book_pct": 97.44
                },
                "favourite": "pl_15JJZ0",
                "favourite_won": false
            }
        ],
        "upset_rates": [
            {
                "band": "2 to 3",
                "matches": 5364,
                "implied_pct": 41.2,
                "outsider_won_pct": 40.1,
                "average_price": 2.39,
                "level_stakes_return_pct": -5.5
            },
            {
                "band": "3 to 5",
                "matches": 3207,
                "implied_pct": 27.4,
                "outsider_won_pct": 28.3,
                "average_price": 3.64,
                "level_stakes_return_pct": 0.5
            }
        ],
        "all": {
            "matches": 10171,
            "upsets": 3356,
            "upset_pct": 33,
            "winners_at_or_over_min_price": 1073
        }
    },
    "meta": {
        "plan": "analyst",
        "window": "everything, including the model endpoints",
        "market": "match_winner",
        "prices": "The best price across bookmakers at the last reading before the start, or the first reading after it where none came before. A best-of-market price: not one bookmaker's line and not a closing line.",
        "odds_archive": {
            "priced_matches": 10222,
            "first": "2016-01-03",
            "last": "2026-03-20"
        },
        "min_price": 3,
        "returns": "Returns are level stakes at the best price across bookmakers, which flatters any approach compared with what one bookmaker would have paid.",
        "how": "An upset is the outsider winning. Rates are banded by the outsider's price.",
        "data_as_of": "2026-09-30T18:38:43Z"
    }
}
```

#### `GET /v1/markets/value` (Analyst)

Value. Fixtures where model and market disagree past a threshold. Empty while no live prices are held (none since 20 March 2026).

Plans: Analyst. Page: https://dartsapi.com/documentation/endpoints/markets-value

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `edge` | query | float | no | The smallest gap between model and market to report, in percentage points: 0 to 50, default 5. |
| `from` | query | date | no | Earliest date to include, YYYY-MM-DD. |
| `to` | query | date | no | Latest date to include, YYYY-MM-DD. |
| `limit` | query | int | no | How many to return. Default 50, at most 200. |

Errors: 401 `no_key`, `bad_key`; 402 `upgrade_required`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

```json
{
    "data": {
        "model_against_market": {
            "matches": 10222,
            "log_loss": {
                "model": 0.62688,
                "market": 0.60652
            },
            "brier": {
                "model": 0.2189,
                "market": 0.21
            },
            "same_favourite_pct": 85.9,
            "better_forecast": "market"
        },
        "backing_the_model_where_it_disagreed": {
            "band": "disagreed by 5+ points",
            "matches": 5689,
            "model_side_won_pct": 44.2,
            "average_price": 2.86,
            "level_stakes_return_pct": -2.5,
            "model_expected_pct": 55
        },
        "by_disagreement": [
            {
                "band": "disagreed by 2+ points",
                "matches": 8318,
                "model_side_won_pct": 45.8,
                "average_price": 2.76,
                "level_stakes_return_pct": -3.1
            },
            {
                "band": "disagreed by 5+ points",
                "matches": 5689,
                "model_side_won_pct": 44.2,
                "average_price": 2.86,
                "level_stakes_return_pct": -2.5
            }
        ],
        "disagreements": [
            {
                "match": {
                    "match_id": "mt_1XPCTP90DH7M0GFP9ATE",
                    "played_on": "2026-03-20",
                    "round": "last_48",
                    "winner": {
                        "player_id": "pl_Z4342S",
                        "name": "Ryan Meikle",
                        "score": 6
                    },
                    "loser": {
                        "player_id": "pl_EQ4VDT",
                        "name": "Francois Schweyen",
                        "score": 4
                    },
                    "event": {
                        "event_id": "ev_MX0A6T",
                        "competition_id": "cp_2YJ4TA",
                        "name": "European Tour",
                        "date": "2026-03-22",
                        "tier": "european_tour"
                    }
                },
                "model_pct": {
                    "pl_Z4342S": 58.82,
                    "pl_EQ4VDT": 41.18
                },
                "market_pct": {
                    "pl_Z4342S": 72.48,
                    "pl_EQ4VDT": 27.52
                },
                "disagreement_points": 13.7,
                "model_side": "pl_EQ4VDT",
                "price": 3.59,
                "model_side_won": false
            },
            {
                "match": {
                    "match_id": "mt_1E0G8VNQ78CG7XZ6S0X6",
                    "played_on": "2026-03-20",
                    "round": "last_48",
                    "winner": {
                        "player_id": "pl_0886SR",
                        "name": "Dirk van Duijvenbode",
                        "score": 6
                    },
                    "loser": {
                        "player_id": "pl_C8VA26",
                        "name": "Lukas Wenig",
                        "score": 3
                    },
                    "event": {
                        "event_id": "ev_MX0A6T",
                        "competition_id": "cp_2YJ4TA",
                        "name": "European Tour",
                        "date": "2026-03-22",
                        "tier": "european_tour"
                    }
                },
                "model_pct": {
                    "pl_0886SR": 48.77,
                    "pl_C8VA26": 51.23
                },
                "market_pct": {
                    "pl_0886SR": 64.62,
                    "pl_C8VA26": 35.38
                },
                "disagreement_points": 15.9,
                "model_side": "pl_C8VA26",
                "price": 2.8,
                "model_side_won": false
            }
        ]
    },
    "meta": {
        "plan": "analyst",
        "window": "everything, including the model endpoints",
        "market": "match_winner",
        "prices": "The best price across bookmakers at the last reading before the start, or the first reading after it where none came before. A best-of-market price: not one bookmaker's line and not a closing line.",
        "odds_archive": {
            "priced_matches": 10222,
            "first": "2016-01-03",
            "last": "2026-03-20"
        },
        "edge_points": 5,
        "returns": "Returns are level stakes at the best price across bookmakers, which flatters any approach compared with what one bookmaker would have paid.",
        "model": {
            "ratings_as_of": "2026-09-30",
            "length_effect": {
                "baseline_race": 6,
                "gamma": 0,
                "verdict": "No length adjustment beat the rating alone, so every format gets the rating's own probability."
            },
            "log_loss": {
                "chosen": 0.58968,
                "rating_alone": 0.58968
            },
            "how": "The rating's probability, adjusted for the length of the format only as far as the archive shows length matters, then turned into a per-leg chance to give scores and legs."
        },
        "how": "Past matches only, since a disagreement can only be judged once the match is played. Each is priced from the ratings as they stood before it was played, with the market's margin taken out, and a disagreement backs whichever side the model rated higher than the market did.",
        "data_as_of": "2026-09-30T18:38:47Z"
    }
}
```

#### `GET /v1/markets/formats` (paid plans)

Formats. How match length changes volatility.

Plans: Live, Archive, Complete, Analyst. Page: https://dartsapi.com/documentation/endpoints/markets-formats

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `from` | query | date | no | Earliest date to include, YYYY-MM-DD. |
| `to` | query | date | no | Latest date to include, YYYY-MM-DD. |

Errors: 401 `no_key`, `bad_key`; 402 `upgrade_required`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

```json
{
    "data": {
        "formats": [
            {
                "band": "first to 1-3",
                "matches": 31,
                "implied_pct": 66.3,
                "favourite_won_pct": 71,
                "average_price": 1.5,
                "level_stakes_return_pct": 1.2,
                "upset_pct": 29,
                "favourite_beat_the_market_by": 4.7
            },
            {
                "band": "first to 4-5",
                "matches": 791,
                "implied_pct": 67.5,
                "favourite_won_pct": 68.4,
                "average_price": 1.49,
                "level_stakes_return_pct": -1,
                "upset_pct": 31.6,
                "favourite_beat_the_market_by": 0.9
            }
        ]
    },
    "meta": {
        "plan": "analyst",
        "window": "everything, including the model endpoints",
        "market": "match_winner",
        "prices": "The best price across bookmakers at the last reading before the start, or the first reading after it where none came before. A best-of-market price: not one bookmaker's line and not a closing line.",
        "odds_archive": {
            "priced_matches": 10222,
            "first": "2016-01-03",
            "last": "2026-03-20"
        },
        "returns": "Returns are level stakes at the best price across bookmakers, which flatters any approach compared with what one bookmaker would have paid.",
        "how": "Every priced match read from the favourite's side and banded by race length. The race is read from the winning score; set-play events are kept apart as sets. If longer races are steadier, the favourite's price shortens and its win rate rises together.",
        "data_as_of": "2026-09-30T18:38:47Z"
    }
}
```

### Probability and props

The model: any pairing in any format, and props priced from it.

#### `GET /v1/probability` (Analyst)

Probability. Any pairing in any format.

Plans: Analyst. Page: https://dartsapi.com/documentation/endpoints/probability

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `player_id` | query | id | no | A player, as pl_ followed by six characters. |
| `opponent_id` | query | id | no | The other player, as pl_ followed by six characters. |
| `format` | query | enum | no | legs or sets. |
| `legs` | query | int | no | First to this many legs (in a sets match, legs per set). |
| `sets` | query | int | no | First to this many sets, for a sets match. |

Errors: 401 `no_key`, `bad_key`; 402 `upgrade_required`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

```json
{
    "data": {
        "format": {
            "format": "legs",
            "first_to_legs": 6,
            "label": "First to 6 legs"
        },
        "players": [
            {
                "player_id": "pl_VEB8HM",
                "name": "Luke Littler",
                "rating": 2415.6,
                "provisional": false
            },
            {
                "player_id": "pl_PMAW5J",
                "name": "Luke Humphries",
                "rating": 2312.4,
                "provisional": false
            }
        ],
        "leg_win_pct": {
            "pl_VEB8HM": 55.44,
            "pl_PMAW5J": 44.56
        },
        "match_win_pct": {
            "pl_VEB8HM": 64.43,
            "pl_PMAW5J": 35.57
        },
        "fair_odds": {
            "pl_VEB8HM": 1.55,
            "pl_PMAW5J": 2.81
        },
        "expected_legs": 9.2,
        "scores": [
            {
                "score": "6-4",
                "winner": "pl_VEB8HM",
                "pct": 14.42
            },
            {
                "score": "6-3",
                "winner": "pl_VEB8HM",
                "pct": 14.38
            }
        ]
    },
    "meta": {
        "plan": "analyst",
        "model": {
            "ratings_as_of": "2026-09-30",
            "length_effect": {
                "baseline_race": 6,
                "gamma": 0,
                "verdict": "No length adjustment beat the rating alone, so every format gets the rating's own probability."
            },
            "log_loss": {
                "chosen": 0.58968,
                "rating_alone": 0.58968
            },
            "how": "The rating's probability, adjusted for the length of the format only as far as the archive shows length matters, then turned into a per-leg chance to give scores and legs."
        },
        "data_as_of": "2026-09-30T18:38:47Z"
    }
}
```

#### `GET /v1/matches/{id}/probability` (Analyst)

Match probability. The same for a real fixture, with the format taken from the match and the market placed beside it.

Plans: Analyst. Page: https://dartsapi.com/documentation/endpoints/match-probability

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `match_id` | path | id | yes | A match, as mt_ followed by six characters. |

Errors: 401 `no_key`, `bad_key`; 402 `upgrade_required`; 404 `not_found`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

```json
{
    "data": {
        "match": {
            "match_id": "mt_1WPYX3K955Y1R2BZBNKP",
            "played_on": "2026-03-20",
            "round": "last_48",
            "winner": {
                "player_id": "pl_ZDYYD1",
                "name": "Boris Krčmar",
                "score": 6
            },
            "loser": {
                "player_id": "pl_X29RN1",
                "name": "Raymond van Barneveld",
                "score": 1
            },
            "event": {
                "event_id": "ev_MX0A6T",
                "competition_id": "cp_2YJ4TA",
                "name": "European Tour",
                "date": "2026-03-22",
                "tier": "european_tour"
            }
        },
        "priced_before": "2026-03-20",
        "format": {
            "format": "legs",
            "first_to_legs": 6,
            "label": "First to 6 legs",
            "read_from": "the winning score"
        },
        "ratings_before": {
            "pl_ZDYYD1": 1976.4,
            "pl_X29RN1": 1855
        },
        "match_win_pct": {
            "pl_ZDYYD1": 66.8,
            "pl_X29RN1": 33.2
        },
        "fair_odds": {
            "pl_ZDYYD1": 1.5,
            "pl_X29RN1": 3.01
        },
        "favourite": "pl_ZDYYD1",
        "favourite_won": true,
        "actual_score_pct": 8.4,
        "market": {
            "decimal": {
                "pl_ZDYYD1": 1.58,
                "pl_X29RN1": 2.58
            },
            "implied_pct": {
                "pl_ZDYYD1": 62.02,
                "pl_X29RN1": 37.98
            },
            "taken_at": "2026-03-20T17:17:59Z",
            "reading": "last_before_start",
            "note": "The best price across bookmakers at the last reading before the start, or the first reading after it where none came before. A best-of-market price: not one bookmaker's line and not a closing line."
        }
    },
    "meta": {
        "plan": "analyst",
        "model": {
            "ratings_as_of": "2026-09-30",
            "length_effect": {
                "baseline_race": 6,
                "gamma": 0,
                "verdict": "No length adjustment beat the rating alone, so every format gets the rating's own probability."
            },
            "log_loss": {
                "chosen": 0.58968,
                "rating_alone": 0.58968
            },
            "how": "The rating's probability, adjusted for the length of the format only as far as the archive shows length matters, then turned into a per-leg chance to give scores and legs."
        },
        "data_as_of": "2026-09-30T18:38:47Z"
    }
}
```

#### `GET /v1/props/180s` (Analyst)

180s. 180s pricing.

Plans: Analyst. Page: https://dartsapi.com/documentation/endpoints/props-180s

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `player_id` | query | id | no | A player, as pl_ followed by six characters. |
| `opponent_id` | query | id | no | The other player, as pl_ followed by six characters. |
| `format` | query | enum | no | legs or sets. |
| `line` | query | float | no | The 180s line to price over and under. |
| `legs` | query | int | no | First to this many legs (in a sets match, legs per set). |
| `sets` | query | int | no | First to this many sets, for a sets match. |

Errors: 401 `no_key`, `bad_key`; 402 `upgrade_required`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

```json
{
    "data": {
        "format": {
            "format": "legs",
            "first_to_legs": 11,
            "label": "First to 11 legs"
        },
        "expected_legs": 18.2,
        "players": [
            {
                "player_id": "pl_VEB8HM",
                "name": "Luke Littler",
                "per_leg_180": 0.5071,
                "expected_180s": 9.21,
                "matches_counted": 134
            },
            {
                "player_id": "pl_PMAW5J",
                "name": "Luke Humphries",
                "per_leg_180": 0.3909,
                "expected_180s": 7.1,
                "matches_counted": 144
            }
        ],
        "total": {
            "expected": 16.31,
            "line": 6.5,
            "over_pct": 99.67,
            "under_pct": 0.33,
            "fair_odds": {
                "over": 1,
                "under": 305.83
            }
        },
        "most_180s": {
            "pl_VEB8HM": 65.47,
            "pl_PMAW5J": 25.81,
            "tie": 8.72
        }
    },
    "meta": {
        "plan": "analyst",
        "figures_from": "2025-09-30 to 2026-09-30",
        "how": "Each player's 180s per leg over the last twelve months, times the legs this format is expected to run, counted as independent Poisson totals.",
        "model": {
            "ratings_as_of": "2026-09-30",
            "length_effect": {
                "baseline_race": 6,
                "gamma": 0,
                "verdict": "No length adjustment beat the rating alone, so every format gets the rating's own probability."
            },
            "log_loss": {
                "chosen": 0.58968,
                "rating_alone": 0.58968
            },
            "how": "The rating's probability, adjusted for the length of the format only as far as the archive shows length matters, then turned into a per-leg chance to give scores and legs."
        },
        "data_as_of": "2026-09-30T18:38:48Z"
    }
}
```

#### `GET /v1/props/finishing` (Analyst)

Finishing. Checkout and nine-darter pricing.

Plans: Analyst. Page: https://dartsapi.com/documentation/endpoints/props-finishing

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `player_id` | query | id | no | A player, as pl_ followed by six characters. |
| `opponent_id` | query | id | no | The other player, as pl_ followed by six characters. |
| `format` | query | enum | no | legs or sets. |
| `legs` | query | int | no | First to this many legs (in a sets match, legs per set). |
| `sets` | query | int | no | First to this many sets, for a sets match. |

Errors: 401 `no_key`, `bad_key`; 402 `upgrade_required`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

```json
{
    "data": {
        "format": {
            "format": "legs",
            "first_to_legs": 11,
            "label": "First to 11 legs"
        },
        "expected_legs": 18.2,
        "players": [
            {
                "player_id": "pl_VEB8HM",
                "name": "Luke Littler",
                "checkout_pct": 47.31,
                "best_checkout_12_months": 170,
                "checkout_at_least": {
                    "100_plus_pct": 72.32,
                    "120_plus_pct": 56.51,
                    "140_plus_pct": 35.63,
                    "170_plus_pct": 11.38
                },
                "matches_counted": 134
            },
            {
                "player_id": "pl_PMAW5J",
                "name": "Luke Humphries",
                "checkout_pct": 43.71,
                "best_checkout_12_months": 170,
                "checkout_at_least": {
                    "100_plus_pct": 74.65,
                    "120_plus_pct": 49.85,
                    "140_plus_pct": 23.52,
                    "170_plus_pct": 3.71
                },
                "matches_counted": 144
            }
        ],
        "either_player": {
            "100_plus_pct": 92.98,
            "120_plus_pct": 78.19,
            "140_plus_pct": 50.77,
            "170_plus_pct": 14.67
        }
    },
    "meta": {
        "plan": "analyst",
        "figures_from": "2025-09-30 to 2026-09-30",
        "how": "How often each player's best checkout in a match reached each mark over the last twelve months, turned into a per-leg chance and scaled to the legs this format is expected to run.",
        "model": {
            "ratings_as_of": "2026-09-30",
            "length_effect": {
                "baseline_race": 6,
                "gamma": 0,
                "verdict": "No length adjustment beat the rating alone, so every format gets the rating's own probability."
            },
            "log_loss": {
                "chosen": 0.58968,
                "rating_alone": 0.58968
            },
            "how": "The rating's probability, adjusted for the length of the format only as far as the archive shows length matters, then turned into a per-leg chance to give scores and legs."
        },
        "data_as_of": "2026-09-30T18:38:48Z"
    }
}
```

### Leaders, sync and usage

Leaderboards, a change feed for syncing, and your own usage.

#### `GET /v1/leaders` (paid plans)

Leaders. Leaderboards.

Plans: Live, Archive, Complete, Analyst. Page: https://dartsapi.com/documentation/endpoints/leaders

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `metric` | query | enum | no | wins, matches, or any statistic by its key: three_dart_avg, count_180, checkout_pct and the rest. |
| `season` | query | int | no | A calendar year, such as 2025. |
| `tier` | query | enum | no | Only this tier: majors, players_championship, european_tour, world_series, qualifiers, development_tour, challenge_tour, womens_series, junior, regional, wdf_platinum, wdf_gold, wdf_silver, wdf_bronze, and so on. |
| `limit` | query | int | no | How many to return. Default 50, at most 200. |

Errors: 401 `no_key`, `bad_key`; 402 `upgrade_required`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

```json
{
    "data": [
        {
            "position": 1,
            "player_id": "pl_VEB8HM",
            "name": "Luke Littler",
            "three_dart_avg": 101.06,
            "matches_counted": 176
        },
        {
            "position": 2,
            "player_id": "pl_PMAW5J",
            "name": "Luke Humphries",
            "three_dart_avg": 98.77,
            "matches_counted": 154
        }
    ],
    "meta": {
        "metric": "three_dart_avg",
        "combined": "mean",
        "season": "2025",
        "count": 3,
        "plan": "analyst",
        "window": "everything, including the model endpoints",
        "qualifying": "ten or more matches with the figure",
        "data_as_of": "2026-09-30T18:39:22Z"
    }
}
```

#### `GET /v1/changes` (paid plans)

Changes. Everything added or changed since a cursor, so a customer can sync without polling every list.

Plans: Live, Archive, Complete, Analyst. Page: https://dartsapi.com/documentation/endpoints/changes

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `since` | query | cursor | no | Carry on from here: pass back meta.next_cursor exactly as it came. Leave it out to start from a day ago. |
| `kind` | query | enum | no | Only one kind of change: match, player or event. |
| `limit` | query | int | no | How many to return. Default 100, at most 500. |

Errors: 401 `no_key`, `bad_key`; 402 `upgrade_required`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

```json
{
    "data": [
        {
            "kind": "match",
            "change": "updated",
            "id": "mt_168KK1Y1YTY9YT7SPXF8",
            "at": "2026-09-29T18:39:37Z",
            "record": {
                "match_id": "mt_168KK1Y1YTY9YT7SPXF8",
                "played_on": "2026-09-16",
                "round": "round_robin",
                "winner": {
                    "player_id": "pl_FSMTAQ",
                    "name": "Kyron Duggan",
                    "score": 2
                },
                "loser": {
                    "player_id": "pl_QSG9M3",
                    "name": "Ray Campbell",
                    "score": 0
                },
                "event": {
                    "event_id": "ev_NXH9HX",
                    "competition_id": "cp_G7BEPB",
                    "name": "Junior Volts Series 1 Week",
                    "date": "2026-09-14",
                    "tier": "junior"
                }
            }
        },
        {
            "kind": "match",
            "change": "updated",
            "id": "mt_03RBVC2T2FFARBE9B7E5",
            "at": "2026-09-29T18:39:37Z",
            "record": {
                "match_id": "mt_03RBVC2T2FFARBE9B7E5",
                "played_on": "2026-09-16",
                "round": "round_robin",
                "winner": {
                    "player_id": "pl_8J9TW6",
                    "name": "Aaron McBride",
                    "score": 2
                },
                "loser": {
                    "player_id": "pl_QSG9M3",
                    "name": "Ray Campbell",
                    "score": 0
                },
                "event": {
                    "event_id": "ev_NXH9HX",
                    "competition_id": "cp_G7BEPB",
                    "name": "Junior Volts Series 1 Week",
                    "date": "2026-09-14",
                    "tier": "junior"
                }
            }
        }
    ],
    "meta": {
        "count": 3,
        "has_more": true,
        "next_cursor": "c_A3PyDXicGpmoirKwNaxGVJ32k0k_fQ",
        "poll": "more waiting: call again straight away with next_cursor",
        "plan": "analyst",
        "window": "everything, including the model endpoints",
        "data_as_of": "2026-09-30T18:39:22Z"
    }
}
```

#### `GET /v1/usage`

Usage. Plan, window, limits and today's counters. Lab tools check this before doing any work.

Plans: Free key, Live, Archive, Complete, Analyst. Page: https://dartsapi.com/documentation/endpoints/usage

Errors: 401 `no_key`, `bad_key`; 429 over the rate or allowance.

```json
{
    "data": {
        "account": "ac_EXAMPLE",
        "plan": {
            "key": "free",
            "name": "Free key",
            "endpoints": 10,
            "of": 41,
            "reach": "every free endpoint, on results at least seven days old"
        },
        "window": {
            "from": null,
            "to": "2026-09-23",
            "in_play": false
        },
        "rate": {
            "per_minute": 60,
            "used_this_minute": 1,
            "resets_in_s": 38
        },
        "allowance": {
            "period": "day",
            "limit": 500,
            "used": 1,
            "remaining": 499,
            "used_pct": 0.2,
            "resets_in_s": 19238,
            "resets_at": "2026-10-01T00:00:00Z"
        },
        "counted": "Every call that is authorised and understood counts, including this one. Refusals for plan or parameters do not.",
        "key": {
            "prefix": "da_live_3f9c",
            "last_used": "2026-09-30T18:39:22Z"
        }
    },
    "meta": {
        "plan": "free",
        "data_as_of": "2026-09-30T18:39:22Z"
    }
}
```

### History

The world championships the match archive does not hold, round by round: the BDO's from 1978 to 2020 and the WDF's of 2023 and 2024, and with draw=women the women's (the BDO's from 2001). Compiled from Wikipedia's draws, used under CC BY-SA.

#### `GET /v1/history/world-championships`

World championships. The world championships the match archive does not hold, the BDO's from 1978 to 2020 and the WDF's of 2023 and 2024: champion, runner-up and what is held for each.

Plans: Free key, Live, Archive, Complete, Analyst. Page: https://dartsapi.com/documentation/endpoints/history-championships

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `draw` | query | string | no | men (the default) or women: the women's world championships, the BDO's from 2001 to 2020 and the WDF's of 2023 and 2024. |

Errors: 401 `no_key`, `bad_key`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

#### `GET /v1/history/world-championships/{year}` (paid plans)

A world championship. One of those championships in full: every round, both players, the sets each won and their averages where published.

Plans: Live, Archive, Complete, Analyst. Page: https://dartsapi.com/documentation/endpoints/history-championship

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `year` | path | int | yes | The year it was played: 1978 to 2020 for the BDO, 2023 or 2024 for the WDF (with draw=women, 2001 to 2020 for the BDO). |
| `draw` | query | string | no | men (the default) or women: the women's world championships, the BDO's from 2001 to 2020 and the WDF's of 2023 and 2024. |

Errors: 401 `no_key`, `bad_key`; 402 `upgrade_required`; 404 `not_found`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

#### `GET /v1/history/majors`

history_majors. The televised majors of 2004 to 2017 the match archive does not hold, from published draws: each event, its dates and how many matches are held. major= for one.

Plans: Free key, Live, Archive, Complete, Analyst. Page: https://dartsapi.com/documentation/endpoints/history-majors

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `major` | query | string | no |  |

Errors: 401 `no_key`, `bad_key`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

#### `GET /v1/history/majors/{year}` (paid plans)

history_major. Every major of that year the archive does not hold, in full: round, both players, the score and their averages where published. major= for one.

Plans: Live, Archive, Complete, Analyst. Page: https://dartsapi.com/documentation/endpoints/history-major

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `year` | path | int | yes |  |
| `major` | query | string | no |  |

Errors: 401 `no_key`, `bad_key`; 402 `upgrade_required`; 404 `not_found`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

### Rankings

#### `GET /v1/order-of-merit`

oom_table. The PDC Order of Merit as it stood on a day: position, places moved, player and ranking prize money. Today's, or date= for another day held.

Plans: Free key, Live, Archive, Complete, Analyst. Page: https://dartsapi.com/documentation/endpoints/oom-table

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `date` | query | string | no |  |

Errors: 401 `no_key`, `bad_key`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

#### `GET /v1/order-of-merit/seasons`

oom_seasons. The seasons whose start-of-season Order of Merit is held (2017 on), with how many players each lists.

Plans: Free key, Live, Archive, Complete, Analyst. Page: https://dartsapi.com/documentation/endpoints/oom-seasons

Errors: 401 `no_key`, `bad_key`; 429 over the rate or allowance.

#### `GET /v1/order-of-merit/seasons/{season}` (paid plans)

oom_season. One season's start list in full: every Tour Card holder in order, country, ranking prize money and how the card was won.

Plans: Live, Archive, Complete, Analyst. Page: https://dartsapi.com/documentation/endpoints/oom-season

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `season` | path | int | yes | A calendar year, such as 2025. |

Errors: 401 `no_key`, `bad_key`; 402 `upgrade_required`; 404 `not_found`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

#### `GET /v1/order-of-merit/lists`

oom_lists. Every other ranking table held, with its seasons: the Order of Merit after each World Championship and year to date, the qualification races for the majors, the Players Championship and European Tour tables, the Challenge Tour, Development Tour, Women's Series, Asian Tour and Nordic & Baltic, from 2019.

Plans: Free key, Live, Archive, Complete, Analyst. Page: https://dartsapi.com/documentation/endpoints/oom-lists

Errors: 401 `no_key`, `bad_key`; 429 over the rate or allowance.

#### `GET /v1/order-of-merit/lists/{list}` (paid plans)

oom_list. One ranking table in full for a season: position, player and ranking prize money (or points). season= for one season, the newest held without it.

Plans: Live, Archive, Complete, Analyst. Page: https://dartsapi.com/documentation/endpoints/oom-list

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `list` | path | string | yes |  |
| `season` | query | int | no | A calendar year, such as 2025. |

Errors: 401 `no_key`, `bad_key`; 402 `upgrade_required`; 404 `not_found`; 422 `bad_parameter`, `unknown_parameter`; 429 over the rate or allowance.

## Guides

### Getting started

From no key to real results in a few minutes. (https://dartsapi.com/documentation/guides/getting-started)

The Darts API is one REST API over the whole darts archive. Every call is a `GET` (one is a `POST`) to `https://api.dartsapi.com/v1`, answers in JSON, and needs your key.

### 1. Get a key

Sign in with Google and a free key is issued at once, with no card. It lives on your [dashboard](https://dartsapi.com/dashboard/key). Keep it in an environment variable rather than in your code.

### 2. Check it works

`/v1/usage` answers with your plan, your window and today's counters. It is the call to make first, and the one lab tools make before doing any work.

```
curl https://api.dartsapi.com/v1/usage \
  -H "Authorization: Bearer $DARTS_API_KEY"
```

### 3. Make a real call

Every player, match and competition has an id that carries its type: `pl_` for a player, `mt_` for a match, `cp_` for a competition, `ev_` for an edition. Find a player by name, then use their id everywhere else.

```
curl "https://api.dartsapi.com/v1/players?q=littler" \
  -H "Authorization: Bearer $DARTS_API_KEY"

curl "https://api.dartsapi.com/v1/results?player_id=pl_VEB8HM&limit=5" \
  -H "Authorization: Bearer $DARTS_API_KEY"
```

### Every response has the same shape

What you asked for is in `data`. Everything about the answer is in `meta`: your `plan`, the `window` it was answered within, a `next_cursor` when there is more, a `request_id` to quote if you ever need help, and `data_as_of`, how fresh the archive was when it answered.

### Authentication

One key, sent in one header, on every call. (https://dartsapi.com/documentation/guides/authentication)

Send your key as a bearer token in the `Authorization` header. Keys start `da_live_` and are 40 characters long.

```
Authorization: Bearer da_live_3f9c…
```

Keys are not accepted in the query string. A key in a URL ends up in logs, proxies, browser history and screenshots, so the API does not look for one there.

### When a key is refused

| Status | Code | What happened |
| --- | --- | --- |
| 401 | `no_key` | No `Authorization` header, or no bearer token in it. |
| 401 | `bad_key` | Something was sent, but it is not shaped like a Darts API key. |
| 401 | `unknown_key` | A well-formed key that is not ours, or one that has been rotated. |

### Rotating your key

Rotate from your [dashboard](https://dartsapi.com/dashboard/key). The old key stops the moment the new one is issued, so put the new one in place first. Your plan, usage and history stay with your account, not the key.

### Pagination

Two ways through a long list, and when to use each. (https://dartsapi.com/documentation/guides/pagination)

Every list returns at most `limit` rows: 50 unless you ask, and at most 200. Fixtures and the change feed allow more, 100 by default and up to 500.

### Cursor, for walking a whole set

When there is more, `meta.next_cursor` holds where to carry on. Pass it back as `cursor` exactly as it came, and stop when it comes back `null`. A cursor pages by position in the sort, so the ten-thousandth page is as quick as the first, and a match arriving while you walk cannot shift a row onto two pages.

```
import os, requests

url = "https://api.dartsapi.com/v1/results"
headers = {"Authorization": f"Bearer {os.environ['DARTS_API_KEY']}"}
params = {"player_id": "pl_VEB8HM", "limit": 200}

while True:
    page = requests.get(url, headers=headers, params=params).json()
    for match in page["data"]:
        print(match["played_on"], match["round"])
    if not page["meta"]["next_cursor"]:
        break
    params["cursor"] = page["meta"]["next_cursor"]
```

### Page, for a pager in a UI

Lists that show a pager to people also take `page`, counting from 1. Use it where someone clicks "page 3". Use `page` or `cursor`, not both.

### Rate limits

Two limits, and every response says where you stand on both. (https://dartsapi.com/documentation/guides/rate-limits)

Each plan has a rate for the minute and an allowance for the day (free key) or the month (paid plans). Every response carries both in its headers, so a client can pace itself and never be refused.

```
x-ratelimit-limit: 60
x-ratelimit-remaining: 58
x-ratelimit-reset: 41          seconds until the minute resets
x-allowance-limit: 500
x-allowance-remaining: 487
x-allowance-reset: 34201       seconds until the day resets
```

### Going over

A call past the minute answers `429 rate_limited`; a call once the allowance is used answers `429 allowance_used`. Both carry a `Retry-After` header in seconds and a sentence saying when to come back. Allowances renew at 00:00 UTC. There is no overage bill, ever: a refused call is simply refused.

### What counts

Only calls that are authorised and understood count. A call refused for its key, its plan or its parameters costs nothing.

| Plan | Endpoints | Window | Rate | Allowance |
| --- | --- | --- | --- | --- |
| Free key | 16 | Every free endpoint, on results at least seven days old | 60 a minute | 500 a day |
| Live | 44 | In-play and the last thirty days | 120 a minute | 250,000 a month |
| Archive | 43 | The whole archive, but nothing in play | 120 a minute | 250,000 a month |
| Complete | 44 | In-play and the whole archive | 180 a minute | 600,000 a month |
| Analyst | 52 | Everything, including the model endpoints | 240 a minute | 1,000,000 a month |

### Errors

Every refusal says what went wrong and what to do. (https://dartsapi.com/documentation/guides/errors)

A refusal is JSON with an `error` object: a `code` to branch on, a `message` written for a person, and a `request_id`. Some add detail, such as the parameters an endpoint accepts or the plan that reaches it.

```
{
  "error": {
    "code": "upgrade_required",
    "message": "/v1/ratings is on every paid plan, from Live at $39 a month. You are on Free key.",
    "needs": "Live",
    "your_plan": "Free key",
    "pricing": "https://dartsapi.com/pricing",
    "request_id": "req_2c81f0a94e7b1d63"
  }
}
```

| Status | Code | What it means |
| --- | --- | --- |
| 400 | `bad_id` | An id of the wrong type, such as a match id given as a player. |
| 401 | `no_key`, `bad_key`, `unknown_key` | The key is missing, malformed or not ours. See Authentication. |
| 402 | `upgrade_required` | Your plan does not reach this endpoint. The message names the plan that does. |
| 402 | `outside_window` | The endpoint is yours, but the date asked for is outside your plan's window. |
| 404 | `not_found`, `no_such_endpoint` | No such record, or no such path. A path close to a real one gets suggestions. |
| 405 | `wrong_method` | A GET endpoint called with POST, or the other way round. |
| 422 | `bad_parameter`, `unknown_parameter`, `missing_parameter` | A parameter is malformed, not one the endpoint takes, or required and absent. The message names it. |
| 429 | `rate_limited`, `allowance_used` | Over the minute, or the day's or month's allowance is used. `Retry-After` says when. See Rate limits. |
| 503 | `archive_unavailable`, `ratings_building` | Something at our end is briefly unavailable. Retry shortly; it never counts against you. |

### Timezones

Everything is UTC. (https://dartsapi.com/documentation/guides/timezones)

Dates are `YYYY-MM-DD` and timestamps are UTC, ending in `Z`. A match's `played_on` is the UTC date it was played.

### Fixture times

Fixtures carry `starts_at`, the start time in UTC, ending in `Z` like every other timestamp. It is `null` while the order of play gives no time yet, rather than a guess.

### How fresh an answer is

Every response carries `meta.data_as_of`, a UTC timestamp of how fresh the archive was when it answered. Live scores also carry `freshness.captured_at`; see [Live and freshness](https://dartsapi.com/documentation/guides/live-and-freshness).

### Plans and windows

What each plan reaches, and how a window shows in a response. (https://dartsapi.com/documentation/guides/plans-and-windows)

A plan decides two things: which endpoints a key reaches, and the window of dates it sees. The endpoint counts below are worked out by the same rule the API enforces.

| Plan | Endpoints | Window | Rate | Allowance |
| --- | --- | --- | --- | --- |
| Free key | 16 | Every free endpoint, on results at least seven days old | 60 a minute | 500 a day |
| Live | 44 | In-play and the last thirty days | 120 a minute | 250,000 a month |
| Archive | 43 | The whole archive, but nothing in play | 120 a minute | 250,000 a month |
| Complete | 44 | In-play and the whole archive | 180 a minute | 600,000 a month |
| Analyst | 52 | Everything, including the model endpoints | 240 a minute | 1,000,000 a month |

### How a window shows

Every response names its window in `meta.window`, so a missing week is never mistaken for a gap in the data. Asking for dates outside it answers `402 outside_window` rather than an empty list that looks like nothing happened.

### Changing plan

Your key stays the same. A new plan applies the moment payment confirms, with nothing to change in your code.

### Live and freshness

How current live scores and fixtures are, and how each answer says so. (https://dartsapi.com/documentation/guides/live-and-freshness)

`/v1/live` lists every match in play with the score and each player's average. It is refreshed every five minutes, on plans that include in-play: Live, Complete and Analyst.

### Freshness is part of the answer

```
{
  "captured_at": "2026-09-24T19:40:02Z",
  "age_seconds": 118,
  "refreshed": "every 5 minutes",
  "behind": false
}
```

A score can be a few minutes behind the board, and the response says by how much. If the feed falls more than twenty minutes behind, `behind` turns true and a note says so, rather than an old score passing for a new one.

### Fixtures

`/v1/fixtures` lists the whole published draw of every tournament under way, on every key. A date the organiser has fixed is marked `date_confirmed`; one not yet fixed is marked unconfirmed rather than guessed. Players the archive does not know yet are named with a null id.

### Ratings

How every player is rated, and what the numbers mean. (https://dartsapi.com/documentation/guides/ratings)

Every player carries a rating, updated after every result, oldest match first. Everyone starts at 1500. A win against a stronger player moves a rating more than a win against a weaker one.

### How much a result moves a rating

A player's first 20 matches move their rating further, so a new player finds their level quickly. Until then the rating is marked provisional. After that, each result moves it by a smaller, steady step.

### Active players

The table ranks players who have played in the last year. Everyone keeps a rating, but a player who has stopped playing drops out of the ranking until they return.

### A rating on any date

`/v1/ratings/snapshot` rebuilds the table as it stood on a date, from matches that started before it and nothing after. That is the table to backtest against: it holds no knowledge of what came next.

### The probability model

How the model prices a match, and how it compares with the market. (https://dartsapi.com/documentation/guides/the-probability-model)

`/v1/probability` prices any two players over any format. The gap between their ratings gives each player's chance, and the format decides how that chance plays out over a race of legs or sets.

### Match length

Whether a longer match favours the stronger player more is measured from the archive rather than assumed, and applied as measured. Every answer says which measurement it used.

### Against the market

`/v1/markets/value` and `/v1/matches/{id}/probability` put the model beside the closing price with the margin taken out. Over the priced archive the market is the better forecaster, and the endpoints say so rather than presenting every disagreement as value.

### Outrights

`/v1/editions/{id}/outrights` and `/v1/simulate/bracket` work out each player's chance of each round exactly, through every path of the draw. Nothing is simulated, so the same draw always gives the same answer.

### Markets and prices

The closing prices held, and what is measured from them. (https://dartsapi.com/documentation/guides/markets-and-prices)

The archive holds closing prices for the match winner on professional matches from 2016, each linked to its match. It is the one market collected for darts.

### Margin taken out

Where an endpoint gives an implied probability, the bookmaker's margin has been removed, so the two players' chances add up to one.

### What is measured

- `/v1/markets/calibration`: implied chance against what actually happened, band by band.

- `/v1/markets/favourites`: how often favourites win, by price and format.

- `/v1/markets/upsets`: the longest-priced winners.

- `/v1/markets/formats`: how match length changes the picture.

- `/v1/prices/bulk`: every priced match, for building your own model.

### Syncing with changes

Keep a copy up to date without re-reading every list. (https://dartsapi.com/documentation/guides/syncing-with-changes)

`/v1/changes` lists everything added or changed since a cursor: matches, players and events, oldest first. Each row says what changed and whether it is new or updated.

### The loop

Start without `since` to get the last day. Store `meta.next_cursor`, and next time pass it as `since`. Filter to one kind with `kind=match`, `player` or `event`.

```
import os, requests, json, pathlib

state = pathlib.Path("since.txt")
params = {"limit": 500}
if state.exists():
    params["since"] = state.read_text()

r = requests.get("https://api.dartsapi.com/v1/changes", params=params,
    headers={"Authorization": f"Bearer {os.environ['DARTS_API_KEY']}"}).json()
for change in r["data"]:
    print(change)
if r["meta"]["next_cursor"]:
    state.write_text(r["meta"]["next_cursor"])
```

## Errors

Every refusal is `{"error": {"code", "message", "detail", "request_id"}}`. A 402 names the plan that reaches the endpoint; a 429 carries `Retry-After`. The full list: https://dartsapi.com/documentation/guides/errors

## About this document

Generated from the endpoint registry, the guides and the plan configuration, never written by hand: the date at the top says how old a copy is. Machine-readable alternatives: https://dartsapi.com/openapi.json and the MCP server at https://dartsapi.com/mcp. Agent skill: https://dartsapi.com/skill.md
