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.

● IT books on a continuous cycle · measured freshness stable event_id · last_update per quote self-serve · no card

GET /api/v1/odds live feed
# 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

01

Create a key

Sign up and generate an odss_live key in a minute. The Free plan is forever, no card required.

02

Call /odds

One endpoint, all cross-book odds by event and market. Filter by sport, league, market and bookmaker.

03

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.

sisalsnaieurobetgoldbetplanetwin365+ decine

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.

Feature
odss-api
Market average
Italian ADM books
Direct, verifiable coverage (public /coverage and /bookmakers), measured, public freshness (p50/p95 at /status).
Absent: they cover foreign books (US/UK/offshore), no ADM book.
How you pay
Per account: monthly quota + rate/min. More books or markets per event don't add cost.
Per simultaneous book, or markets×regions credits: cost explodes on multi-book.
Cross-book
Deterministic event_id shared by all markets of a fixture: native comparison, no heuristic matching.
Often proprietary odds or non-deterministic matching.
Freshness
ISO last_update in the clear, book by book: you know how recent each leg is.
Often not exposed per single book.
Agent-ready
OpenAPI 3.1, llms.txt, JSON-LD, /.well-known/api-catalog: an agent finds and reads it on its own.
Docs behind login or blocked crawlers, no agentic standard.
Price & onboarding
Public pricing with a Free tier; self-serve configurable Enterprise. A key in a minute.
Sales-gated, opaque Enterprise, or self-serve without Italian books.
Targeted keys
Scopable by sport/league (e.g. a «soccer only» key), with no key-count limit.
Not documented.

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.

We don't exclude any league. We track all ADM bookmakers and show everything they price: if a book quotes a match, you see it here too — from the big European leagues to minor divisions and international competitions. What appears depends on season and timing: no matches means bookmakers don't price them, so they don't show. The list below is the schedule at this moment.

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

01

Create a key

Sign up and generate a key in the dashboard. The Free plan is forever.

02

List sports

Verify the key with a call to /sports.

03

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

ParameterDescription
sportExact sport filter (e.g. calcio, tennis, basket). Values: see /api/v1/sports.
marketCanonical market: 1x2, ou, btts, dc, handicap, moneyline…
bookmakersCSV list of book keys (e.g. snai,bet365). Values: see /api/v1/bookmakers.
leagueCase-insensitive substring filter (e.g. serie a). Values: see /api/v1/leagues.
event_idA single event, by exact id.
stateprematch (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.
limitRecords per page. Default 500, max 2000.
offsetStart index for pagination. Default 0.

Response fields

FieldDescription
countTotal records matching the filters (across all pages).
offset · returnedEcho of the requested offset and the records actually returned in this page.
odds[].event_idDeterministic event id: identical for every market of the same fixture and stable for the whole prematch window.
odds[].eventNormalized event name (Home - Away).
odds[].sport · leagueSport and league/competition of the event.
odds[].home_team · away_teamThe two teams, when available.
odds[].commence_timeEvent start, ISO 8601 UTC.
odds[].market · line · scope · periodCanonical market, optional line (e.g. 2.5), scope (e.g. team) and period (e.g. 1st half).
odds[].state · score · minutestate = 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[].keyBookmaker key, with country, playable_it and is_exchange.
…bookmakers[].outcomesOutcome → decimal odds map (e.g. HOME: 2.10).
…bookmakers[].last_updateISO 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.

StatusDescription
401Missing, invalid or revoked key.
403Out of scope: suspended account, feed outside the key's scope (e.g. live with a prematch-only key) or Enterprise-only feature (stream, webhooks).
429Burst: per-minute requests of your plan exceeded. Retry-After: 60 header.
429Monthly quota exhausted: upgrade or wait for the window.
502Feed 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.

FieldDescription
/openapi.jsonOpenAPI 3.1 contract (endpoints, parameters, schemas, x-api-key auth).
/llms.txtMarkdown guide for LLMs (llmstxt.org): summary and links to resources.
/postman_collection.jsonPostman collection: import it and set the x-api-key variable to try the endpoints right away.
/sdk/odss_api.pyOfficial Python SDK (single-file, zero dependencies): typed client with automatic pagination and live support.
/sdk/odss-api.tsOfficial TypeScript SDK (single-file, zero dependencies): types, async iterator and an SSE stream helper.
/.well-known/api-catalogAPI 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.

0forever
Start free
  • 500 requests / month
  • 30 requests / min
  • Full coverage: every sport and every book in the feed
★ Most chosen

Starter

For bots and production integrations.

79/month
Choose Starter
  • 50,000 requests / month
  • 120 requests / min
  • Full coverage: every sport and every book in the feed

Pro

For platforms and high volumes.

159/month
Choose Pro
  • 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.

199/month
+€120

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.

Dashboard

Current plan
free
Change plan
This month (account)

The quota is per account: it's shared across all your keys, not per key.

Generate a key

Create as many as you want — they share the account quota. Restrict them to sports or leagues if you need dedicated keys.

Feed

My API keys