Authentication
Send your API key as the X-API-Key header on every request.
curl -H "X-API-Key: zwc_pk_…" \
https://api.zafronix.com/fifa/worldcup/v1/tournaments
A small set of endpoints work without a key for evaluation
(GET /, GET /health, GET /tournaments) — capped at 100 req/day per IP.
Get a key at /signup; free tier requires no card.
Rate limits
Limits depend on your tier. Every response includes:
X-RateLimit-Limit— daily quota for your keyX-RateLimit-Remaining— requests left in the current 24h windowX-RateLimit-Reset— epoch seconds when the window resets
When you exceed the limit you'll get HTTP 429 with a Retry-After header. See /pricing for tier details.
Error shape
All errors return JSON with this consistent shape:
{
"error": "not_found",
"message": "No tournament found for year 1932.",
"request_id": "req_abc123"
}
Common error codes: unauthorized, rate_limited, not_found, invalid_request, internal_error.
Meta
GET /
Returns API name + version. Public.
{
"name": "Zafronix World Cup API",
"version": "1.0.0-preview",
"docs": "https://github.com/zafronix/zafronix-wc-api",
"timestamp": "2026-05-04T02:02:31Z"
}
GET /health
Uptime + dataset freshness probe. Returns 503 if data files fail to load. Public.
{
"ok": true,
"tournamentsLoaded": 23,
"oldestTournament": 1930,
"newestTournament": 2026,
"triviaFactCount": 98
}
Tournaments
GET /tournaments
List of every World Cup tournament with year, host, and champion. Public.
[
{ "year": 1930, "host": ["Uruguay"], "champion": "Uruguay", "edition": 1, "file": "tournaments/1930.json" },
{ "year": 1934, "host": ["Italy"], "champion": "Italy", "edition": 2, "file": "tournaments/1934.json" },
…
{ "year": 2026, "host": ["United States","Canada","Mexico"], "champion": null, "edition": 23, "file": "tournaments/2026.json" }
]
GET /tournaments/{year}
Full data for one tournament — meta, every team, every player. Auth required.
Path: year — 4-digit year, must match a tournament returned by /tournaments.
GET /fifa/worldcup/v1/tournaments/1986
{
"schemaVersion": 1,
"tournament": {
"year": 1986,
"edition": 13,
"host": ["Mexico"],
"datesIso": { "start": "1986-05-31", "end": "1986-06-29" },
"teamsCount": 24,
"matchesCount": 52,
"champion": "Argentina",
"runnerUp": "West Germany",
"thirdPlace": "France",
"topScorer": { "player": "Gary Lineker", "goals": 6 },
"bestPlayer": "Diego Maradona",
"totalGoals": 132,
"totalAttendance": 2394031
},
"teams": [ /* 24 entries with full squads */ ]
}
Teams
GET /teams?tournament=YYYY
All teams in a single tournament — same data as tournaments/{year}.teams, just shorter to fetch when you don't need the meta block. Auth.
GET /teams/{name}
Cross-tournament summary for one team — every WC they appeared in, their final position, and squad-level goal totals. Auth.
GET /fifa/worldcup/v1/teams/Argentina
{
"name": "Argentina",
"appearances": [
{ "year": 1930, "finalPosition": 2, "groupStage": {…}, "squadSize": 19, "goalsScored": 18 },
…
{ "year": 2022, "finalPosition": 1, "groupStage": {…}, "squadSize": 26, "goalsScored": 15 }
]
}
URL-encode names with special characters: /teams/C%C3%B4te%20d%27Ivoire.
GET /teams/{name}/roster?year=YYYY
Squad list for a specific tournament. Each player has jersey, position, club, goals, and (when known) DOB / minutes / cards. Auth.
GET /fifa/worldcup/v1/teams/Argentina/roster?year=1986
[
{
"jersey": 10,
"name": "Diego Maradona",
"fullName": "Diego Armando Maradona",
"position": "MF",
"born": "1960-10-30",
"ageAtTournament": 25,
"club": { "name": "Napoli", "country": "Italy" },
"goals": 5,
"captain": true,
"starter": true
},
…
]
Players
GET /players?q=…&limit=…
Substring search (case-insensitive) over all squads. Returns up to limit matches (default 25, max 100). Auth.
GET /players/{name}
One player's career across every WC they appeared in. Looks up by exact name OR fullName. Auth.
GET /fifa/worldcup/v1/players/Diego%20Maradona
{
"name": "Diego Maradona",
"appearances": [
{ "year": 1982, "team": "Argentina", "position": "MF", "jersey": 10, "goals": 2, "captain": false, "club": {…} },
{ "year": 1986, "team": "Argentina", "position": "MF", "jersey": 10, "goals": 5, "captain": true, "club": {…} },
{ "year": 1990, "team": "Argentina", "position": "MF", "jersey": 10, "goals": 0, "captain": true, "club": {…} },
{ "year": 1994, "team": "Argentina", "position": "MF", "jersey": 10, "goals": 1, "captain": true, "club": {…} }
],
"totalGoals": 8,
"tournamentCount": 4
}
Other
GET /trivia?year=YYYY&category=X
Curated facts. Filters: year (matches scalar OR array), category (e.g. firsts, format, award). Auth.
GET /compare?years=1986,2022
Side-by-side metrics for 1-8 tournaments. Useful for analytics dashboards. Auth.
GET /aggregates/players?years=…
Position counts, birth-month distribution per position (north/south hemisphere split), confederation breakdown. Auth.
GET /aggregates/champions
Title counts per country + decade-by-decade winners. Auth.
Machine-readable spec: openapi.yaml. Source: github.com/zafronix/zafronix-wc-api.