WorldCups.ai API
The WorldCups.ai API gives programmatic access to the WorldCups.ai database. You can download tables as CSV files, run SQL queries directly against the database, and ask natural language questions powered by the same AI engine as he WorldCups.ai's AI assistant.
Base URL:
https://worldcups.ai/api/v1API access requires a subscription. Manage your API keys from your account page.
Authentication
All requests must include your API key as a bearer token in the
Authorization header.Authorization: Bearer YOUR_API_KEY
API keys are prefixed with
wc_. You can generate and revoke keys from your account page. Keys are shown only once at creation — store them securely.Rate limits
Each endpoint has a separate monthly request limit. Limits reset on the first day of each month at midnight UTC. Limits are per API key, not per account — if you have multiple keys, each has its own limit. You can have up to 5 API keys at a time.
Every response includes the following headers:
When you exceed a limit, the API returns a
429 response.Errors
All errors return a JSON object with
error and code fields.{
"error": "Invalid or revoked API key.",
"code": "unauthorized"
}
Endpoints
Download a table
Downloads a table from the WorldCups.ai database as a CSV file.
GET /download/:table
Path parameters
Query parameters
Example
curl -X GET "https://worldcups.ai/api/v1/download/matches?version=curated" \
-H "Authorization: Bearer YOUR_API_KEY" \
--output matches.csv
Valid table names
The following tables are available for download. See the database documentation for full details on each table.
Entity tables:
tournaments, confederations, teams, matches, players, managers, referees, stadiums, awardsTournament tables:
host_countries, tournament_stages, groups, group_standings, tournament_standings, award_winnersRegistration tables:
qualified_teams, squads, manager_appointments, referee_appointmentsAppearance tables:
team_appearances, player_appearances, manager_appearances, referee_appearancesEvent tables:
goals, bookings, substitutions, penalty_kicksResponse
Returns a CSV file with the content type
text/csv. The filename is {table}_{version}.csv.Query with SQL
Executes a SQL
SELECT query against the WorldCups.ai database and returns the results.POST /query
Request body
Only
SELECT and WITH statements are permitted. All tables are in the worldcupsai schema.Example
curl -X POST "https://worldcups.ai/api/v1/query" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"sql": "SELECT p.family_name, p.given_name, COUNT(*) AS goals FROM worldcupsai.goals g JOIN worldcupsai.players p ON g.player_id = p.player_id WHERE g.own_goal = FALSE GROUP BY p.player_id, p.family_name, p.given_name ORDER BY goals DESC LIMIT 10",
"format": "json"
}'
Response (JSON)
{
"data": [
{ "family_name": "Klose", "given_name": "Miroslav", "goals": 16 }
],
"total_rows": 10,
"meta": {
"executed_at": "2024-01-15T12:00:00.000Z"
}
}
Ask a question
Asks a natural language question about World Cup history. The API generates a SQL query, executes it, and returns a written answer along with the underlying data.
POST /ask
Request body
Example
curl -X POST "https://worldcups.ai/api/v1/ask" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"question": "Who has scored the most World Cup goals of all time?",
"category": "men",
"format": "json"
}'
Response (JSON)
{
"answer": "Miroslav Klose holds the record with 16 goals across four tournaments.",
"sql": "SELECT ...",
"data": [
{ "family_name": "Klose", "given_name": "Miroslav", "goals": 16 }
],
"total_rows": 1,
"meta": {
"executed_at": "2024-01-15T12:00:00.000Z",
"question": "Who has scored the most World Cup goals of all time?",
"category": "men",
"confidence": 0.95
}
}
CSV format
When
format is csv, the response contains the raw data rows only — the answer and sql fields are not included. Use JSON format if you need the written answer.Example: Python
import requests
API_KEY = "YOUR_API_KEY"
BASE_URL = "https://worldcups.ai/api/v1"
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
}
# Ask a question
response = requests.post(
f"{BASE_URL}/ask",
headers=headers,
json={
"question": "Which countries have won the World Cup and how many times?",
"category": "men",
}
)
data = response.json()
print(data["answer"])
for row in data["data"]:
print(row)
Example: R
library(httr2)
API_KEY <- "YOUR_API_KEY"
BASE_URL <- "https://worldcups.ai/api/v1"
# Run a SQL query and load results into a data frame
response <- request(paste0(BASE_URL, "/query")) |>
req_headers(
Authorization = paste("Bearer", API_KEY),
`Content-Type` = "application/json"
) |>
req_body_json(list(
sql = "SELECT team_name, COUNT(*) AS matches FROM worldcupsai.team_appearances GROUP BY team_name ORDER BY matches DESC LIMIT 20",
format = "json",
limit = 20
)) |>
req_perform() |>
resp_body_json()
df <- do.call(rbind, lapply(response$data, as.data.frame))
Example: Download a table
import requests
API_KEY = "YOUR_API_KEY"
BASE_URL = "https://worldcups.ai/api/v1"
response = requests.get(
f"{BASE_URL}/download/goals",
headers={"Authorization": f"Bearer {API_KEY}"},
params={"version": "curated"},
)
with open("goals.csv", "wb") as f:
f.write(response.content)