# FDB4 — full reference for language models > A football (soccer) results database covering national-team football, domestic leagues > and domestic and continental cups, from the 19th century to yesterday. Its speciality is > draws: for every team it tracks the draw rate, the current run without a draw, the > longest runs ever, and from those a ranking of which teams are most overdue a draw. > Reachable as a website, a REST API and an MCP server. This file is the complete machine-readable reference. The short index is at https://fdb4.io/llms.txt. The human version of the REST section is at https://fdb4.io/api and of the MCP section at https://fdb4.io/mcp — one page each, because they are priced differently: /v1 is paid outright, /mcp has a free tier. Everything here is historical statistics. It is not betting advice and must not be presented as a forecast of any individual match: https://fdb4.io/not-betting-advice ================================================================================ 1. WHAT IS IN THE DATABASE ================================================================================ MATCHES Every match the archive covers, with date, competition, edition/season, both teams, the 90-minute score, the final score where a tie was settled after it, and a status (PLAYED, SCHEDULED, POSTPONED, ABANDONED, CANCELLED, AWARDED). Statistics count PLAYED matches only. Results and draw logic use the 90-minute score, so a cup tie decided on penalties is a draw here. COMPETITIONS AND EDITIONS National-team tournaments (World Cups, continental championships, qualifiers, friendlies), domestic leagues, domestic cups and the European club cups. Each competition has editions — one per season or tournament — each with its own matches and, where one was decided, a champion and a runner-up. TEAMS National teams and clubs, each with a country, a slug, a numeric id and a full set of derived draw statistics: matches played, draws, draw percentage, the no-draw run currently in progress, the longest run ever, the average of its longest runs, and the probability signals the draw score is built from. NO-DRAW STREAKS A no-draw streak is a run of consecutive matches that all ended in a win or a loss. Every recorded run is stored with its length, start and end dates and the matches that bound it, which is what makes the all-time leaderboard possible. THE DRAW PREDICTOR A team that draws often but has not drawn for a long time is carrying "draw debt". The predictor turns that into a score and a global rank across the field, so the whole set of teams can be ordered by how overdue a draw each one is. Filters subset which teams are listed; a team's score and rank are global and do not change with the filter. HEAD TO HEAD The complete record between any two teams: matches played, wins each way, draws, goals each way, draw percentage, and every meeting. HONOURS Champions and runners-up per edition, plus all-time winners rankings with title counts and the years each title was won. ================================================================================ 2. AUTHENTICATION ================================================================================ Both machine surfaces take the same key in the same header: Authorization: Bearer To get one: sign in with Google at https://fdb4.io/login, then create a key at https://fdb4.io/account. The plaintext is shown exactly once. One key opens both the REST API and the MCP server, and both draw on one balance and one rate limit; an account may hold several keys and they all share that balance. There is no other way in for /v1. The REST API is closed by default: with no key, every request 401s. THE MCP SERVER HAS A FREE TIER, AND THE REST API DOES NOT. /mcp accepts a request with no Authorization header at all. Six of its eleven tools then answer in full; the other five return a tool error result carrying `key_required` (see section 5) rather than data. /v1 is unchanged and still refuses every keyless request — the REST API is the paid product. A key that IS sent and is invalid, revoked or expired is refused on both surfaces. Sending a bad key is an error; sending none is a choice. Deviation worth knowing: the MCP specification's authorization section expects OAuth 2.1 with dynamic client registration. FDB4 uses static bearer keys instead. Any client that can send a custom header works; a client that only speaks OAuth will not connect. ================================================================================ 3. PRICING ================================================================================ 1 call = 1 point = 1 cent. That is the whole price list. A REST request costs one point. A paid MCP tool invocation costs one point. A paginated call costs one point per page, so a query that asks for what it needs in one call is cheaper than one that walks pages. A cached answer still costs a point — it is still an answer. FREE MCP TOOLS — no key, no balance, no charge to a key holder either: list_countries reference data list_tournaments reference data, including one competition in full list_teams the identity lookup every other tool needs first get_team one team's profile and draw statistics get_team_streaks every no-draw run a team has had, and the one it is on search_results the first page of 50, and any `from` date inside the last 7 days The rule behind that line: a tool is free when its answer comes from a table an indexer already filled and the query is bounded; it is paid when the answer is a model's output, a ranking over the whole field, or an unbounded slice of history. The same two groups are laid out for a person at https://fdb4.io/mcp, built from the running server's own tool registry rather than restated — so they cannot disagree with this list. PAID MCP TOOLS — 1 point each: predict_draws the ranking over the whole field get_team_prediction one team's place in that ranking get_draw_model every draw reading for one fixture: the goals model, the Elo gap rate, the published blend, the logistic model and the market price top_streaks the all-time leaderboard head_to_head a full pairwise history search_results beyond the free window: an older `from`, `limit` above 50, or any page after the first Also free of charge: connecting to the MCP server (initialize), listing its tools (tools/list), ping, any request refused by the rate limiter (429), and any request that fails to authenticate (401). - New accounts are granted 10 points on creation. - Accounts that have signed in (or made an authenticated call) within the last month receive 2 more points every month, automatically. - Referrals pay the referrer 10% of every point their referee is ever credited — welcome grants, monthly grants and purchases alike. See https://fdb4.io/account/referral - Top up at https://fdb4.io/account/balance. You choose the amount; payment is in crypto against a published wallet address. NO REFUNDS, EVER. The product is data, and data cannot be returned. This is stated before purchase, on the purchase form, and here. Keys issued before accounts existed (no owner account attached) are not charged. They keep working until they are attached to an account, at which point they start paying. ================================================================================ 4. RATE LIMITS ================================================================================ Every key carries its own per-minute cap (120 by default). REST and MCP share that one budget: a key allowed 120 a minute gets 120 requests a minute across both surfaces combined, not 120 each. On the MCP server one JSON-RPC message is one HTTP request, so one tool invocation counts as one. Callers with no key are capped per IP address before authentication. On /v1 that is a burst guard on the 401 — 20 requests a minute. On /mcp, where a keyless caller gets real answers, it is a budget: 60 requests an hour per address, counting every JSON-RPC message including initialize and tools/list. A caller holding a key skips that budget entirely and meets its own per-minute cap instead. Responses carry X-RateLimit-Limit and X-RateLimit-Remaining. A 429 additionally carries Retry-After and X-RateLimit-Reset, and costs no points. ================================================================================ 5. ERROR CONTRACTS ================================================================================ The `code` values are stable and safe to branch on; the prose is not. 401 — no valid key The bearer token is missing, unknown, revoked or expired. { "message": "Missing API key. Send it as \"Authorization: Bearer \".", "documentation": "https://fdb4.io/api", "request_key": "https://fdb4.io/api#getting-a-key" } 402 — out of points The account behind the key has less than one point left. Nothing was charged and no data was returned. Do not retry; top up or wait for the monthly grant. { "error": { "code": "insufficient_balance", "balance": 0, "top_up_url": "https://fdb4.io/account/balance", "monthly_grant": 2 } } Over MCP this same JSON comes back as a tool ERROR RESULT (isError: true) with a human-readable sentence in front of it — not as an HTTP status and not as a JSON-RPC transport error — so an agent can read it and tell its user what happened. key_required — a paid MCP tool, called with no key MCP only, and not an HTTP status: a tool error result (isError: true) with a sentence in front of the JSON. Nothing was charged and no data was returned. Either call one of the `free_tools` instead, or tell the user they can create a free key at `sign_up_url` — do not retry the same call unauthenticated. { "error": { "code": "key_required", "tool": "get_draw_model", "free_tools": ["get_team_streaks", "list_teams", "get_team", "list_tournaments", "list_countries", "search_results"], "sign_up_url": "https://fdb4.io/login?next=%2Faccount", "documentation": "https://fdb4.io/api", "welcome_points": 10, "monthly_grant": 2, "price": "1 call = 1 point = 1 cent" } } 429 — rate limited Over the key's per-minute cap, or over 60 calls an hour if you hold no key. Carries Retry-After. Costs no points. 404 — no such record A team, competition or edition id/slug that does not exist. Over MCP this is a tool error result explaining where valid ids come from. 422 — invalid parameters Laravel's standard {"message", "errors"} validation body. Over MCP the validation messages come back as a tool error result. ================================================================================ 6. REST API — https://fdb4.io/v1 ================================================================================ Read-only JSON. Every endpoint is GET; nothing here writes. Responses are UTF-8 and wrap their payload in a `data` key; paginated endpoints add `meta` and `links`. curl -H "Authorization: Bearer $FDB_API_KEY" https://fdb4.io/v1/predictor?limit=10 GET /v1/countries Every country, ordered by name. - q (string): Match on country name prefix or exact FIFA code. Example: https://fdb4.io/v1/countries?q=eng GET /v1/tournaments Competitions in catalogue order, with precomputed match and draw counts. Example: https://fdb4.io/v1/tournaments GET /v1/tournaments/{id} One competition with its coverage span, every edition (newest first, with the champion where one is decided) and the all-time winners ranking. Accepts a numeric id or a slug. - id (path): Numeric competition id or slug (e.g. 53 or norway-cup). Example: https://fdb4.io/v1/tournaments/norway-cup GET /v1/teams Teams ordered by name, filterable by type, initial letter and name prefix. - type (string): national_team or club. - letter (string): First letter A–Z, or # for non-letter initials. - q (string): Name prefix, matched against short and full name. Example: https://fdb4.io/v1/teams?type=club&letter=A GET /v1/teams/{id} One team with its all-competitions draw statistics. Accepts a numeric id or a slug. - id (path): Numeric team id or slug (e.g. 431 or arsenal). Example: https://fdb4.io/v1/teams/arsenal GET /v1/teams/{id}/streaks A team's active no-draw run (with its matches) plus every recorded all-time run. - id (path): Numeric team id or slug. - league_only (boolean): Reserved. Accepted but currently ignored — runs span all competitions. Example: https://fdb4.io/v1/teams/arsenal/streaks GET /v1/predictor Teams ranked by draw likelihood, most "due" a draw first. Filters subset which teams are listed; the score and rank are global and never change with them. - type (string): national_team or club. Omit to rank both together. - recent (boolean): Only teams with a match in the last few months. Default true. - wc2026 (boolean): Restrict to the World Cup 2026 team group. Default false. - limit (integer): How many ranked teams to return, max 500. Default 100. Example: https://fdb4.io/v1/predictor?type=club&limit=25 GET /v1/predictor/{id} One team's draw prediction plus its recent form. The prediction is null when the team exists but is not a ranked candidate. - id (path): Numeric team id or slug. - recent (boolean): Match the ranking filter used by /v1/predictor. Default true. - wc2026 (boolean): Rank within the World Cup 2026 group. Default false. Example: https://fdb4.io/v1/predictor/arsenal GET /v1/draw-model Every draw reading held for one fixture: the goals model, the draw rate at its Elo gap, the published blend, the logistic model with its 95% band, and the market price where one exists. Two readings are published at once on purpose — the one-parameter blend the site has shown since September 2026 and the five-feature logistic model measured to beat it out of sample — and neither has replaced the other. `logistic.is_forecast` is false for a played match, whose logistic figure is in sample because the model was fitted on all of history. - match (integer): Match id. Required unless team is given. - team (string): Team id or slug. Required unless match is given. - date (date): With team: the match date (YYYY-MM-DD). Omit for that team's next fixture. Example: https://fdb4.io/v1/draw-model?team=arsenal GET /v1/results Played matches, newest first, paginated. Same filter names as the results browser. - type (string): national_team or club. - competition_id (integer): Restrict to one competition. - competition_item_id (integer): Restrict to one edition/season. - team_id (integer): Matches involving this team, home or away. - outcome (string): H (home win), A (away win) or D (draw). - from (date): Earliest match date, inclusive (YYYY-MM-DD). - to (date): Latest match date, inclusive (YYYY-MM-DD). - limit (integer): Page size: 50, 100, 250 or 500. Default 100. - page (integer): Page number. Default 1. Example: https://fdb4.io/v1/results?team_id=431&outcome=D&from=2020-01-01 GET /v1/h2h Head-to-head record between two teams, from team A's perspective, plus every meeting. - a (integer): Team A id. Required. - b (integer): Team B id. Required, must differ from a. - type (string): Restrict to one competition type. - item (integer): Restrict to one edition/season id. Example: https://fdb4.io/v1/h2h?a=431&b=447 GET /v1/streaks/top All-time leaderboard of no-draw runs, longest first. A team may appear more than once. - min (integer): Minimum run length. Default 5. - team_id (integer): Restrict to one team. - type (string): national_team or club. - limit (integer): Page size, max 500. Default 50. - page (integer): Page number. Default 1. Example: https://fdb4.io/v1/streaks/top?min=20&type=club ================================================================================ 7. MCP SERVER — https://fdb4.io/mcp ================================================================================ The same data spoken to AI clients over the Model Context Protocol, via streamable HTTP. Eleven tools, one per REST endpoint, delegating to the same code — a field means the same thing on both surfaces. Endpoint https://fdb4.io/mcp (POST; DELETE answers 405, and so does a GET asking for text/event-stream — the server pushes nothing on its own. Any other GET is the human documentation page for this section.) Transport Streamable HTTP, JSON-RPC 2.0. Responses are application/json. Auth Authorization: Bearer , or none at all — see below Cost 6 of the 11 tools are free and need no key; the other 5 cost 1 point per invocation. initialize, tools/list and ping are always free. Keyless 60 calls an hour per IP address CONNECTING WITHOUT A KEY Leave the header off. The reference tools, a team's current no-draw run and the last week of results answer as normal; a paid tool returns a `key_required` tool error naming what a key costs and where to get one. A free answer carries a second content block — one sentence saying what a key adds — after the JSON payload; the payload itself is the same document the REST endpoint serves, unchanged. claude mcp add --transport http fdb4 https://fdb4.io/mcp CLIENT CONFIGURATION Claude Code (one command): claude mcp add --transport http fdb4 https://fdb4.io/mcp \ --header "Authorization: Bearer YOUR_KEY" Claude Desktop (claude_desktop_config.json), Cursor (.cursor/mcp.json) and anything else taking the same shape: { "mcpServers": { "fdb4": { "type": "http", "url": "https://fdb4.io/mcp", "headers": { "Authorization": "Bearer YOUR_KEY" } } } } Raw JSON-RPC, for a client you are writing yourself: curl -X POST https://fdb4.io/mcp \ -H "Authorization: Bearer $FDB_API_KEY" \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","id":1,"method":"tools/call", "params":{"name":"predict_draws","arguments":{"type":"national_team","limit":10}}}' TOOLS Every tool returns its payload as JSON text, identical to what the matching REST endpoint serves. List tools return the first 25 rows by default alongside the true total and a hint for narrowing; if `total` exceeds `returned`, filter rather than paging blindly. Each tool below is marked FREE (no key needed) or 1 POINT. predict_draws — 1 POINT Rank teams by how overdue a draw is — the question this database exists to answer. Arguments: type, recent, wc2026, limit get_team_prediction — 1 POINT How overdue a draw one named team is, plus the results that made it so. Arguments: team (required), recent, wc2026 get_draw_model — 1 POINT Every draw reading FDB4 holds for ONE match — use it when someone asks how likely a specific fixture is to end level, rather than which teams are overdue a draw (`predict_draws` answers that). Arguments: match_id, team, date top_streaks — 1 POINT The all-time leaderboard of no-draw runs — the longest any team has gone without drawing. Arguments: min, team_id, type, limit, page get_team_streaks — FREE Every no-draw run one team has ever had, plus the one it is on now. Arguments: team (required) list_teams — FREE Find a team and its id — the lookup every other team tool depends on. Arguments: q, type, letter, limit get_team — FREE One team's profile and its all-time draw statistics. Arguments: team (required) list_tournaments — FREE Every competition covered — leagues, domestic cups, continental cups, World Cups — with how many matches and how many draws each one holds. Arguments: tournament, limit list_countries — FREE Every country in the database, with its FIFA code and id. Arguments: q, limit search_results — FREE for the last 7 days, otherwise 1 POINT Search the match archive: played matches, newest first, with scores. Free without a key when `page` is 1 or absent, `limit` is 50 or absent, and `from` (if given) is inside the last 7 days. Anything reaching further back costs 1 point per page. Arguments: team_id, competition_id, competition_item_id, outcome, type, from, to, limit, page head_to_head — 1 POINT The complete record between two teams, and every match they have ever played. Arguments: a (required), b (required), type, item ================================================================================ 8. WEB PAGES ================================================================================ Public, indexable, no key needed: https://fdb4.io/ home https://fdb4.io/predictor draw predictor https://fdb4.io/streaks longest no-draw streaks https://fdb4.io/results results archive https://fdb4.io/h2h head to head https://fdb4.io/tournaments competitions https://fdb4.io/teams teams https://fdb4.io/tables league tables https://fdb4.io/charts charts: streak timeline, draw rate by era, coverage, draw scores https://fdb4.io/api API reference https://fdb4.io/not-betting-advice what this site is and is not https://fdb4.io/sitemap.xml sitemap index Account pages, behind a Google sign-in: https://fdb4.io/login sign in https://fdb4.io/account API keys https://fdb4.io/account/balance balance and top-up https://fdb4.io/account/referral referral programme ================================================================================ 9. NOTES FOR AGENTS ================================================================================ - Start with ids. list_teams (or /v1/teams?q=) turns a name into the numeric id and slug every other tool takes; list_tournaments does the same for competitions and their editions. - The draw score is field-relative: it is normalised against the set of teams in view, so scores are comparable within one listing rather than across different filters. Ranks are global. - Dates and results are 90-minute outcomes; penalty shootouts do not turn a draw into a win. - Ask for what you need in one call. Each page costs its own point. - Cache responsibly and identify yourself with a User-Agent. - Usage policy for crawling, training and inference: https://fdb4.io/ai.txt - Contact: https://fdb4.io/feedback