A race's market
Live, Archive and CompleteMCP: race_market
Book percentage, every price and what moved.
Examplea real answer from 2026-10-29, trimmed to a few rows
{
"data": {
"race_id": "rc_0aa1c4st",
"book_percentage": 133.36,
"runners": [
{
"horse_id": "hs_x73ps4xh",
"horse": "Af Saqara",
"sp": "7/1",
"sp_decimal": 8,
"implied": 0.125,
"price_path": {
"opening": null,
"opening_decimal": null,
"touched": null,
"sp": "7/1",
"sp_decimal": 8,
"drift": null,
"source": "starting_price_only"
},
"favourite": false,
"market_position": 3,
"exchange": null,
"tote_final": null
},
{
"horse_id": "hs_des8z34q",
"horse": "Af Marmuq",
"sp": "10/1",
"sp_decimal": 11,
"implied": 0.0909,
"price_path": {
"opening": null,
"opening_decimal": null,
"touched": null,
"sp": "10/1",
"sp_decimal": 11,
"drift": null,
"source": "starting_price_only"
},
"favourite": false,
"market_position": 7,
"exchange": null,
"tote_final": null
},
{
"horse_id": "hs_5nzbfr73",
"horse": "Ezzah",
"sp": "8/1",
"sp_decimal": 9,
"implied": 0.1111,
"price_path": {
"opening": null,
"opening_decimal": null,
"touched": null,
"sp": "8/1",
"sp_decimal": 9,
"drift": null,
"source": "starting_price_only"
},
"favourite": false,
"market_position": 4,
"exchange": null,
"tote_final": null
}
]
},
"meta": {
"request_id": "24c90f9ffc95cc5e",
"plan": "complete",
"window": "January 2017 to the next 3 days",
"data_as_of": "2026-10-30T08:11:33+00:00"
}
}Parameters
| Name | In | Type | Required | What it does |
|---|---|---|---|---|
race_id | path | id | yes | Our id for the race, as other answers give it (rc_ and eight characters). |
Returns
One record in data. Every answer carries meta: request_id, plan, window and data_as_of.
| Field | Type | Holds |
|---|---|---|
race_id | string | Our id for the race. |
book_percentage | number | The total of the market's implied chances. Null on the free key. |
runners | array | The runners, or how many there were. |
runners[].horse_id | string | Our id for the horse. |
runners[].horse | string | The horse's name. |
runners[].sp | string | Starting price, fractional. Null on the free key. |
runners[].sp_decimal | integer | Starting price, decimal. Null on the free key. |
runners[].implied | number | The probability the starting price implies. Null on the free key. |
runners[].price_path | object | How the price moved: opening, touched and drift. Null on the free key. |
runners[].favourite | boolean | Whether it started favourite. Null on the free key. |
runners[].market_position | integer | Its place in the betting. Null on the free key. |
runners[].exchange | null or value | Exchange prices, where held. Null on the free key. |
runners[].tote_final | null or value | The final tote price, where held. Null on the free key. |
Errors
| Code | Status | When |
|---|---|---|
unauthorized | 401 | No key was sent, or the key is not one of ours. |
upgrade_required | 403 | Your plan does not reach this endpoint. The answer names the plans that do. |
outside_plan_window | 403 | The day asked for is outside what your plan reads. The answer gives your window and the day you asked for. |
bad_request | 400 | A value is the wrong shape: a date that is not YYYY-MM-DD, a cursor that is not ours, or a key sent in the address. |
unknown_parameter | 422 | A parameter this endpoint does not take. The answer lists the ones it does. |
not_found | 404 | No record has that id, or it is not British or Northern Irish racing. |
rate_limited | 429 | Too many calls this minute for your plan. |
quota_exceeded | 429 | Your plan's calls for the month are used. The answer says when they reset. |