13 verified API examples
Every example below was recorded from a live call to the public API and carries machine-checked assertions, so it cannot drift from what the API actually returns.
Verified Examples
Worked examples of behaviour shipped this week, each recorded from a live call. These are not hand-written illustrations: every example carries machine-checked assertions, andnpm run docs:verifyreplays them against the public API and fails the run if any documented behaviour stops being true.
`type` is an alias of `race_type` on the boardrecorded 2026-10-05
On /racing/meetings both `type` and `race_type` filter the code, and they return the identical set of meetings.
curl -H "X-API-Key: $KROK_API_KEY \
"https://krokodds.com.au/api/v1/racing/meetings?date=2026-10-05&type=T&limit=5"{
"success": true,
"data": [
{
"id": "tab_1234567",
"venue": "Flemington",
"state": "VIC",
"country": "AU",
"type": "T",
"date": "2026-10-05",
"race_count": 8,
"next_jump": "2026-10-05T04:35:00.000Z",
"races": [
{
"race_key": "2026-10-05_flemington_T_5",
"number": 5,
"status": "open"
}
],
"data_quality": {
"books_count": 12,
"has_results": false,
"last_price_update": "2026-10-05T03:58:12.000Z"
}
}
],
"meta": {
"count": 6,
"tier": "api",
"limit": 100,
"requested_limit": 5
}
}- `type=T|H|G` and `race_type=T|H|G` are interchangeable on this endpoint.
- Every meeting in the response has `type` set to the requested code.
- The two spellings return the same number of meetings (asserted against the `race_type` example).
`race_type` on the board (same result as `type`)recorded 2026-10-05
`race_type` is the spelled-out form of the same filter, and returns the same meetings as `type`.
curl -H "X-API-Key: $KROK_API_KEY \
"https://krokodds.com.au/api/v1/racing/meetings?date=2026-10-05&race_type=T&limit=5"{
"success": true,
"data": [
{
"id": "tab_1234567",
"venue": "Flemington",
"type": "T",
"date": "2026-10-05",
"race_count": 8
}
],
"meta": {
"count": 6,
"tier": "api",
"limit": 100,
"requested_limit": 5
}
}- The board echoes neither parameter in `meta` — the filter shows up in the data, not in a meta field.
- Use whichever spelling you prefer; both are supported here.
Default price-line taxonomy: `fixed` + `group` onlyrecorded 2026-10-05
A default request serves only `fixed` and `group` price lines. Every served odds row carries `bookmaker_type`, and group rows also carry the white-label roster in `brands[]`.
curl -H "X-API-Key: $KROK_API_KEY \
"https://krokodds.com.au/api/v1/racing/meetings?date=2026-10-05&limit=5"{
"data": [
{
"races": [
{
"runners": [
{
"number": 3,
"name": "Zaaki",
"best_win": 3.2,
"best_win_bookmaker": "Sportsbet",
"odds": [
{
"bookmaker": "Sportsbet",
"bookmaker_type": "fixed",
"win": 3.2,
"place": 1.5
},
{
"bookmaker": "PuntersTech",
"bookmaker_type": "group",
"win": 3.25,
"brands": [
"BetAlpha",
"BetBlitz",
"MintBet",
"PuntersTech",
"XBet"
]
}
]
}
]
}
]
}
]
}- `bookmaker_type` is one of `fixed | tote | exchange | group | derived | capped`.
- Default board = `fixed` + `group`; the other four types need `include=` (see the next example).
- A `group` odds row aggregates a platform’s whole roster and lists it in `brands[]`.
- The six types are also published by /racing/bookmakers with the same spelling.
`include=` opts into the extra price linesrecorded 2026-10-25
`include=` adds the opt-in price-line types to the default `fixed`+`group` set; an unknown type is rejected with a 400.
curl -H "X-API-Key: $KROK_API_KEY \
"https://krokodds.com.au/api/v1/racing/meetings?date=2026-10-25&include=exchange&limit=5"{
"data": [
{
"races": [
{
"runners": [
{
"number": 3,
"odds": [
{
"bookmaker": "Sportsbet",
"bookmaker_type": "fixed",
"win": 3.2,
"place": 1.5
},
{
"bookmaker": "Betfair",
"bookmaker_type": "exchange",
"win": 3.4,
"lay": 3.5,
"matched": 42000
}
]
}
]
}
]
}
]
}- Comma-separate the values. Valid values: `fixed`, `tote`, `exchange`, `group`, `derived`, `capped`.
- The default board carries `fixed` and `group`; opt in for `exchange` (with `lay`/`matched`) and the rest.
- A requested type only appears for the races where that price line is published — an opted-in type can be absent for a whole meeting.
- An unknown value is a 400: `{"success":false,"error":"Unsupported bookmaker type: bogus"}`.
`bookmaker_type` and `brands[]` on the catalogue
/racing/bookmakers labels every book with the same `bookmaker_type` enum the odds rows use, and group entries list their white-label roster in `brands[]`.
curl -H "X-API-Key: $KROK_API_KEY \
"https://krokodds.com.au/api/v1/racing/bookmakers"{
"success": true,
"data": [
{
"id": "ladbrokes",
"name": "Ladbrokes",
"region": "au",
"supported": true,
"is_aggregator": false,
"is_exchange": false,
"bookmaker_type": "fixed"
},
{
"id": "punterstech",
"name": "PuntersTech",
"region": "au",
"supported": false,
"is_aggregator": true,
"is_exchange": false,
"bookmaker_type": "group",
"brands": [
"BetAlpha",
"BetBlitz",
"MintBet",
"XBet"
]
},
{
"id": "tab",
"name": "TAB",
"region": "au",
"supported": true,
"is_aggregator": false,
"is_exchange": false,
"bookmaker_type": "tote"
},
{
"id": "betfair_ex_au",
"name": "Betfair",
"region": "au",
"supported": true,
"is_aggregator": false,
"is_exchange": true,
"bookmaker_type": "exchange"
}
],
"meta": {
"count": 23,
"timestamp": "2026-10-05T01:20:00.000Z"
}
}- Use this catalogue to know up front which labels will appear as `group`, `tote` or `exchange` in an odds payload.
- `brands[]` is present on `group` entries (e.g. 20+ names for a white-label platform) and omitted elsewhere.
- `is_aggregator` / `is_exchange` remain, but `bookmaker_type` is the field the odds rows carry.
Results archive: `race_type` is the filterrecorded 2026-09-26
On /racing/results `race_type` is the documented filter and `type` is its alias — the response is filtered either way, and `meta.race_type` echoes the code that was applied.
curl -H "X-API-Key: $KROK_API_KEY \
"https://krokodds.com.au/api/v1/racing/results?since=2026-09-26&until=2026-09-26&race_type=T&limit=2000"{
"success": true,
"data": [
{
"id": "2026-09-26_market-rasen_T_1",
"race_key_v2": "2026-09-26_market-rasen_T_1",
"date": "2026-09-26",
"track": "Market Rasen",
"race_no": 1,
"race_type": "T",
"racing_type": "T",
"status": "resulted",
"data_quality": {
"books": 0,
"has_result": true
},
"winner": {
"tab_number": 5,
"name": "Jilord Viva",
"slug": "jilord-viva"
},
"runners": [
{
"tab_number": 5,
"name": "Jilord Viva",
"finish_position": 1,
"win_result": "Winner"
}
]
}
],
"meta": {
"count": 375,
"tier": "api",
"limit": 2000,
"race_type": "T"
}
}- `race_type=T|H|G` filters the archive and is echoed in `meta.race_type`.
- Every returned row carries the matching `race_type` (and `racing_type`).
- `type=` is the same filter under the shorter name — see the next example.
Results archive: `type=` is the same filter as `race_type`recorded 2026-10-25
`/racing/results` reads `type` as an alias of `race_type`: the same rows come back and `meta.race_type` echoes the code that was applied. With both present, `race_type` wins.
curl -H "X-API-Key: $KROK_API_KEY \
"https://krokodds.com.au/api/v1/racing/results?since=2026-10-25&until=2026-10-25&type=T&limit=2000"{
"success": true,
"data": [
{
"id": "2026-09-26_market-rasen_T_1",
"race_type": "T"
}
],
"meta": {
"count": 375,
"tier": "api",
"limit": 2000,
"race_type": "T"
}
}- `type=T` returns the same set as `race_type=T` (asserted against the previous example).
- `meta.race_type` echoes the applied code for either spelling — log it rather than trusting your request string.
- Both spellings work across the racing routes; `race_type` is the documented one.
Dated results: `race_type=T` filters the cardrecorded 2026-10-04
On `/racing/results/{date}` the code filter is `race_type`, echoed in `meta.race_type`, and every returned row is that code.
curl -H "X-API-Key: $KROK_API_KEY \
"https://krokodds.com.au/api/v1/racing/results/2026-10-04?race_type=T&limit=2000"{
"success": true,
"data": [
{
"id": "2026-09-26_market-rasen_T_1",
"race_key": "2026-09-26_market-rasen_T_1",
"date": "2026-09-26",
"track": "Market Rasen",
"race_no": 1,
"race_type": "T",
"status": "resulted",
"winner": {
"name": "Jilord Viva",
"tab_number": 5
}
}
],
"meta": {
"count": 74,
"date": "2026-10-04",
"race_type": "T",
"tier": "api"
}
}- `race_type=T|H|G` filters the day and is echoed in `meta.race_type`.
- `type=` is an accepted alias here too — see the next example.
- The dated endpoint is the full-detail card (margins, times, tote pools); /racing/results is the lighter archive.
Dated results: `type=` is the same filter as `race_type`recorded 2026-10-25
The dated endpoint reads `type` as an alias of `race_type` and echoes the applied code in `meta.race_type`; both spellings return the same card.
curl -H "X-API-Key: $KROK_API_KEY \
"https://krokodds.com.au/api/v1/racing/results/2026-10-25?type=T&limit=2000"{
"success": true,
"data": [
{
"id": "2026-09-26_market-rasen_T_1",
"race_type": "T"
}
],
"meta": {
"count": 74,
"date": "2026-10-25",
"race_type": "T",
"tier": "api"
}
}- `type=T` returns the same set as `race_type=T` (asserted against the previous example).
- `meta.race_type` echoes the applied code, so a filter that was not applied is visible in the response.
- Every racing route accepts both spellings; `race_type` is the documented one.
Results archive without a code filterrecorded 2026-09-26
The unfiltered archive for a day range returns the races that settled in it, across every code.
curl -H "X-API-Key: $KROK_API_KEY \
"https://krokodds.com.au/api/v1/racing/results?since=2026-09-26&until=2026-09-26&limit=2000"{
"success": true,
"data": [
{
"id": "2026-09-26_market-rasen_T_1",
"race_type": "T"
},
{
"id": "2026-09-26_gawler_G_3",
"race_type": "G"
},
{
"id": "2026-09-26_addington_H_2",
"race_type": "H"
}
],
"meta": {
"count": 645,
"tier": "api",
"limit": 2000,
"race_type": null
}
}- One day of results spans `T`, `H` and `G`.
- Use `since`/`until` for a day range (paid plan; a free key gets the tier gate).
- `limit` caps the page and `meta.count` reports how many races matched the window.
Identity gate: results are named, or reported `pending`recorded 2026-09-26
A result row is only served when the runner can be named; a race with any unidentified result row is reported as `pending` with `winner: null`, and `status` is never null.
curl -H "X-API-Key: $KROK_API_KEY \
"https://krokodds.com.au/api/v1/racing/results/2026-09-26"{
"success": true,
"data": [
{
"id": "2026-09-26_aquis-park-gold-coast_T_1",
"race_type": "T",
"status": "pending",
"winner": null,
"runners": [
{
"tab_number": null,
"name": null,
"finish_position": null
},
{
"tab_number": 4,
"name": "Named Runner",
"finish_position": null
}
],
"data_quality": {
"books": 7,
"has_result": false
}
},
{
"id": "2026-09-26_market-rasen_T_1",
"status": "resulted",
"winner": {
"tab_number": 5,
"name": "Jilord Viva",
"slug": "jilord-viva"
},
"runners": [
{
"tab_number": 5,
"name": "Jilord Viva",
"finish_position": 1,
"win_result": "Winner"
}
]
}
],
"meta": {
"count": 645,
"tier": "api",
"limit": 2000,
"race_type": null
}
}- Rows carrying a finishing position but no runner name are dropped — you never receive "a result" that names nobody.
- A race with at least one such row is `pending` with `winner: null` even if a winner is identifiable, because the surviving rows are not a complete finishing order.
- `status` is always a string: `resulted`, `finished`, `pending`, … — never null.
- The gate applies to every code on the day, so the example requests the whole day rather than one code.
- `data_quality.has_result` reflects the served rows only.
GET /me/usage and the X-Credits-* headers
Every metered response carries credit headers; /me/usage returns the same numbers as a body. Four headers appear: X-Credits-Limit, X-Credits-Remaining, X-Credits-Reset and (on metered endpoints only) X-Credits-Cost.
curl -H "X-API-Key: $KROK_API_KEY \
"https://krokodds.com.au/api/v1/me/usage"{
"success": true,
"data": {
"tier": "api",
"credits_used": 7071,
"credits_remaining": 42929,
"credits_limit": 50000,
"usage_pct": 14.14,
"reset_date": "2026-11-01T00:00:00.000Z",
"rate_limit": {
"limit": 500,
"remaining": 491,
"reset": "2026-10-05T01:28:00.000Z"
}
},
"meta": {
"truncated": false,
"timestamp": "2026-10-05T01:27:06.755Z"
}
}- `X-Credits-Limit` / `X-Credits-Remaining` / `X-Credits-Reset` are on every authenticated response, including this one.
- `X-Credits-Cost` is on the endpoint that charges: e.g. `/racing/results/{date}` returns `X-Credits-Cost: 5`.
- `X-RateLimit-*` is the short-term request window; `X-Credits-*` is the monthly allowance — different limits, both in the headers.
- `data.usage_pct` is `credits_used / credits_limit × 100`, rounded to 2dp.
`X-Credits-Cost` on a metered endpointrecorded 2026-09-26
A metered endpoint advertises what it charged in the same header set as the credit balance.
curl -H "X-API-Key: $KROK_API_KEY \
"https://krokodds.com.au/api/v1/racing/results/2026-09-26?race_type=T&limit=2"{
"headers": {
"x-ratelimit-tier": "api",
"x-ratelimit-limit": "500",
"x-credits-cost": "5",
"x-credits-limit": "50000",
"x-credits-remaining": "42924",
"x-credits-reset": "2026-11-01T00:00:00.000Z"
}
}- `X-Credits-Cost` is the per-request charge for this endpoint (5 for the dated results endpoint).
- `X-Credits-Remaining` is read after the charge is applied.
Reproduce them: KROK_API_KEY=… npx tsx scripts/api-docs-vs-live.ts