{"openapi":"3.1.0","info":{"title":"OpenFoot API","version":"1.0.0-beta","description":"A developer-first football data API combining current German data, Romanian and expanded European league datasets, open archives and derived analytics. Coverage, season metadata and source licenses are explicit; an uptime SLA is not included in this beta.","contact":{"name":"OpenFootAPI"}},"servers":[{"url":"https://openfootapi.com","description":"OpenFootAPI open-data beta"}],"tags":[{"name":"System","description":"API availability and metadata"},{"name":"Competitions","description":"Coverage, source and license information"},{"name":"Matches","description":"Fixtures, results and derived match context"},{"name":"Search","description":"Human-friendly entity lookup"}],"paths":{"/v1/health":{"get":{"operationId":"getHealth","tags":["System"],"summary":"Check API health","responses":{"200":{"description":"The API is operational","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}}}}},"/v1/account/quota":{"get":{"operationId":"getAccountQuota","tags":["Account"],"summary":"Inspect monthly quota without consuming requests","description":"Returns current billing-period usage for the supplied API key. Read-only: never consumes monthly quota.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Current period usage for the key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountQuotaResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimitExceeded"}}}},"/v1/competitions":{"get":{"operationId":"listCompetitions","tags":["Competitions"],"summary":"List supported competitions","security":[{},{"bearerAuth":[]}],"responses":{"200":{"description":"Competition coverage, source and licenses","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompetitionListResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/QuotaExceeded"}}}},"/v1/standings":{"get":{"operationId":"getStandings","tags":["Competitions"],"summary":"Get league standings table","description":"Returns the league table with total, home, and away splits, goal difference, points and recent form.","security":[{},{"bearerAuth":[]}],"parameters":[{"name":"competition","in":"query","required":true,"description":"Stable competition ID","schema":{"type":"string","example":"comp_bundesliga_de"}},{"name":"season","in":"query","required":false,"description":"Season label (e.g. 2024/25 or 2026)","schema":{"type":"string","example":"2024/25"}}],"responses":{"200":{"description":"Computed league standings","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StandingsResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/QuotaExceeded"}}}},"/v1/matches":{"get":{"operationId":"listMatches","tags":["Matches"],"summary":"List fixtures and results","description":"The public preview returns at most five matches. Developer access supports cursor pagination with up to 100 matches per page. Queries without a competition or team filter cover the flagship set (top-5 European leagues, major cups, Champions League, Superliga RO, MLS, Brasileirão); pass competition or team to reach the full catalog of 75 competitions.","security":[{},{"bearerAuth":[]}],"parameters":[{"name":"date","in":"query","description":"Kickoff date in YYYY-MM-DD","schema":{"type":"string","format":"date"}},{"name":"competition","in":"query","description":"Stable competition ID","schema":{"type":"string"}},{"name":"team","in":"query","description":"Stable team ID","schema":{"type":"string"}},{"name":"status","in":"query","schema":{"type":"string","enum":["scheduled","live","finished","postponed"]}},{"name":"season","in":"query","schema":{"type":"string","example":"2026/27"}},{"name":"round","in":"query","description":"Numeric matchday for providers that expose rounds","schema":{"type":"string","pattern":"^[0-9]{1,2}$","example":"34"}},{"name":"limit","in":"query","description":"Page size. Public requests remain capped at five items.","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"cursor","in":"query","description":"Opaque cursor from meta.pagination.next_cursor. Requires Developer access.","schema":{"type":"string","maxLength":100}}],"responses":{"200":{"description":"Matching fixtures and results","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MatchListResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/QuotaExceeded"},"502":{"$ref":"#/components/responses/SourceUnavailable"}}}},"/v1/matches/{id}/context":{"get":{"operationId":"getMatchContext","tags":["Matches"],"summary":"Get derived match context","description":"Returns both teams' form, Elo-style rating, rest, table position, venue record, head-to-head and field freshness. The public preview ID is match_olg_83156; other IDs require a Developer API key.","security":[{},{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Stable match ID","schema":{"type":"string","example":"match_olg_83156"}}],"responses":{"200":{"description":"Normalized match context","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MatchContextResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/ApiKeyRequired"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/QuotaExceeded"},"502":{"$ref":"#/components/responses/SourceUnavailable"}}}},"/v1/search":{"get":{"operationId":"searchEntities","tags":["Search"],"summary":"Search teams and competitions","description":"The public preview returns at most five search results.","security":[{},{"bearerAuth":[]}],"parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":2},"example":"bayern"}],"responses":{"200":{"description":"Matching entities","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/QuotaExceeded"}}}},"/v1/matches/{id}/events":{"get":{"operationId":"getMatchEvents","tags":["Matches"],"summary":"Get live key events and commentary timeline","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"example":"match_olg_83156"}],"responses":{"200":{"description":"Match events and minute-by-minute commentary"}}}},"/v1/matches/{id}/lineups":{"get":{"operationId":"getMatchLineups","tags":["Matches"],"summary":"Get starting XI, bench and tactical formations","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"example":"match_olg_83156"}],"responses":{"200":{"description":"Lineups and formations"}}}},"/v1/matches/{id}/xg":{"get":{"operationId":"getMatchXG","tags":["Analytics"],"summary":"Get granular shot maps and expected goals (xG) per shot","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"example":"match_olg_83156"}],"responses":{"200":{"description":"Shot map with coordinates and xG"}}}},"/v1/analytics/xg":{"get":{"operationId":"getLeagueXG","tags":["Analytics"],"summary":"Get league-wide expected goals and performance table","security":[{"bearerAuth":[]}],"parameters":[{"name":"league","in":"query","schema":{"type":"string","default":"epl"}}],"responses":{"200":{"description":"League xG table and match records"}}}},"/v1/odds":{"get":{"operationId":"getMatchOdds","tags":["Odds"],"summary":"Get bookmaker odds benchmark and implied fair probabilities","security":[{"bearerAuth":[]}],"parameters":[{"name":"matchId","in":"query","required":true,"schema":{"type":"string"},"example":"match_olg_83156"}],"responses":{"200":{"description":"Odds and win probability benchmark"}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API key","description":"Developer API keys use the fs_live_ prefix and are stored only as SHA-256 hashes."}},"responses":{"BadRequest":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"Unauthorized":{"description":"API key missing or invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"ApiKeyRequired":{"description":"A Developer API key is required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"NotFound":{"description":"The requested resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"QuotaExceeded":{"description":"The monthly request allowance is exhausted","headers":{"Retry-After":{"description":"Seconds until the monthly quota resets","schema":{"type":"integer"}},"RateLimit-Limit":{"schema":{"type":"integer"}},"RateLimit-Remaining":{"schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until reset","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"RateLimitExceeded":{"description":"Per-minute rate limit exceeded for the current plan","headers":{"Retry-After":{"description":"Seconds until the minute window resets","schema":{"type":"integer"}},"RateLimit-Limit":{"description":"Requests allowed per minute on the current plan","schema":{"type":"integer"}},"RateLimit-Remaining":{"schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until reset","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"SourceUnavailable":{"description":"An upstream open-data source is unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"schemas":{"Access":{"type":"object","required":["authenticated","plan"],"properties":{"authenticated":{"type":"boolean"},"plan":{"type":"string","example":"developer"},"quota":{"type":"integer"},"used":{"type":"integer"},"remaining":{"type":"integer"},"period":{"type":"string","example":"2026-08"}}},"StandingsStats":{"type":"object","required":["played","won","drawn","lost","goalsFor","goalsAgainst","goalDifference","points"],"properties":{"played":{"type":"integer"},"won":{"type":"integer"},"drawn":{"type":"integer"},"lost":{"type":"integer"},"goalsFor":{"type":"integer"},"goalsAgainst":{"type":"integer"},"goalDifference":{"type":"integer"},"points":{"type":"integer"}}},"StandingsRow":{"type":"object","required":["position","team","total","home","away","form"],"properties":{"position":{"type":"integer"},"team":{"type":"object","required":["id","name","shortName","code"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"shortName":{"type":"string"},"code":{"type":"string"},"logoUrl":{"type":["string","null"]}}},"total":{"$ref":"#/components/schemas/StandingsStats"},"home":{"$ref":"#/components/schemas/StandingsStats"},"away":{"$ref":"#/components/schemas/StandingsStats"},"form":{"type":"array","items":{"type":"string","enum":["W","D","L"]}}}},"StandingsResponse":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"object","required":["competitionId","competitionName","season","updatedAt","table"],"properties":{"competitionId":{"type":"string"},"competitionName":{"type":"string"},"season":{"type":"string"},"updatedAt":{"type":"string","format":"date-time"},"table":{"type":"array","items":{"$ref":"#/components/schemas/StandingsRow"}}}},"meta":{"$ref":"#/components/schemas/Meta"}}},"SourceAttribution":{"type":"object","required":["name","license","url","coverage"],"properties":{"name":{"type":"string","enum":["OpenLigaDB","OpenFootball","Football-Data.co.uk","Understat","ESPN"]},"license":{"type":"string"},"url":{"type":"string","format":"uri"},"coverage":{"type":"string"}}},"Meta":{"type":"object","required":["request_id","generated_at","environment"],"properties":{"request_id":{"type":"string","example":"req_19d5a7a8e7c4437d94"},"generated_at":{"type":"string","format":"date-time"},"environment":{"type":"string","enum":["beta"]},"count":{"type":"integer","minimum":0},"total_count":{"type":"integer","minimum":0},"preview_limit":{"type":["integer","null"]},"pagination":{"type":"object","required":["limit","next_cursor"],"properties":{"limit":{"type":"integer","minimum":1,"maximum":100},"next_cursor":{"type":["string","null"]}}},"access":{"$ref":"#/components/schemas/Access"},"sources":{"type":"array","items":{"$ref":"#/components/schemas/SourceAttribution"}}},"additionalProperties":true},"ErrorResponse":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string"},"message":{"type":"string"}}},"meta":{"type":"object","properties":{"request_id":{"type":"string"}}}}},"Team":{"type":"object","required":["id","name","shortName","code","logoUrl","country","competitionId"],"properties":{"id":{"type":"string","example":"team_olg_40"},"name":{"type":"string","example":"FC Bayern München"},"shortName":{"type":"string","example":"Bayern"},"code":{"type":"string","example":"FCB"},"logoUrl":{"type":["string","null"],"format":"uri","example":"https://i.imgur.com/v0tkpNx.png"},"country":{"type":"string","example":"Germany"},"competitionId":{"type":"string","example":"comp_bundesliga_de"}}},"Match":{"type":"object","required":["id","competitionId","season","kickoffAt","status","round","venue","homeTeam","awayTeam","score","updatedAt"],"properties":{"id":{"type":"string","example":"match_olg_83156"},"competitionId":{"type":"string"},"season":{"type":"string"},"kickoffAt":{"type":"string","format":"date-time"},"status":{"type":"string","enum":["scheduled","live","finished","postponed"]},"round":{"type":"string"},"venue":{"type":["string","null"]},"homeTeam":{"$ref":"#/components/schemas/Team"},"awayTeam":{"$ref":"#/components/schemas/Team"},"score":{"type":"object","properties":{"home":{"type":["integer","null"]},"away":{"type":["integer","null"]}}},"updatedAt":{"type":"string","format":"date-time"}}},"Competition":{"type":"object","required":["id","name","country","code","currentSeason","availableSeasons","coverage","source"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"country":{"type":"string"},"code":{"type":"string"},"currentSeason":{"type":"string"},"availableSeasons":{"type":"array","items":{"type":"string"}},"coverage":{"type":"object","additionalProperties":{"type":"boolean"}},"source":{"type":"object","required":["name","mode","license","url"],"properties":{"name":{"type":"string"},"mode":{"type":"string","enum":["current","archive","unavailable"],"description":"unavailable = no verified upstream currently serves fixtures for this competition"},"license":{"type":"string"},"url":{"type":"string","format":"uri"}}}}},"TeamContext":{"type":"object","properties":{"team":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"code":{"type":"string"}}},"form":{"type":"string","example":"WWDWW"},"pointsLast5":{"type":"integer"},"goalsScoredLast5":{"type":"integer"},"goalsConcededLast5":{"type":"integer"},"goalsAverage":{"type":"number"},"elo":{"type":"integer"},"tablePosition":{"type":["integer","null"]},"restDays":{"type":["integer","null"]},"venueRecord":{"type":"object","properties":{"wins":{"type":"integer"},"draws":{"type":"integer"},"losses":{"type":"integer"}}}}},"HealthResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"status":{"type":"string"},"version":{"type":"string"},"provider":{"type":"string"}}},"meta":{"$ref":"#/components/schemas/Meta"}}},"AccountQuotaResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"plan":{"type":"string"},"period":{"type":"string"},"quota":{"type":"integer"},"used":{"type":"integer"},"remaining":{"type":"integer"}}},"meta":{"$ref":"#/components/schemas/Meta"}}},"CompetitionListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Competition"}},"meta":{"$ref":"#/components/schemas/Meta"}}},"MatchListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Match"}},"meta":{"$ref":"#/components/schemas/Meta"}}},"MatchAnalytics":{"type":"object","description":"Derived analytical modeling including goal expectancy, odds benchmark, momentum, and team radar","properties":{"expectedGoals":{"type":"object","properties":{"homeXG":{"type":"number","example":1.65},"awayXG":{"type":"number","example":1.12},"totalExpectedGoals":{"type":"number","example":2.77}}},"oddsBenchmark":{"type":"object","properties":{"impliedHomeWinPct":{"type":"number","example":52.4},"impliedDrawPct":{"type":"number","example":26.1},"impliedAwayWinPct":{"type":"number","example":21.5},"projectedFairOdds":{"type":"object","properties":{"home":{"type":"number","example":1.91},"draw":{"type":"number","example":3.83},"away":{"type":"number","example":4.65}}}}},"momentum":{"type":"object","properties":{"homeAttackPressure":{"type":"number","example":64},"awayAttackPressure":{"type":"number","example":36},"dominanceIndicator":{"type":"string","enum":["home_dominant","balanced","away_dominant"]},"restAdvantageDays":{"type":"number","example":2},"fatigueRisk":{"type":"string","enum":["low","moderate","high"]}}},"radar":{"type":"object","properties":{"home":{"type":"object","additionalProperties":{"type":"number"}},"away":{"type":"object","additionalProperties":{"type":"number"}}}}}},"MatchContextResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"match":{"$ref":"#/components/schemas/Match"},"home":{"$ref":"#/components/schemas/TeamContext"},"away":{"$ref":"#/components/schemas/TeamContext"},"headToHead":{"type":"object","additionalProperties":{"type":"integer"}},"analytics":{"$ref":"#/components/schemas/MatchAnalytics"},"freshness":{"type":"object","additionalProperties":{"type":"string","format":"date-time"}}}},"meta":{"$ref":"#/components/schemas/Meta"}}},"SearchResponse":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["team","competition"]},"id":{"type":"string"},"name":{"type":"string"},"subtitle":{"type":"string"}}}},"meta":{"$ref":"#/components/schemas/Meta"}}}}}}