Race analysis
/v1/races/{race_id}/analysisAvailable on Live Plus only
A Live key reaches the other 42 endpoints and
receives 403 upgrade_required here. Compare plans
Conditions and measured early pace for one race in a single request, joined per runner — the trap record at this track and distance, typical winning times, field experience, and each runner's early split with the sample behind it.
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 |
|---|---|---|---|---|
race_id |
path | integer | yes | The race identifier. |
Request
curl "https://api.greyhoundapi.com/v1/races/3959843903/analysis" \
-H "X-API-Key: $GAPI_KEY"<?php
$ch = curl_init('https://api.greyhoundapi.com/v1/races/3959843903/analysis');
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/3959843903/analysis', {
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/3959843903/analysis', {
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/3959843903/analysis",
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/3959843903/analysis?key=$GAPI_KEY"<?php
$url = 'https://api.greyhoundapi.com/v1/races/3959843903/analysis' . (str_contains('https://api.greyhoundapi.com/v1/races/3959843903/analysis', '?') ? '&' : '?') . '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/3959843903/analysis?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/3959843903/analysis?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/3959843903/analysis",
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"
},
"data": {
"race_id": 1229082445,
"track": {
"track_id": 1400000014,
"name": "Romford",
"region": "GB",
"timezone": "Europe/London"
},
"distance_m": 400,
"grade": "A3",
"going": null,
"is_handicap": false,
"conditions": {
"trap_bias": {
"sample_races": 11745,
"even_break_pct": 16.67,
"traps": [
{
"trap": 1,
"wins": 2161,
"win_pct": 18.4
}
],
"note": null
},
"winning_time": {
"sample_races": 4820,
"window": "last 24 months",
"average_s": 24.61,
"fastest_s": 23.84,
"stdev_s": 0.412
},
"field": {
"runners": 6,
"avg_career_win_pct": 12.8,
"avg_career_runs": 24.5,
"least_experienced": 7,
"most_experienced": 61
}
},
"pace": {
"field_avg_first_split_s": 3.85,
"spread_s": 0.25,
"quickest_away": {
"trap": 3,
"dog_name": "Miami Yeats"
},
"slowest_away": {
"trap": 5,
"dog_name": "Headford Eimear"
},
"with_data": 3,
"without_data": [
{
"trap": 4,
"dog_id": 1640101557,
"dog_name": "Savana Ruby",
"runs": 2,
"reason": "2 timed runs \u2014 below the 3 needed"
}
],
"scope": {
"window": "last 18 months",
"same_track": true,
"same_distance": true,
"handicaps": "excluded",
"min_runs": 3,
"note": null
}
},
"runners": [
{
"trap": 3,
"dog_id": 1654595188,
"dog_name": "Miami Yeats",
"pace": {
"avg_first_split_s": 3.7,
"best_s": 3.66,
"vs_field_s": -0.15,
"runs": 5
}
}
],
"note": "Conditions and measured early pace for this race in one request. Every figure carries the sample it is drawn from. Nothing here rates a runner, ranks the field by chance or forecasts the result."
}
}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.