AI analysis and structured predictions for greyhound racing — built on the GreyhoundAPI (Great Britain & Australia).
greyhound-ai pulls real racing data — racecards, form, results, tracks — and runs it through a large language model (OpenAI, Anthropic/Claude, MiniMax, or your own) to produce readable race previews and structured, ranked predictions. Then it does the part most "AI tipster" tools skip: a backtester that scores those predictions against the actual results, so you can see how good (or bad) the model really is.
Experimental analysis for research and education — not betting advice. Model output is frequently wrong; measure it before relying on it. See Responsible use.
- Provider-agnostic — swap OpenAI / Claude / MiniMax with one line
- Grounded in real GreyhoundAPI data (no hallucinated form)
- Structured output: ranked runners with per-runner reasoning and confidence
- Built-in backtesting against real results (win rate, top-3 rate, rank correlation)
- Zero heavy dependencies — the standard library plus the
greyhoundapiclient
pip install greyhound-aiThis pulls in the greyhoundapi data client automatically. You'll also need an API key from whichever LLM provider you choose.
The data comes from the GreyhoundAPI, authenticated with a key:
- Go to greyhoundapi.com and click Get a free key (top-right).
- Sign in to create your account.
- Open Account → API keys and click Create key.
- Copy the key — it's shown only once. Sandbox keys start
gapi_test_; live keys startgapi_live_.
A free sandbox key (no card) covers the race & track endpoints over a rolling 7-day window at 500 requests/day — enough to try greyhound-ai end to end. The live plan opens the full archive and every endpoint. See pricing.
Set your keys as environment variables:
export GREYHOUNDAPI_KEY=gapi_... # from greyhoundapi.com
export OPENAI_API_KEY=sk-... # or ANTHROPIC_API_KEY / MINIMAX_API_KEYfrom greyhound_ai import GreyhoundAI, OpenAIProvider
ai = GreyhoundAI(provider=OpenAIProvider(model="gpt-4o-mini")) # reads GREYHOUNDAPI_KEY
preview = ai.preview_race(1229082)
print(preview.preview) # natural-language overview
for r in sorted(preview.ranking, key=lambda x: x["rank"]):
print(r["rank"], "trap", r["trap"], r["dog"], "—", r["reason"])Or from the command line:
python -m greyhound_ai preview 1229082
python -m greyhound_ai analyze 655044
python -m greyhound_ai backtest 1229081 1229082 1229083 --provider anthropic --model claude-3-5-haiku-latestPass any provider to GreyhoundAI(provider=...). Each reads its key from the
environment by default, and takes an explicit model (names change often — use
one your account has):
from greyhound_ai import OpenAIProvider, AnthropicProvider, MiniMaxProvider, CallableProvider
OpenAIProvider(model="gpt-4o-mini") # OPENAI_API_KEY
AnthropicProvider(model="claude-3-5-haiku-latest") # ANTHROPIC_API_KEY
MiniMaxProvider(model="MiniMax-Text-01", base_url="...") # MINIMAX_API_KEY (confirm the current host)
# anything else — a local model, a gateway, a stub for tests:
CallableProvider(lambda system, user: my_llm(system, user))| Method | What you get |
|---|---|
preview_race(race_id) |
Overview + a ranked prediction (trap, rank, confidence, reason) grounded in the runners' recent form |
analyze_runner(dog_id) |
A dog's profile summarised: strengths, weaknesses, best conditions |
compare(dog_id, rival_id) |
Head-to-head read using the API's H2H history and both dogs' form |
ask(question, race_id=…) |
A plain-language answer grounded strictly in the supplied data |
backtest(ai, race_ids) |
Accuracy of the model's predictions vs real results |
Every result carries the .disclaimer and the raw model text in .raw.
Predictions are only worth as much as their track record, so greyhound-ai
measures them for you. For each past race it takes the model's ranking, fetches
the real result, and scores:
from greyhound_ai import GreyhoundAI, OpenAIProvider, backtest
ai = GreyhoundAI(provider=OpenAIProvider(model="gpt-4o-mini"))
report = backtest(ai, ["1229081", "1229082", "1229083"])
print(f"top pick won: {report.win_hit_rate:.0%}")
print(f"top pick in first 3: {report.top3_hit_rate:.0%}")
print(f"rank correlation: {report.avg_rank_correlation:.2f}") # 1 = perfect, 0 = randomRun it over a few hundred races and you'll have an honest read on whether the model is doing anything a coin toss wouldn't. That number — not the confident prose — is what matters.
The model only ever sees data returned by the GreyhoundAPI (the race, the runners, their recent form), passed through as JSON, with an instruction not to invent form, times or prices. Output is requested and parsed as JSON. It can still be wrong — greyhound racing is high-variance — which is exactly why the backtester exists.
greyhound-ai is a research and education tool. It does not provide betting
advice, tips, staking guidance, or any assurance about outcomes, and its authors
accept no liability for decisions made using it. Greyhound racing results are
inherently uncertain and no model predicts them reliably. If you gamble, do so
within your means and seek help if it stops being fun.
- GreyhoundAPI — https://greyhoundapi.com
- API documentation — https://greyhoundapi.com/documentation
- Data SDK (
greyhoundapi) — the underlying client this builds on