Documentation / Platform & reference
Coverage ledger
/v1/coverageAvailable on Free Live Live Plus
Every track and day: races carded, run, resulted and abandoned, checked against Betfair's own market list for anything we never received. On every key.
Authenticate with your key in the X-API-Key header, or
?key= if your tool cannot set one —
see Authentication. Works with sandbox keys
inside the sandbox data window.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
date |
query | date | no | The day, as a UTC date, which is the racing day in every country we carry. Defaults to today. The ledger runs from 1 December 2022 to tomorrow. |
region |
query | string | no | GB, IE or AU. Omit for all three. |
Request
curl "https://api.greyhoundapi.com/v1/coverage?date=2026-09-22" \
-H "X-API-Key: $GAPI_KEY"<?php
$ch = curl_init('https://api.greyhoundapi.com/v1/coverage?date=2026-09-22');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['X-API-Key: ' . getenv('GAPI_KEY')],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($response['data']);const res = await fetch('https://api.greyhoundapi.com/v1/coverage?date=2026-09-22', {
headers: { 'X-API-Key': process.env.GAPI_KEY }
});
if (!res.ok) throw new Error(`GreyhoundAPI ${res.status}`);
const { meta, data } = await res.json();
console.log(meta.data_as_of, data);import { useEffect, useState } from 'react';
export default function Example() {
const [data, setData] = useState(null);
useEffect(() => {
fetch('https://api.greyhoundapi.com/v1/coverage?date=2026-09-22', {
headers: { 'X-API-Key': import.meta.env.VITE_GAPI_KEY }
})
.then((r) => r.json())
.then((body) => setData(body.data));
}, []);
if (!data) return <p>Loading…</p>;
return <pre>{JSON.stringify(data, null, 2)}</pre>;
}Browser code exposes whatever key it ships with — use a sandbox key for prototypes and proxy live keys through your own server in production.
import os
import requests
r = requests.get(
"https://api.greyhoundapi.com/v1/coverage?date=2026-09-22",
headers={"X-API-Key": os.environ["GAPI_KEY"]},
timeout=10,
)
r.raise_for_status()
body = r.json()
print(body["meta"]["data_as_of"], body["data"])curl "https://api.greyhoundapi.com/v1/coverage?date=2026-09-22&key=$GAPI_KEY"<?php
$url = 'https://api.greyhoundapi.com/v1/coverage?date=2026-09-22' . (str_contains('https://api.greyhoundapi.com/v1/coverage?date=2026-09-22', '?') ? '&' : '?') . 'key=' . getenv('GAPI_KEY');
$ch = curl_init($url);
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($response['data']);const res = await fetch(`https://api.greyhoundapi.com/v1/coverage?date=2026-09-22&key=$GAPI_KEY`.replace('$GAPI_KEY', process.env.GAPI_KEY));
if (!res.ok) throw new Error(`GreyhoundAPI ${res.status}`);
const { meta, data } = await res.json();
console.log(meta.data_as_of, data);import { useEffect, useState } from 'react';
export default function Example() {
const [data, setData] = useState(null);
useEffect(() => {
fetch(`https://api.greyhoundapi.com/v1/coverage?date=2026-09-22&key=$GAPI_KEY`.replace('$GAPI_KEY', import.meta.env.VITE_GAPI_KEY))
.then((r) => r.json())
.then((body) => setData(body.data));
}, []);
if (!data) return <p>Loading…</p>;
return <pre>{JSON.stringify(data, null, 2)}</pre>;
}Browser code exposes whatever key it ships with — use a sandbox key for prototypes and proxy live keys through your own server in production.
import os
import requests
r = requests.get(
"https://api.greyhoundapi.com/v1/coverage?date=2026-09-22",
params={"key": os.environ["GAPI_KEY"]},
timeout=10,
)
r.raise_for_status()
body = r.json()
print(body["meta"]["data_as_of"], body["data"])A key in the URL appears in server logs, browser history and anything the link is pasted into. Convenient for a spreadsheet or a quick look; the header is safer everywhere else.
Response
{
"meta": {
"request_id": "req_8f2ac1",
"data_as_of": "2026-07-08T13:05:12Z",
"list": {
"source": "betfair",
"held": true,
"kind": "live",
"first_seen": "2026-09-22T18:00:04Z"
},
"updated": "2026-09-23T21:45:07Z",
"rebuilt": "every 15 minutes"
},
"data": {
"date": "2026-09-23",
"regions": [
{
"region": "GB",
"checked": true,
"tracks": 12,
"carded": 154,
"run": 154,
"resulted": 153,
"abandoned": 1,
"pending": 0,
"listed": 154,
"missing": 0,
"unlisted": 0,
"before_list": 0,
"not_carried": {
"venues": 0,
"listed": 0
}
},
{
"region": "AU",
"checked": true,
"tracks": 6,
"carded": 50,
"run": 50,
"resulted": 50,
"abandoned": 0,
"pending": 0,
"listed": 50,
"missing": 0,
"unlisted": 0,
"before_list": 0,
"not_carried": {
"venues": 2,
"listed": 21
}
}
],
"tracks": [
{
"track_id": 1400000014,
"name": "Romford",
"region": "GB",
"carried": true,
"carded": 12,
"run": 12,
"resulted": 12,
"abandoned": 0,
"pending": 0,
"checked": true,
"listed": 12,
"missing": 0,
"unlisted": 0,
"before_list": 0
},
{
"track_id": 1400000031,
"name": "Towcester",
"region": "GB",
"carried": true,
"carded": 12,
"run": 12,
"resulted": 11,
"abandoned": 1,
"pending": 0,
"checked": true,
"listed": 12,
"missing": 0,
"unlisted": 0,
"before_list": 0
},
{
"track_id": null,
"name": "Capalaba",
"region": "AU",
"carried": false,
"carded": 0,
"run": 0,
"resulted": 0,
"abandoned": 0,
"pending": 0,
"checked": true,
"listed": 12,
"missing": null,
"unlisted": 0,
"before_list": 0
}
]
}
}Run it live
A real request from your browser straight to api.greyhoundapi.com
with your own key — nothing is proxied or logged by this page.
Held in this tab only, sent only to the API host. No key yet? Create a free sandbox key — it runs every endpoint against the sandbox data window.
Common uses
Missing or abandoned?
A race you expected is not in the feed. If abandoned counts it, it never ran. If missing counts it, the exchange listed it and we never received it, and it is ours to chase.
Checking your own pipeline
Compare your stored races for a day with resulted per track. A gap on your side, with nothing missing on ours, is a fetch you can simply repeat.
How complete the archive is
Walk the dates to see which days were checked and what was missing. A backtest over a period with gaps is measuring less racing than it thinks.
Notes
Free on every tier, sandbox keys included, and not held to the free key's date window: it carries counts, not racing data. Rebuilt every 15 minutes; meta.updated says when this day was last rebuilt. track_id is null for a venue we do not carry.