Loading match intelligence…
Football, tennis and basketball fixtures with model predictions, recent form, head-to-head records and live odds — over a simple, read-only JSON API. No SDK required.
# All upcoming football matches curl https://api.smoance.com/matches \ -H "X-API-Key: sk_live_your_key_here"
Send your key on every request as either header. Requests without a valid key fall back to the anonymous tier (limited per IP) rather than being rejected — so public, low-volume use works with no key at all. Need a key? dash@smoance.com.
X-API-Key: sk_live_your_key_here
Authorization: Bearer sk_live_your_key_here
| Tier | Requests / min | Notes |
|---|---|---|
| anon | 60 | No key. Limited per client IP. |
| free | 120 | Issued free key. |
| pro | 1,200 | Higher-volume integrations. |
| unlimited | ∞ | First-party / internal. |
Limits are per minute on a rolling 60-second window. Every response carries your budget; exceeding it returns 429 with a Retry-After header.
X-RateLimit-Tier: pro X-RateLimit-Limit: 1200 X-RateLimit-Remaining: 1187 # When exceeded: HTTP/1.1 429 Too Many Requests Retry-After: 23
All upcoming football matches with predictions, form, H2H and odds.
{
"total": 72,
"data": [
{
"league": "Serie B",
"country": "Brazil",
"match": "Coritiba vs Goias",
"match_url": "https://www.flashscore.com/match/xYz123/",
"date": "2026-06-20",
"time": "23:00",
"team_1": { "name": "Coritiba", "standing": { "rank": 3 }, "...": "..." },
"team_2": { "name": "Goias", "...": "..." },
"model": {
"win_probability": { "team_1": 47, "team_2": 31, "draw": 22 },
"over_2_5_probability": 0.41,
"prediction_quality": "high"
},
"odds": { "match_winner": { "home": { "value": 2.10 }, "...": "..." } }
}
]
}A single football match. `{id}` is the Flashscore match id from match_url.
Football leagues that currently have upcoming matches.
{
"total": 5,
"data": [
{
"country": "Brazil",
"league": "Serie B",
"country_slug": "brazil",
"league_slug": "serie-b",
"count": 7
}
]
}Upcoming matches in one league, Flashscore-style slugs.
Upcoming tennis matches. Optional ?date=YYYY-MM-DD returns a specific day.
A single tennis match by id.
Tennis tournaments (grouped by tour) with upcoming matches.
{
"total": 13,
"data": [
{
"tour_type": "ATP",
"tournament": "Halle",
"country": "Germany",
"surface": "grass",
"tour_slug": "atp",
"tournament_slug": "halle",
"count": 2
}
]
}Upcoming matches in one tournament.
All upcoming basketball matches.
A single basketball match by id.
Basketball leagues with upcoming matches.
Upcoming matches in one league.
Echo the tier resolved for your key. Never cached.
{
"authenticated": true,
"tier": "pro",
"limit_per_min": 1200,
"name": "Acme Corp"
}Liveness probe + per-sport record counts.
| Status | Meaning |
|---|---|
| 200 | OK. |
| 304 | Not Modified — your If-None-Match ETag still matches. |
| 400 | Bad request, e.g. a malformed ?date= value. |
| 404 | No match found for that id. |
| 429 | Rate limit exceeded. See Retry-After header. |
| 5xx | Transient upstream/server error — retry with backoff. |
Data refreshes roughly every 10 seconds. Responses are returned with Cache-Control: public, max-age=0, s-maxage=8, stale-while-revalidate=20 and a weak ETag. Honor the ETag with If-None-Match for cheap 304 responses, and let shared caches absorb bursts — you never get data more than a few seconds stale.