OddsPortal APIoddsportal.com ↗
Access sports betting odds, match details, league standings, and bookmaker data from OddsPortal across 8+ sports via a structured REST API.
What is the OddsPortal API?
The OddsPortal API exposes 7 endpoints covering sports betting data across football, tennis, basketball, and five other sports — including match details with multi-market odds, league metadata, bookmaker ratings, and standings URLs. The get_match_details endpoint returns structured SportsEvent data alongside raw odds for markets including 1x2, over/under, Asian handicap, and both-teams-to-score. Tournament identifiers and bookmaker bitmasks from get_league_matches are required to navigate the data hierarchy.
No input parameters required.
curl -X GET 'https://api.parse.bot/scraper/866c8d40-aa7f-4f08-9d76-4cd26492cb04/get_all_sports' \ -H 'X-API-Key: $PARSE_API_KEY'
Typed, relational, agent-ready
A generated client with real types, enums, and the links between objects — the structure a flat JSON response can't carry. Autocompletes in your editor and reads cleanly to coding agents.
- Fully typed · autocompletes
- Objects link to objects
- Typed errors & pagination
Typed Python client. Set up the SDK in your uv project, then pull this API’s typed client:
uv add parse-sdk uv run parse init uv run parse add --marketplace oddsportal-com-api
uv run parse add --marketplace pulls a pinned snapshot of this canonical API — it won’t change underneath you. To customize it, subscribe and swap to your own copy.
from parse_apis.oddsportal_api import OddsPortal
oddsportal = OddsPortal()
# List all available sports
for sport in oddsportal.sports.list():
print(sport.name, sport.slug)
# Get leagues for football
football = oddsportal.sport("football")
for league in football.leagues():
print(league.country, league.name, league.slug)
# Get tournament metadata for Premier League
prem = oddsportal.league("premier-league")
metadata = prem.matches(sport="football", country="england")
print(metadata.tournament_id, metadata.bitmask, metadata.url)
# Get standings page URL
standings = prem.standings(sport="football", country="england")
print(standings.url, standings.sport)
# Get today's matches page
today = football.today()
print(today.url, today.sport)
# Get match details with odds
match = oddsportal.matchdetails.get(
home_team="aston-villa-W00wmLO0",
away_team="manchester-united-ppjDR086",
event_id="pOnfE84l",
)
print(match.match_id, match.url)
# List all bookmakers
for bm in oddsportal.bookmakers.list():
print(bm.name, bm.average_payout, bm.rating)
Get all available sports supported by OddsPortal. Returns a static list of sport names and URL slugs used to construct further queries.
No input parameters required.
{
"type": "object",
"fields": {
"sports": "array of sport objects each containing name and slug"
},
"sample": {
"data": {
"sports": [
{
"name": "Football",
"slug": "football"
},
{
"name": "Tennis",
"slug": "tennis"
},
{
"name": "Basketball",
"slug": "basketball"
},
{
"name": "Hockey",
"slug": "hockey"
},
{
"name": "Baseball",
"slug": "baseball"
},
{
"name": "American Football",
"slug": "american-football"
},
{
"name": "Handball",
"slug": "handball"
},
{
"name": "Rugby League",
"slug": "rugby-league"
}
]
},
"status": "success"
}
}About the OddsPortal API
Sports, Leagues, and Match Coverage
The API starts with get_all_sports, which returns a static list of sport names and their URL slugs. From there, get_sport_leagues accepts one of eight sport slugs — football, tennis, basketball, hockey, baseball, american-football, handball, or rugby-league — and returns major leagues with country, name, and slug fields. These slugs feed directly into get_league_matches, which requires sport, league, and country params and returns a tournament_id and bitmask string alongside the constructed page URL. Set is_results to true to retrieve metadata for the completed-matches page instead of upcoming fixtures.
Match Details and Odds Data
get_match_details takes a match_slug (formatted as <home-team>-<away-team>-<match-id>, obtainable from league pages) plus the sport, league, and country slugs. The response includes a details object structured as a Schema.org SportsEvent — covering teams, venue, and date — plus a match_id string and an odds_raw object keyed by market: 1x2, over_under, asian_handicap, and btts. The odds data is returned in a compressed, obfuscated format consistent with how OddsPortal encodes this information; consumers will need to decode it before use.
Bookmakers and Geo-Dependency
get_all_bookmakers returns the full bookmaker list with per-bookmaker fields including id, name, ratings, payout percentages broken down overall and per sport, bonus offer details, and feature flags. The response also includes tab_counts segmenting bookmakers into all, classic, and crypto categories. A note field in the response flags that results reflect geographic availability based on proxy IP location — the bookmaker set visible to the API may differ from what a user in another region would see.
Navigation Helpers
Two lightweight endpoints round out the API. get_today_matches accepts an optional sport slug and returns the URL for that sport's today-matches page, useful for polling fresh fixtures. get_league_standings returns the standings page URL for a given sport, league, and country combination — it does not return parsed standings data directly, only the URL string.
The OddsPortal API is a managed, monitored endpoint for oddsportal.com — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when oddsportal.com changes and a check fails, the API is automatically queued for repair and re-verified. It is built to keep working as the site underneath it changes.
This isn't an official oddsportal.com API — it's an independent, maintained REST wrapper over public data. Where the source has no official API (or only a limited one), Parse gives you a stable contract over a source that never promised one, and keeps it current. Need a new endpoint or field? You can revise it yourself in plain English and the agent rebuilds it against the live site in minutes — contributing the change back to the shared API is free.
Will this API break when the source site changes?+
Is this an official API from the source site?+
Can I fix or extend this API myself if I need a new endpoint or field?+
What happens if I call an endpoint that has an issue?+
- Aggregate 1x2, over/under, and Asian handicap odds from multiple bookmakers for a specific football match
- Build a league browser by iterating
get_sport_leaguesacross all eight supported sport slugs - Filter bookmakers by payout percentage or crypto support using fields from
get_all_bookmakers - Monitor today's upcoming fixtures across sports using
get_today_matcheson a polling schedule - Retrieve tournament IDs via
get_league_matchesto construct match-level data pipelines for a given competition - Compare bookmaker ratings and bonus offers for a target market segment using
tab_countscategory data - Store SportsEvent structured data (teams, venue, date) from
get_match_detailsfor historical match archiving
| Tier | Price | Credits/month | Rate limit |
|---|---|---|---|
| Free | $0/mo | 100 | 5 req/min |
| Hobby | $30/mo | 1,000 | 20 req/min |
| Developer | $100/mo | 5,000 | 100 req/min |
One credit = one API call regardless of which marketplace API you call. Exceeding the rate limit returns a 429 response. Authenticate with the X-API-Key header.
Does OddsPortal have an official developer API?+
What does the odds_raw field in get_match_details actually contain?+
odds_raw object is keyed by market name — 1x2, over_under, asian_handicap, and btts. The values within each market are in a compressed, obfuscated format that mirrors how OddsPortal encodes odds on its site. You will need to write a decoder to extract individual bookmaker lines and price values from this structure before the data is usable in calculations.Why might the bookmaker list differ between API calls?+
get_all_bookmakers response is geo-dependent: the set of bookmakers returned reflects which ones OddsPortal makes visible based on the proxy IP location used at request time. The response includes a note field that flags this behavior. Bookmakers available in one region may not appear for another, so the total count and the bookmakers array can vary across requests routed through different geographies.Does the API return parsed, tabular standings data for leagues?+
get_league_standings returns only the standings page URL for a given sport, league, and country — it does not parse the table rows, team positions, points, or win/draw/loss records into structured fields. You can fork this API on Parse and revise it to add an endpoint that parses standings table data for the leagues you need.Can I retrieve historical odds movement or line history for a match?+
get_match_details returns a snapshot of odds at the time of the request; there is no endpoint for opening lines, odds history, or timestamped movement data. You can fork this API on Parse and revise it to add a historical odds endpoint if that data is available on the match page.