Search races
/v1/racesAvailable on Free Live Live Plus
Search the full greyhound race archive by date range, region, track, grade, distance, handicap flag and lifecycle status, with cursor pagination.
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 |
|---|---|---|---|---|
ids |
query | string | no | Fetch a known set in one call — up to 50 ids, dash or comma separated, e.g. ?ids=2765720978-1237493697. Composes with every other filter, and each id costs one call against your rate limit. If any id has no record the whole request is refused with 400 invalid_id naming it, rather than quietly returning the rest. See batch requests. |
date_from |
query | date | no | Start of the date range, track-local calendar date (YYYY-MM-DD). See Timezones & dates. |
date_to |
query | date | no | End of the date range, track-local calendar date, inclusive. |
region |
query | string | no | Filter by region code: GB, AU or IE. |
track_id |
query | integer | no | Filter to a single track. Track IDs come from List tracks. |
grade |
query | string | no | Filter by composed grade, e.g. A2, S1, D3, OR. |
distance_m |
query | integer | no | Filter by race distance in metres. |
is_handicap |
query | boolean | no | Restrict to handicap or non-handicap races. |
status |
query | string | no | Lifecycle filter: scheduled, off, results_pending, complete, void, abandoned. |
cursor |
query | string | no | Opaque pagination cursor from the previous response's meta.next_cursor. |
limit |
query | integer | no | Page size, 1–200. Defaults to 50. |
page |
query | integer | no | Page number (1-based) — a simpler alternative to cursor. When set, the response also returns meta.page, meta.per_page, meta.total, meta.total_pages, meta.next_page and meta.prev_page. The first page carries these even without page. Prefer cursor for large bulk exports; use page for browsing or bounded (date-filtered) queries. |
Request
curl "https://api.greyhoundapi.com/v1/races?date_from=2026-07-01®ion=GB" \
-H "X-API-Key: $GAPI_KEY"<?php
$ch = curl_init('https://api.greyhoundapi.com/v1/races?date_from=2026-07-01®ion=GB');
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/races?date_from=2026-07-01®ion=GB', {
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/races?date_from=2026-07-01®ion=GB', {
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/races?date_from=2026-07-01®ion=GB",
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/races?date_from=2026-07-01®ion=GB&key=$GAPI_KEY"<?php
$url = 'https://api.greyhoundapi.com/v1/races?date_from=2026-07-01®ion=GB' . (str_contains('https://api.greyhoundapi.com/v1/races?date_from=2026-07-01®ion=GB', '?') ? '&' : '?') . '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/races?date_from=2026-07-01®ion=GB&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/races?date_from=2026-07-01®ion=GB&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/races?date_from=2026-07-01®ion=GB",
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",
"count": 1,
"next_cursor": "eyJzIjoiMjAyNi0wNy0wOFQyMDo0NjowMFoifQ",
"page": 1,
"per_page": 50,
"total": 1287,
"total_pages": 26,
"next_page": 2,
"prev_page": null
},
"data": [
{
"race_id": 1229082445,
"meeting_id": 1449422077,
"region": "GB",
"track": {
"track_id": 1400000014,
"name": "Romford",
"region": "GB",
"timezone": "Europe/London"
},
"race_number": 12,
"grade": "S1",
"class_letter": "S",
"class_number": 1,
"distance_m": 575,
"race_type": "Flat",
"is_handicap": false,
"going": null,
"field_size": 6,
"scheduled_start": {
"utc": "2026-07-08T20:46:00Z",
"local": "2026-07-08T21:46:00+01:00"
},
"status": "scheduled",
"off": null,
"freshness": {
"first_seen": "2026-07-07T05:12:10Z",
"results_received": null,
"results_delay_s": null
},
"weather": {
"hour_utc": "2026-07-08T20:00:00Z",
"temp_c": 15.2,
"humidity_pct": 81,
"wind_kph": 19.5,
"gust_kph": 42.8,
"wind_from": "W",
"wind_deg": 271,
"precip_mm": 0.3,
"conditions": "light drizzle",
"before_race": {
"rain_6h_mm": 1.6,
"rain_24h_mm": 2,
"wind_avg_6h_kph": 21.4
},
"source": "archive"
}
}
]
}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.