Tennis API endpoints
ATP/WTA rankings, upcoming fixtures, match results, Elo ratings and surface-specific stats.
5 of 5 endpoints · all categories · get a free API key
GET/api/v1/tennis/eloFree tier
Overall or surface-specific Elo ratings for ATP/WTA players (UTS/tennisabstract-derived).
Two very differently-shaped response rows depending on `surface`: with `surface` set it reads the surface store and returns {id, player_name, player_id, surface, elo}; without it, reads the Elo store and returns the richer {rank, player_name, country_code, elo_rating, best_rank, best_rating, points_diff} shape — field names differ (elo vs elo_rating) between the two modes. `player` filter fetches up to limit*6 rows first then filters in memory (partial match).
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| player | string | No | – | Player name filter, partial/substring, case-insensitive. |
| surface | string | No | – | "hard" | "clay" | "grass" — switches to the surface-Elo table/shape. Any other value is ignored (falls back to overall Elo). |
| limit | integer | No | 100 | Max rows, clamped 1-500 (MAX_LIMIT). |
curl \
-H "X-API-Key: YOUR_KEY" \
"https://krokodds.com.au/api/v1/tennis/elo?player=lebron-james"{
"success": true,
"data": [
{
"id": "atp_sinner_j",
"rank": 1,
"player_name": "Jannik Sinner",
"player_id": "s0ag",
"country_code": "ITA",
"elo_rating": 2312,
"best_rank": 1,
"best_rating": 2340,
"points_diff": 45
}
],
"meta": {
"count": 1,
"tier": "free",
"license": "krokodds-derived",
"player": null,
"surface": null,
"timestamp": "2026-09-03T04:00:00.000Z",
"rate_limit": {
"limit": 100,
"remaining": 949,
"reset": "2026-10-01T00:00:00.000Z"
}
}
}GET/api/v1/tennis/fixturesAPI plan
Upcoming/scheduled tennis fixtures by tour.
Tier detail: api (paid) — 'historical' is NOT in the free-tier feature set
Gated on the 'historical' feature despite being a forward-looking fixtures list (not a historical archive) — free-tier keys get a 402 tier-gate response here. the credit cost=2 (archive-weighted, per the standard v1 route factory cfg comment: standard 1 / archive 5 / bulk 25 — this is priced above standard but not full archive). Built via the standard v1 route factory/the tennis fixture store collection.
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| tour | string | No | – | Tour filter, e.g. "ATP" or "WTA" — exact match on the `tour` JSONB field. |
| limit | integer | No | 100 | Max rows; capped 50 (free) / 200 (api) per limitByTier. |
curl \
-H "X-API-Key: YOUR_KEY" \
"https://krokodds.com.au/api/v1/tennis/fixtures?tour=value"{
"success": true,
"data": [
{
"tour": "ATP",
"tournament": "US Open",
"round": "QF",
"player1": "Carlos Alcaraz",
"player2": "Alexander Zverev",
"date": "2026-09-04",
"surface": "hard",
"venue": "USTA Billie Jean King National Tennis Center"
}
],
"meta": {
"count": 1,
"tier": "api",
"limit": 100,
"requested_limit": 100,
"tour": "ATP",
"timestamp": "2026-09-03T04:00:00.000Z",
"rate_limit": {
"limit": 200,
"remaining": 998,
"reset": "2026-10-01T00:00:00.000Z"
}
}
}GET/api/v1/tennis/matchesFree tier
Historical ATP/WTA singles match results (a public tennis dataset dataset), filterable by season/tour/surface.
Reads the tennis-matches store. Only `season` is an indexed equality filter pushed to the primary store; `tour`/`surface` are applied in-memory after over-fetching (limit*6) when set — per the file's own query-design comment this keeps it on an indexed column. Throws a 400 bad-request error (400) if `season` is non-numeric.
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| season | integer | No | – | Season year, e.g. 2026. Must parse as a number or 400 a 400 bad-request error is returned. |
| tour | string | No | – | "atp" or "wta", case-insensitive, in-memory filter. |
| surface | string | No | – | "hard" | "clay" | "grass", case-insensitive, in-memory filter. |
| limit | integer | No | 100 | Max rows; capped 100 (free) / 500 (api) per limitByTier. |
curl \
-H "X-API-Key: YOUR_KEY" \
"https://krokodds.com.au/api/v1/tennis/matches?season=10"{
"success": true,
"data": [
{
"season": 2026,
"tour": "atp",
"surface": "hard",
"tournament": "US Open",
"round": "SF",
"winner_name": "Jannik Sinner",
"loser_name": "Novak Djokovic",
"score": "6-4 3-6 7-6(5) 6-2",
"date": "2026-09-05"
}
],
"meta": {
"count": 1,
"tier": "free",
"limit": 100,
"requested_limit": 100,
"season": 2026,
"tour": "atp",
"surface": "hard",
"timestamp": "2026-09-03T04:00:00.000Z",
"rate_limit": {
"limit": 100,
"remaining": 949,
"reset": "2026-10-01T00:00:00.000Z"
}
}
}GET/api/v1/tennis/rankingsAPI plan
Current ATP/WTA player rankings.
Tier detail: api (paid) — 'historical' is NOT in the free-tier feature set
Gated on 'historical' despite being a current-state rankings list, not an archive — free-tier keys get 402. No filter params at all beyond `limit` (no tour/player filter exposed). the credit cost=2 like /tennis/fixtures.
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| limit | integer | No | 100 | Max rows; capped 100 (free) / 500 (api) per limitByTier. |
curl \
-H "X-API-Key: YOUR_KEY" \
"https://krokodds.com.au/api/v1/tennis/rankings?limit=100"{
"success": true,
"data": [
{
"ranking": 1,
"tour": "ATP",
"player_name": "Jannik Sinner",
"country": "ITA",
"points": 11330,
"movement": 0
},
{
"ranking": 1,
"tour": "WTA",
"player_name": "Iga Swiatek",
"country": "POL",
"points": 9945,
"movement": 1
}
],
"meta": {
"count": 2,
"tier": "api",
"limit": 100,
"requested_limit": 100,
"timestamp": "2026-09-03T04:00:00.000Z",
"rate_limit": {
"limit": 500,
"remaining": 998,
"reset": "2026-10-01T00:00:00.000Z"
}
}
}GET/api/v1/tennis/surface-statsFree tier
Tennis surface-specific Elo/win-rate stats (hard/clay/grass) for ATP/WTA players.
Reads the SAME table (the surface store) and returns the SAME shape ({id, player_name, player_id, surface, elo}) as /api/v1/tennis/elo?surface=X — effectively a duplicate/alias of that mode with a dedicated path. No win-rate field despite the doc-comment and summary saying "win rates and Elo by surface" — only `elo` is actually returned, no win_pct/matches_played field exists in code.
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| player | string | No | – | Player name filter, partial/substring, case-insensitive. |
| surface | string | No | – | "hard" | "clay" | "grass" — invalid values are silently ignored (no filter applied). |
| limit | integer | No | 100 | Max rows, clamped 1-500 (MAX_LIMIT). |
curl \
-H "X-API-Key: YOUR_KEY" \
"https://krokodds.com.au/api/v1/tennis/surface-stats?player=lebron-james"{
"success": true,
"data": [
{
"id": "atp_alcaraz_c_clay",
"player_name": "Carlos Alcaraz",
"player_id": "a0e2",
"surface": "clay",
"elo": 2280
}
],
"meta": {
"count": 1,
"tier": "free",
"license": "krokodds-derived",
"player": null,
"surface": "clay",
"timestamp": "2026-09-03T04:00:00.000Z",
"rate_limit": {
"limit": 100,
"remaining": 949,
"reset": "2026-10-01T00:00:00.000Z"
}
}
}Other categories
Per-event head-to-head odds, alternate lines, best prices across books, player props, live state and AI-generated summaries.
Krok's built-in scanners — arbitrage, positive EV, middles, low-holds, player props and same-game multi (SGM) picks, already devigged against a blended sharp baseline.
The full Australian racing stack — thoroughbred, harness and greyhound. Meetings and runner fields, form, sectionals, ratings, market movers, exchange arbs, tote pools and results.
Raw per-bookmaker prices as scraped, before any analysis layer. `/scraped-odds/*` paths are aliases of the equivalent `/odds-feed/*` route.
Sport reference data, team form guides, league standings, injury reports and weather-impact analysis.
AI-generated betting tips with confidence scores and historical accuracy tracking.
Ranked leaderboards built on top of the stat feeds — per-sport player leaders for a chosen stat, season and view.
Deep archives — player and team game logs, shot charts, AFL/NRL historical data. Paid API plan only.
Static lookup data for building your own UI — players, venues, headshots, team logos and sport/league metadata.
Cricket, cycling, esports, Formula 1, golf, MMA, boxing, NFL and soccer coverage beyond the AU staples.
Account and billing endpoints, bulk export, SSE streaming, webhook management and API health.
Odds history, steam-move detection, player prop stats/results, injuries, weather and other supporting feeds.
Polymarket and Kalshi sentiment plus a universal prediction-market catalogue and resolutions feed.