Quickstart.
Three lines.
That returns Granit Xhaka's full profile JSON — biographics, current club, contract, all 8 external IDs. Same shape for any player. The same pattern (predicate filtering, embedding) works on every resource.
Authentication.
Public reads work without a key (rate-limited per-IP). Authenticated reads use x-api-key header.
Free tier: 5,000 req/month. Pro: 250k. Commercial: unlimited. Keys can be scoped (read-only, write-allowed for auth flows, etc.) and can be revoked from the dashboard.
Filtering.
Operators on every column. Same pattern Postgrest uses.
| Operator | Meaning | Example |
|---|---|---|
eq | equal | ?country=eq.IT |
gt / gte / lt / lte | compare | ?height_cm=gte.190 |
in | any of | ?position=in.(GK,DF) |
like / ilike | SQL LIKE | ?name=ilike.*haaland* |
not.eq | negation | ?retired=not.eq.true |
or / and | compose | ?or=(goals.gte.20,assists.gte.15) |
order | sort | ?order=goals.desc,name.asc |
Embedding.
Pull related rows in one request.
One round-trip. Embedding follows foreign keys. Use the alias syntax (home:teams!matches_home_team_id_fkey) when there are multiple FKs to the same table.
Pagination & limits.
Either ?limit=50&offset=100 or HTTP Range header (Range: 0-99). Default page size 100, max 1000. Use Prefer: count=exact to get total count in the Content-Range header.
Players.
412k profiles. Same schema for every player.
| Field | Type | Description |
|---|---|---|
| id | int | Internal player ID. |
| name | text | Display name. |
| date_of_birth | date | YYYY-MM-DD. |
| country_id | int | FK → countries. |
| position | enum | GK | DF | MF | FW. |
| detailed_position | enum | CB, RB, DM, AM, RW, ST, etc. |
| height_cm | int | Height in cm. |
| preferred_foot | enum | L | R | Both. |
| external_ids | jsonb | Cross-reference IDs (Wikidata + other public ID systems). |
MCP server.
Anthropic's Model Context Protocol means LLMs (Claude, GPT-4, local models) can query foot.io in natural language without you writing the queries.
The MCP server exposes 12 high-level tools (search_players, list_matches, get_table, …) that compose the underlying REST. The LLM picks the right tool, gets typed results, and synthesises an answer.
Webhooks (Pro+).
We POST to your endpoint when something interesting happens. Events: transfer.completed, match.kicked_off, match.finished, injury.reported, card.shown, goal.scored.