Enterprise · Experimental
AI-assisted tips
Three read-only GET endpoints return saved selections for UK and Irish races, each with evidence and a two-sentence explanation.
Not a prediction or wagering service
What it is
- A scheduled job ranks declared runners using documented rules and saves at most one selection per race.
- An AI model then writes exactly two sentences from the saved evidence. Explanations are pre-generated and stored; no AI call happens when you request them.
- There is no POST endpoint and no way to trigger analysis on demand.
- Dates return only saved records. Past dates are historical saved records, not recalculated.
Access and auth
Requires an active Enterprise account. Send your key as X-API-Key: YOUR_KEY or Authorization: Bearer YOUR_KEY. Requests share the Enterprise 10 requests per second limit with every other feed. Other plans receive 403. Signed-in Enterprise customers can also view today's tips in Dashboard, Tips.
Endpoints
| Request | Returns |
|---|---|
GET /v1/tips?date=YYYY-MM-DD&page=1&limit=50 | Paginated tips for the date. limit 1 to 100. |
GET /v1/races/{raceId}/tip?date=YYYY-MM-DD | The tip for one race. |
GET /v1/races/{raceId}/tip/explanation?date=YYYY-MM-DD | Only the saved explanation, version and status. |
Silk image links inside selection.silkUrl are authenticated API URLs; send your key to fetch the PNG.
Status, version and freshness
| status | Meaning |
|---|---|
pending | Not analysed yet. selection and explanation are null. |
active | Current saved selection. |
no_selection | Rules produced no selection; see reason. |
withdrawn | Selected runner no longer declared. Do not display as usable. |
stale | Verification is older than 15 minutes or scheduled off has passed without a result. Do not display as usable. |
settled | Result published; see result. |
version increments when the selection, explanation or lifecycle state changes. Price and verification refreshes do not change the analysis version. Use generatedAt, checkedAt and oddsObservedAt to judge freshness; prices are observations, not live quotes.
The worker checks around once per minute while the service runs. No request waits for AI, but warmup, autoscaling and source outages may delay preparation. A withdrawn selection is not automatically replaced, and no selection is created after scheduled off.
offAt is the conservative analysis cutoff, not a canonical interpretation of unzoned source times. An explicitly zoned source datetime takes priority. Otherwise both source clocks must be valid and the earlier is interpreted in Europe/London, so analysis may freeze earlier than the displayed race time. Unresolvable clocks produce no selection.
Empty and missing
- A date with no saved tips returns
200withdata: []. - An unknown race or a race without a saved record returns
404witherror,codeandrequestId. explanationisnulluntil it has been generated.
Response shape
Structure only. Values are placeholders, not real selections.
{
"meta": {
"date": "YYYY-MM-DD",
"total": 1,
"page": 1,
"limit": 50
},
"data": [
{
"raceId": "RACE_ID",
"date": "YYYY-MM-DD",
"raceName": "RACE_NAME",
"course": "COURSE",
"time": "HH:MM",
"status": "active",
"version": 1,
"explanation": "SENTENCE_ONE. SENTENCE_TWO.",
"selection": {
"horseId": "HORSE_ID",
"horseName": "HORSE_NAME",
"jockey": "JOCKEY",
"trainer": "TRAINER",
"silkUrl": "/v1/silks/HORSE_ID?raceId=RACE_ID&date=YYYY-MM-DD",
"evidence": [
"EVIDENCE_ITEM"
]
},
"odds": [
{
"bookmaker": "BOOKMAKER",
"bookmakerId": "ID",
"price": "PRICE",
"fractional": "PRICE",
"eachWay": ""
}
],
"generatedAt": "ISO_TIMESTAMP",
"checkedAt": "ISO_TIMESTAMP",
"oddsObservedAt": "ISO_TIMESTAMP",
"reason": null,
"result": null
}
]
}Full schemas are in the API reference.