RapidOddsAPIRapidOddsAPI

API Documentation

Everything you need to get started with the RapidOddsAPI

Getting Started

1. Create a free account to get your API key
2. Find your key in the dashboard
3. Start making requests

Authentication

Include your API key as a query parameter on every request. Your key starts with oa_ and can be found in your dashboard. Keep it secret — if compromised, regenerate it instantly.

Never expose your API key in client-side code (browser JavaScript, mobile apps, etc). Always make API calls from your backend server to keep your key secure.

Coverage

We cover 10+ leagues, 100+ bookmakers (including clones), and a wide range of market types including head-to-head, spreads, totals, and player props. Available markets vary by sport and bookmaker.

See our full coverage page for a complete list of all available leagues, bookmakers, and market types per sport.

Credits

Each request costs credits based on the number of market types and bookmakers requested:

credits = market_types × ⌈bookmakers / 5⌉

Every 5 bookmakers counts as 1 group (rounded up).

Examples

Market TypesBookmakersCredits
111
151
162
2104
3159

Credits are only deducted when data is returned. If your query returns no games, you are not charged.

Endpoint

One endpoint for everything. Choose your sport, pick the bookmakers and market types you want.

GET https://api.rapidoddsapi.com/sports/{sport_id}/markets?api_key={your_api_key}&market_type={market_type}&bookmaker={bookmaker}

Parameters

ParameterTypeRequiredDescription
sport_idpathYesSport identifier — see coverage
api_keyqueryYesYour API key
market_typequery (multi)YesMarket type. Repeat for multiple — see coverage
bookmakerquery (multi)YesBookmaker name. Repeat for multiple — see coverage

Example

GET https://api.rapidoddsapi.com/sports/NBA/markets?api_key=your_api_key&market_type=head_to_head&bookmaker=Sportsbet&bookmaker=DraftKings&bookmaker=Pinnacle
{ "sport": "NBA", "games": [ { "game": { "commence_time": "2026-02-14T10:00:00", "home_team": "Charlotte Hornets", "away_team": "Detroit Pistons" }, "bookmakers": [ { "name": "Sportsbet", "last_update": "2026-02-14T05:34:27", "markets": [ { "key": "head_to_head", "outcomes": [ { "name": "Detroit Pistons", "price": 1.65 }, { "name": "Charlotte Hornets", "price": 2.29 } ] } ] }, { "name": "DraftKings", "last_update": "2026-02-14T05:33:12", "markets": [ { "key": "head_to_head", "outcomes": [ { "name": "Detroit Pistons", "price": 1.62 }, { "name": "Charlotte Hornets", "price": 2.35 } ] } ] }, { "name": "Pinnacle", "last_update": "2026-02-14T05:34:01", "markets": [ { "key": "head_to_head", "outcomes": [ { "name": "Detroit Pistons", "price": 1.67 }, { "name": "Charlotte Hornets", "price": 2.31 } ] } ] } ] } ] }

Response

FieldTypeDescription
sportstringSport display name
games[]arrayList of games with odds
gameobjectGame details
commence_timestringGame start time (ISO 8601)
home_teamstringHome team name
away_teamstringAway team name
bookmakers[]arrayRequested bookmakers with data for this game
namestringBookmaker name
last_updatestringLast time odds were updated (ISO 8601)
markets[]arrayMarkets for this bookmaker
keystringMarket type identifier
outcomes[]arrayOdds outcomes for this market
namestringOutcome name (team or Over/Under)
pricenumberDecimal odds
pointnumberLine value — spreads, totals, and player props
player_namestringPlayer name — player props only
team_namestringTeam name — team markets only

Rate Limiting

All plans are limited to 30 requests per second per API key. Exceeding this limit returns a 429 error.

Error Codes

CodeMeaning
401Invalid API key
403Subscription is not active
404Sport not found
422Missing required parameter (api_key, market_type, or bookmaker)
429Insufficient credits or rate limit exceeded
500Internal server error

Code Examples

curl "https://api.rapidoddsapi.com/sports/NBA/markets?\ api_key=your_api_key&\ market_type=head_to_head&\ bookmaker=Sportsbet&\ bookmaker=DraftKings"

WebSocket

Real time odds pushed straight to you

Overview

The WebSocket feed pushes fresh odds data directly to you the moment each scraping cycle completes — no polling required. You connect once, subscribe to the sports and bookmakers you want, and receive updates automatically.

WebSocket access is included on the Pro and Elite plans. See pricing for details.

The data pushed over WebSocket is identical in structure to the REST endpoint response — the same sports, bookmakers, market types, and credit formula apply.

Connecting

Connect using your API key as a query parameter:

WSS wss://api.rapidoddsapi.com/ws?api_key=your_api_key

Once connected, the server sends a confirmation message:

{ "event": "connected", "tier": "pro", "message": "Send subscribe messages to start receiving odds data." }

Messages

Sending — Subscribe

After connecting, send a subscribe message to start receiving pushes for a sport. You can subscribe to multiple sports by sending one message per sport.

{ "action": "subscribe", "sport": "NBA", "bookmakers": ["Sportsbet", "DraftKings"], "market_types": ["head_to_head"] }

Sending — Unsubscribe

{ "action": "unsubscribe", "sport": "NBA" }

Receiving — Unsubscribed

{ "event": "unsubscribed", "sport": "NBA" }

Receiving — Subscribed

Sent immediately after a successful subscribe. Includes the credit cost per push for your subscription.

{ "event": "subscribed", "sport": "NBA", "bookmakers": ["Sportsbet", "DraftKings"], "market_types": ["head_to_head"], "credits_per_push": 1 }

Receiving — Odds Update

Sent each time a scraping cycle completes for your subscribed sport. The data field is identical in structure to the REST endpoint response.

{ "event": "odds_update", "sport": "NBA", "timestamp": "2026-02-25T10:00:00.000000", "credits_charged": 1, "data": { "sport": "NBA", "games": [ ... ] } }

Receiving — Error

{ "event": "error", "message": "Insufficient credits. Need 2, have 0." }

Credits

Credits are charged per push, not per connection. The same formula as the REST endpoint applies:

credits = market_types × ⌈bookmakers / 5⌉

The credit cost for your subscription is shown in the credits_per_push field of the subscribed confirmation. Credits are only deducted when a push contains data — if a scrape cycle returns no games, you are not charged.

If you have insufficient credits when a push is triggered, you will receive an error event and the push will be skipped.

Error Codes

WebSocket errors fall into two categories — connection rejections (before the connection is established) and in-session error events (sent as messages after connecting).

TypeCode / EventMeaning
ConnectionHTTP 403Invalid or missing API key, inactive subscription, or plan does not include WebSocket access
In sessionerrorInsufficient credits, invalid sport, missing bookmakers or market types, or unknown action

Code Examples

import asyncio import websockets import json async def main(): url = "wss://api.rapidoddsapi.com/ws?api_key=your_api_key" async with websockets.connect(url) as ws: # Connected confirmation connected = json.loads(await ws.recv()) print(connected["message"]) # Subscribe to a sport await ws.send(json.dumps({ "action": "subscribe", "sport": "NBA", "bookmakers": ["Sportsbet", "DraftKings"], "market_types": ["head_to_head"] })) sub = json.loads(await ws.recv()) print(f"Subscribed — credits per push: {sub['credits_per_push']}") # Receive pushes async for message in ws: data = json.loads(message) if data["event"] == "odds_update": games = data["data"]["games"] print(f"{len(games)} games — credits charged: {data['credits_charged']}") asyncio.run(main())