Documentation / Platform & reference
All statistics
/v1/archiveAvailable on Free Live Live Plus
The size of the dataset, counted rather than claimed: how many dogs, trainers, owners and tracks exist, how many runs and meetings, how many pace profiles and trap tables have been built, and races by track and distance with the earliest and latest date and how many carry starting prices, exchange prices and sectionals.
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 |
|---|---|---|---|---|
region |
query | string | no | GB, AU or IE. Omit for every region. |
Request
curl "https://api.greyhoundapi.com/v1/archive" \
-H "X-API-Key: $GAPI_KEY"<?php
$ch = curl_init('https://api.greyhoundapi.com/v1/archive');
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/archive', {
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/archive', {
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/archive",
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/archive?key=$GAPI_KEY"<?php
$url = 'https://api.greyhoundapi.com/v1/archive' . (str_contains('https://api.greyhoundapi.com/v1/archive', '?') ? '&' : '?') . '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/archive?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/archive?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/archive",
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
{
"computed_utc": "2026-09-10T02:14:00Z",
"entities": [
{
"name": "runs",
"count": 3804648,
"serves": "dogs, races",
"note": null
},
{
"name": "dogs",
"count": 76732,
"serves": "dogs",
"note": null
},
{
"name": "pace_profiles",
"count": 62234,
"serves": "dogs",
"note": null
},
{
"name": "meetings",
"count": 53078,
"serves": "meetings",
"note": null
},
{
"name": "owners",
"count": 15786,
"serves": "owners",
"note": null
},
{
"name": "trainers",
"count": 2636,
"serves": "trainers",
"note": null
},
{
"name": "tracks",
"count": 48,
"serves": "tracks",
"note": null
}
],
"totals": {
"races": 610357,
"runners": 3750021,
"first_race": "2018-02-03",
"last_race": "2026-09-10",
"coverage": {
"with_sp": 610038,
"with_betfair": 393663,
"with_sectionals": 516873
}
},
"tracks": [
{
"track_id": 1400000014,
"name": "Romford",
"region": "GB",
"races": 18422,
"runners": 109880,
"first_race": "2018-02-05",
"last_race": "2026-09-09",
"coverage": {
"with_sp": 18400,
"with_betfair": 9120,
"with_sectionals": 14203
},
"distances": [
{
"distance_m": 400,
"races": 9871,
"with_betfair": 4902
},
{
"distance_m": 575,
"races": 5104,
"with_betfair": 2610
}
]
}
]
}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.
Notes
Free on every tier, sandbox keys included. Two figures are worth reading together: races is how much there is, and coverage is how much of it carries the field you need — exchange prices exist on roughly two thirds of races and are concentrated in recent years, so a strategy priced on the exchange has less to work with than the headline count suggests. Per-distance coverage varies within a single track. Counts come from completed races and are recomputed nightly, so they lag the live feed by a day. A count of null means that figure was not computed on the last run, which is not the same as zero.