Sports odds
in one API
Normalized odds from dozens of bookmakers — including the Italian books global APIs lack — in a stable JSON format. For your models, bots and tools.
# one request, all the odds for an event curl "https://odss-api.com/api/v1/odds?sport=calcio&league=serie%20a" \ -H "x-api-key: odss_live_..." { "count": 118, "offset": 0, "returned": 118, "state": "prematch", "odds": [{ "event_id": "a3f9c1e07b2d4865", "event": "Inter - Milan", "league": "Serie A", "market": "1x2", "commence_time": "2026-08-23T18:45:00Z", "bookmakers": [ { "key":"snai", "outcomes":{"HOME":2.10,"DRAW":3.40,"AWAY":3.60}, "last_update":"2026-07-14T10:32:05Z" }, { "key":"bet365", "outcomes":{"HOME":2.05,"DRAW":3.50,"AWAY":3.70}, "last_update":"2026-07-14T10:28:12Z" } ]}]}
Bookmakers in the feed
Three moves to integrate the odds
Create a key
Sign up and generate an odss_live key in a minute. The Free plan is forever, no card required.
Call /odds
One endpoint, all cross-book odds by event and market. Filter by sport, league, market and bookmaker.
Integrate and sync
Stable event_id to recognize events, last_update for freshness, offset to read the whole schedule.
The moat: Italian books.
The ADM bookmakers global APIs don't have
Sisal, SNAI, Eurobet, GoldBet, Planetwin365, Betflag and dozens more Italian books, read directly. Plus bet365, Betfair Exchange and Pinnacle as sharp references.
Stable schema
A public, versioned JSON format: the engine's internal shape never leaks into your code.
Reliable integration
Deterministic event_id for the whole prematch window, ISO last_update per book, offset pagination: no-surprise syncs.
Honest freshness
Italian books run on a continuous cycle and the real freshness is measured and public, per book, on the status page; bet365 and Betfair arrive via partner feeds with a cadence of a few minutes. Every quote declares its last_update: no stale numbers dressed up as live.
The honest comparison.
Where we stand vs global APIs and the market average. No names, no promises.
Comparison against the average of the global/enterprise providers reviewed (Jul 2026). Our side is verifiable from the public endpoints and the docs.
Bookmakers & leagues
Live numbers, counted from the feed right now — not a catalog inventory.
—
bookmakers active in the feed
—
sports priced right now
—
leagues on the board
Leagues on the board right now
Live data from the feed (public endpoint /api/v1/leagues): for each sport, the leagues currently priced. Names are the values for the league filter.
Loading the schedule…
The board follows the season: club football is naturally thinner in summer.
Documentation
Base URL https://odss-api.com. Authenticate with the x-api-key: odss_live_… header or Authorization: Bearer. JSON responses, European decimal odds.
First call in 3 steps
Create a key
Sign up and generate a key in the dashboard. The Free plan is forever.
List sports
Verify the key with a call to /sports.
Get odds
Call /odds with sport and market: you get cross-book odds.
GET /api/v1/odds example
curl "https://odss-api.com/api/v1/odds?sport=calcio&league=serie%20a&limit=5" \ -H "x-api-key: odss_live_..."
const r = await fetch(
"https://odss-api.com/api/v1/odds?sport=calcio&league=serie%20a&limit=5",
{ headers: { "x-api-key": "odss_live_..." } }
);
const { count, odds } = await r.json();
import requests
r = requests.get(
"https://odss-api.com/api/v1/odds",
params={"sport": "calcio", "league": "serie a", "limit": 5},
headers={"x-api-key": "odss_live_..."},
)
data = r.json() # { count, offset, returned, state, odds: [...] }
GET /api/v1/odds
Current cross-book odds, grouped by event, market and line. Each record lists the bookmakers with their outcomes and the timestamp of their last update.
Parameters
| Parameter | Description |
|---|---|
| sport | Exact sport filter (e.g. calcio, tennis, basket). Values: see /api/v1/sports. |
| market | Canonical market: 1x2, ou, btts, dc, handicap, moneyline… |
| bookmakers | CSV list of book keys (e.g. snai,bet365). Values: see /api/v1/bookmakers. |
| league | Case-insensitive substring filter (e.g. serie a). Values: see /api/v1/leagues. |
| event_id | A single event, by exact id. |
| state | prematch (default), live (in-play, with current score and minute) or all (both). With live, if the in-play engine is off the list is empty and live_enabled=false. If the key has a feed scope (prematch-only or live-only), a state outside the scope returns 403 and all degrades to the allowed state. |
| limit | Records per page. Default 500, max 2000. |
| offset | Start index for pagination. Default 0. |
Response fields
| Field | Description |
|---|---|
| count | Total records matching the filters (across all pages). |
| offset · returned | Echo of the requested offset and the records actually returned in this page. |
| odds[].event_id | Deterministic event id: identical for every market of the same fixture and stable for the whole prematch window. |
| odds[].event | Normalized event name (Home - Away). |
| odds[].sport · league | Sport and league/competition of the event. |
| odds[].home_team · away_team | The two teams, when available. |
| odds[].commence_time | Event start, ISO 8601 UTC. |
| odds[].market · line · scope · period | Canonical market, optional line (e.g. 2.5), scope (e.g. team) and period (e.g. 1st half). |
| odds[].state · score · minute | state = prematch or live. For live: current score (e.g. "1-0") and minute (e.g. "63'"). Same event_id as prematch to correlate the fixture across the two states. |
| …bookmakers[].key | Bookmaker key, with country, playable_it and is_exchange. |
| …bookmakers[].outcomes | Outcome → decimal odds map (e.g. HOME: 2.10). |
| …bookmakers[].last_update | ISO timestamp of that book's last successful odds update. |
Pagination
Repeat the call increasing offset by returned, as long as offset + returned < count. The board is live: count may shift slightly between pages.
GET /api/v1/odds?sport=calcio&limit=1000&offset=0
GET /api/v1/odds?sport=calcio&limit=1000&offset=1000
# … finché offset + returned < count
GET /api/v1/sports
The sports currently available in the feed (the values for the sport parameter).
GET /api/v1/bookmakers
The bookmakers active in the feed, with country, playable_it (false for sharp references like Pinnacle) and is_exchange (commission on winnings).
GET /api/v1/leagues public, no key
The current schedule, aggregated: for each sport the priced leagues, with event and bookmaker counts. Useful to discover values for the league filter.
GET /api/v1/stream Enterprise
Server-Sent Events: a hello event on connect, then odds events with the CHANGED records (same schema as /odds, each with its own state) and the removed ones, within ~10 seconds of the engine detecting them — no polling. Optional sport and state (prematch|live|all) parameters; initial snapshot via GET /odds?state=…. Data cadence stays the engine's (per-book freshness measured on the status page; bet365/Betfair via partner feeds): the stream removes polling latency, last_update is authoritative. Max 3 concurrent streams; the connection counts as 1 quota request.
GET /api/v1/coverage public, no key
Catalog inventory of bookmakers per region. It is a catalog count, not the list of books active in the feed: for that, use /api/v1/bookmakers or /api/v1/leagues.
POST /api/mcp MCP
MCP server (JSON-RPC 2.0) for AI agents and connectors (Claude, ChatGPT…). Auth with the same key (Authorization: Bearer odss_live_… or x-api-key). Tools: get_odds (with state=live), list_sports, list_bookmakers, list_leagues. Only tools/call uses quota; the handshake is free. Stateless: every request is self-contained.
curl -X POST https://odss-api.com/api/mcp \
-H "Authorization: Bearer odss_live_..." -H "content-type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call",
"params":{"name":"get_odds","arguments":{"sport":"calcio","state":"live","limit":5}}}'
Webhook Enterprise
Register an https URL from the dashboard or via API — POST /api/account/webhooks with your account session (body {url, sport?, state?}; the secret is shown once, max 20 per account) — and receive odds changes via POST: same {changed, removed} payload as the stream. Each delivery is signed: X-Odss-Signature: t=<unix>,v1=<hex> = HMAC-SHA256 of «{timestamp}.{body}» with the webhook secret (verify it, reject old timestamps). https only, redirects not followed; endpoints that repeatedly fail auto-disable. Respond 2xx.
Limits, headers and errors
Every authenticated response includes X-RateLimit-Limit (your plan's monthly quota) and X-RateLimit-Remaining. The quota is a rolling 30-day window.
| Status | Description |
|---|---|
| 401 | Missing, invalid or revoked key. |
| 403 | Out of scope: suspended account, feed outside the key's scope (e.g. live with a prematch-only key) or Enterprise-only feature (stream, webhooks). |
| 429 | Burst: per-minute requests of your plan exceeded. Retry-After: 60 header. |
| 429 | Monthly quota exhausted: upgrade or wait for the window. |
| 502 | Feed temporarily unavailable: retry with backoff. |
Machine-readable · contract & agents
To generate clients, SDKs or use the API from an AI agent: the OpenAPI 3.1 contract and a concise LLM guide are public and always in sync.
| Field | Description |
|---|---|
| /openapi.json | OpenAPI 3.1 contract (endpoints, parameters, schemas, x-api-key auth). |
| /llms.txt | Markdown guide for LLMs (llmstxt.org): summary and links to resources. |
| /postman_collection.json | Postman collection: import it and set the x-api-key variable to try the endpoints right away. |
| /sdk/odss_api.py | Official Python SDK (single-file, zero dependencies): typed client with automatic pagination and live support. |
| /sdk/odss-api.ts | Official TypeScript SDK (single-file, zero dependencies): types, async iterator and an SSE stream helper. |
| /.well-known/api-catalog | API catalog (RFC 9727, JSON linkset). |
Usage license
Internal use (models, bots, analysis, backtests) is included in every plan. Redistributing the data — e.g. showing it to your product's end users — requires written authorization: write to [email protected] and we'll define a license that fits your case.
The right plan for your volume.
Same coverage on every plan: you only pay for volume. Start free, cancel anytime.
Free
To explore the API. Forever, no card.
- 500 requests / month
- 30 requests / min
- Full coverage: every sport and every book in the feed
Starter
For bots and production integrations.
- 50,000 requests / month
- 120 requests / min
- Full coverage: every sport and every book in the feed
Pro
For platforms and high volumes.
- 500,000 requests / month
- 600 requests / min
- Priority support
Enterprise
For platforms, companies and resellers: configure volume, rate and license — the price updates by itself and you activate at checkout, no negotiation.
Authorises you to show the data to your product's end users (without it, use stays internal). Read the license →
- SSE streaming included (/api/v1/stream)
- Quota and rate configured on your account
- Automatic activation on payment, cancel anytime
By proceeding you accept the Enterprise & Redistribution License (readable from the link above) in addition to the Terms of service.
Payments via Stripe · one-click cancellation from the portal · quota is a rolling 30-day window
Frequently asked questions.
Can I use the data in a commercial product (SaaS)?
Internal use — your own models, bots, analysis, tools — is included in every plan. Showing the data to your product's end users requires written authorization: write to [email protected] and we'll define a license that fits your volume.
How often are odds updated?
Italian bookmakers on a continuous cycle — the REAL freshness, measured per book (p50/p95), is public on the status page; bet365 and Betfair arrive via partner feeds with a cadence of a few minutes. You don't have to take our word for it: every quote in the response carries its last_update.
Is there a trial of the paid plans?
The Free plan is forever and has the same coverage as the paid plans: it's the best way to verify the data. If you need more volume for an evaluation, write to [email protected].
How is this different from surebett.app?
Same engine, two products: odss-api sells the raw normalized odds to build on; surebett.app is the finished product, with arbitrages already computed and balanced stakes.