API di quote sportive · per sviluppatori e piattaforme

Le quote dei bookmaker ADM, esteri ed exchange in un'unica API.

Un solo formato JSON per calcio, tennis, basket e tutti gli altri sport del palinsesto. Ogni quota porta il suo last_update, e la freschezza del feed è misurata e pubblica.

  • Free: 500 richieste al mese, senza carta
  • Sandbox pubblico, senza chiave
curl "https://odss-api.com/api/v1/mock/odds?sport=calcio&market=1x2&limit=2"

Feed vero: /api/v1/odds con l'header x-api-key · SDK Python · TypeScript

Esempio · dati sinteticiRisposta · estrattoapplication/json
{
  "mock": true,
  "notice": "Dati SINTETICI a scopo di sviluppo: prezzi inventati, nessun rapporto con i listini reali dei book. Feed vero: /api/v1/* con chiave.",
  "count": 7, "offset": 0, "returned": 2, "state": "prematch",
  "odds": [
    {
      "event_id": "mock_39b522d4",
      "event": "Juventus - Inter",
      "sport": "calcio", "league": "Serie A",
      "market": "1x2",
      "bookmakers": [
        {
          "key": "mockbook_it_1", "country": "IT", "playable_it": true,
          "is_exchange": false, "family": "mockplat_a",
          "outcomes": { "HOME": 2.27, "DRAW": 3.14, "AWAY": 3.06 },
          "last_update": "2026-09-23T23:59:00.000Z"
        },
        {
          "key": "mockbook_it_2", "country": "IT", "playable_it": true,
          "is_exchange": false, "family": "mockplat_a",
          "outcomes": { "HOME": 2.8, "DRAW": 3.45, "AWAY": 2.46 },
          "suspended": [],
          "last_update": "2026-09-23T23:58:23.000Z"
        },
        {
          "key": "mockbook_it_3", "country": "IT", "playable_it": true,
          "is_exchange": false, "family": "mockplat_a",
          "outcomes": { "HOME": 3.9, "DRAW": 2.42 },
          "suspended": ["AWAY"],
          "last_update": "2026-09-23T23:57:46.000Z"
        }
      ]
    }
  ]
}

Il campo notice è sempre in italiano, qualunque sia la lingua della pagina.

GET /api/v1/mock/oddsbook mockbook_*, stessa forma di /api/v1/odds
—bookmaker nel feed
—sport in palinsesto
—leghe in palinsesto
—età p50 · 24 h
—età p95 · 24 h
Stato del feed

Età delle quote italiane che ricevi, sulle ultime 24 ore. Come la misuriamo

Come funziona

Dalla chiave alla prima quota in tre passi.

Crea la chiave

Registrati con la tua email. La chiave Free si genera subito, senza carta, e la vedi una volta sola: salvala dove tieni i segreti.

export ODSS_KEY="odss_live_…"

Chiedi le quote

Filtra per sport, lega e mercato con i nomi del feed. Un parametro che non esiste risponde 400 e ti suggerisce quello giusto.

curl "https://odss-api.com/api/v1/odds?sport=calcio&market=1x2" \
  -H "x-api-key: $ODSS_KEY"

Leggi freschezza e consumo

Ogni quota dice quando è stata letta (last_update); ogni risposta dice quante richieste ti restano e quando la quota si azzera.

X-RateLimit-Limit: 100000
X-RateLimit-Remaining: 99870
X-RateLimit-Reset: 1791763200

Freschezza

Quanto è vecchia una quota quando arriva a te.

Non promettiamo il tempo reale: misuriamo l'età delle quote e la pubblichiamo, così decidi tu quanto fidarti di un prezzo.

Età delle quote italiane che ricevi, ultime 24 ore
p50
metà delle quote servite sotto questa età
p95
95 quote servite su 100 sotto questa età

Come la misuriamo

Ogni 2 minuti, sullo snapshot che l'API sta servendo, misuriamo l'età di ogni quota pre-partita dei book italiani (adesso − last_update): è l'età delle quote che ricevi, non quella dentro il motore. p50 e p95 sono la mediana dei campioni delle ultime 24 ore; il tratteggio è il ciclo con cui il motore rilegge un book.

Cosa non è

Non è l'uptime, che non dichiariamo, e non è la latenza della tua richiesta: è quanto è vecchio il prezzo che ricevi. Un limite, detto: last_update è la fine della lettura del book, e nelle letture di dettaglio che durano minuti le prime righe lette sono un po' più vecchie del loro timbro.

Apri lo stato del feed

Prodotto

Tutto quello che serve per lavorare sulle quote.

REST per interrogare e streaming per ricevere, con una documentazione leggibile anche dalle macchine. Lo storico dei movimenti non è ancora attivo.

Un formato per tutti i bookmaker

Stessi nomi di sport, mercati ed esiti per book ADM, esteri ed exchange. Un mercato che non sappiamo mappare con certezza esce come other:<etichetta>, mai indovinato.

Dal sandbox · Juventus - Inter · 1x2 · dati sintetici
bookmakers[].keyHOMEDRAWAWAYlast_update
mockbook_it_12.273.143.0623:59:00Z
mockbook_it_22.803.452.4623:58:23Z
mockbook_it_33.902.42suspended23:57:46Z
mockbook_it_43.162.642.5823:57:09Z
mockbook_it_52.432.423.6623:56:32Z
mockbook_it_62.362.314.4923:55:55Z
mockbook_it_72.113.792.8123:55:18Z
mockbook_uk_11.972.87suspended23:24:41Z
mockbook_sharp4.022.173.2223:54:04Z
mockbook_exchange2.893.302.4423:53:27Z

Un esito che il book quota ma adesso non accetta sta in suspended, non in outcomes: «non quotato» e «quotato ma chiuso» restano due fatti distinti.

40+ concessionari ADM in un solo feed

Decine di concessionari italiani con licenza ADM, più book di riferimento internazionali ed exchange. L'elenco attivo è su /api/v1/bookmakers, con una chiave: nessuna lista di marchi da credere sulla parola.

keycountryplayable_itis_exchangesource

Campi della risposta di /api/v1/bookmakers: l'endpoint non accetta parametri. Su /api/v1/odds, country e playable_it sono anche filtri.

Pro ed Enterprise

Streaming SSE

Su /api/v1/stream arrivano solo i record cambiati e quelli rimossi, niente polling: con state=live il live di solito in 10-30 secondi. Il pre-partita intero oggi non arriva in modo affidabile (un giro completo pesa centinaia di MB): arriva con filtri stretti, a ondate; per tutto il pre-partita usa /odds.

id: mock.42
event: odds
data: {"changed":[…],"removed":[]}

: ping

GET /api/v1/mock/stream Stream d'esempio, senza chiave · dati sintetici

Storico dei movimenti · non ancora attivo

Non ancora attivo: oggi /odds/history risponde vuoto (history_enabled: false) e la chiamata conta nella quota. Quando lo sarà: una riga ogni volta che un book cambia prezzo, e a partita iniziata la prima riga è la chiusura.

aperturachiusura

Copertura verificabile, senza chiave

/coverage conta i marchi con una quota valida adesso; /coverage/matrix dice, book per book e sport per sport, quali mercati quotano.

Marchi con una quota valida adesso, per regione · GET /api/v1/coverage

Enterprise

Webhook firmati

Le variazioni arrivano in POST al tuo URL, firmate HMAC-SHA256; una consegna grande arriva in più pagine numerate.

POST <url>
X-Odss-Timestamp: <unix>
X-Odss-Signature: t=<unix>,v1=<hex>
X-Odss-Page: 1/3

{"page": 1, "pages": 3,
 "changed": […], "removed": […],
 "changed_total": <n>, …}

Server MCP per agenti AI

Un agente scopre gli strumenti senza chiave e senza consumare quota; la chiave serve per chiamarli.

Metodo JSON-RPCChiave e quota
initializeno
tools/listno
tools/callsì

Confronto

Il confronto, senza nomi.

Dove ci mettiamo rispetto alle API globali e alla media del mercato. Senza nomi, senza promesse.

Caratteristicaodss-apiMedia del mercato
Book ADM italianiSì, verificabili. /coverage pubblico, /bookmakers con chiave; l'età delle quote che ricevi è misurata e pubblica (p50/p95 su /status).Pochi, spesso a book. Nate per i book esteri (US/UK/offshore): i concessionari ADM, quando ci sono, sono pochi e spesso pagati a book.
Come si pagaPer account. Quota mensile + rate/min: più book o mercati per evento non aumentano il costo.Per book o a crediti. Crediti mercati×regioni: sul multi-book il costo esplode.
Cross-bookDeterministico. Un event_id condiviso da tutti i mercati dell'incontro: confronto nativo, matching non euristico.Spesso euristico. Quote proprietarie o matching non deterministico.
FreschezzaPer book, in chiaro. last_update ISO su ogni book: sai quanto è recente ogni gamba.Spesso assente. Non esposta per singolo book.
Pronta per gli agentiSì, standard aperti. OpenAPI 3.1, llms.txt, JSON-LD, /.well-known/api-catalog: un agente la trova e la legge da solo.Di rado. Docs dietro login o crawler bloccati, nessuno standard agentico.
Prezzo e avvioListino pubblico. Free tier, Enterprise self-serve configurabile. Chiave in un minuto.Spesso su trattativa. Enterprise opachi, oppure self-serve con pochi book italiani, spesso pagati a book.
Chiavi miratePer sport o lega. Es. una chiave «solo calcio», senza limite di numero.Non documentato.

Confronto con la media dei provider globali/enterprise valutati (lug 2026). Le voci del nostro lato sono verificabili dagli endpoint pubblici e dalla documentazione.

Copertura

Cosa c'è nel feed, contato adesso.

Non un catalogo: sport, leghe, eventi e book letti in questo momento dall'endpoint pubblico /api/v1/leagues. Cambiano con il palinsesto, e puoi verificarli senza chiave.

Copertura per book e mercato

Non escludiamo nessuna lega. Seguiamo i principali bookmaker ADM — l'elenco esatto è su /api/v1/bookmakers — e mostriamo tutto ciò che quotano: se un book del feed quota una partita, la vedi anche qui — dalle grandi leghe europee alle serie minori e alle competizioni internazionali. Quello che compare dipende dalla stagione e dal periodo: se non ci sono partite, i bookmaker non le quotano, quindi non appaiono. La lista qui sotto è il palinsesto di questo momento.

Carico il palinsesto…

L'elenco nominativo dei book attivi in questo momento è su GET /api/v1/bookmakers, con i campi country, playable_it, is_exchange e source: richiede una chiave API (la Free si genera in un minuto, senza carta). Senza chiave sono pubblici GET /api/v1/leagues — da cui vengono i conteggi qui sopra — e GET /api/v1/coverage.

Il palinsesto segue la stagione: d'estate il calcio di club è naturalmente ridotto.

Prezzi

Stessa copertura su ogni piano. Paghi solo il volume.

Lo streaming SSE arriva con Pro, i webhook con Enterprise. Inizia gratis e disdici quando vuoi.

In tutti i piani, Free compreso:

  • Tutti gli sport e tutti i book del feed
  • Player props
  • Sync delta con changed_since
  • Uso interno (modelli, bot, analisi)

Free

Per esplorare l'API. Per sempre, senza carta.

0 € per sempre, senza carta

500 richieste/mese · 30/min

Esempio: scrivere e collaudare l'integrazione, anche con il sandbox.

Inizia gratis

Hobby

Per progetti personali e piccoli bot.

19 € al mese + IVA

10.000 richieste/mese · 60/min

Esempio: un campionato letto ogni 5 minuti, circa 8.600 richieste al mese.

Scegli Hobby

Starter

Consigliato

Per bot e integrazioni in produzione.

79 € al mese + IVA

100.000 richieste/mese · 120/min

Esempio: tre campionati con il live, letti ogni 90 secondi: circa 86.000 richieste al mese.

Scegli Starter

Pro

Per piattaforme e volumi alti.

159 € al mese + IVA

500.000 richieste/mese · 600/min

  • Streaming SSE (/api/v1/stream)
  • Priorità di assistenza

Esempio: dieci campionati con il live, letti ogni 90 secondi (circa 288.000 richieste al mese), oppure lo stream.

Scegli Pro

  • Pagamento via Stripe Il totale lo confermi nel riepilogo, prima di pagare
  • Fattura elettronica Via SDI o PEC, per chi ha partita IVA italiana
  • Disdetta in un click Dall'area clienti, nel portale di pagamento
  • PRAXIS 3 S.r.l. P.IVA e C.F. 01434870661

Enterprise

Per piattaforme, aziende e rivenditori: configura volume, rate e licenza — il prezzo si aggiorna da solo e attivi in checkout, senza trattative.

  • Streaming SSE incluso (/api/v1/stream)
  • Quota e rate configurati sul tuo account
  • Attivazione automatica al pagamento, disdici quando vuoi
1 milione
+30 € per ogni milione oltre il primo.
600
+20 € per ogni 300 richieste al minuto oltre le 600.
+120 €

Ti autorizza a mostrare i dati agli utenti finali del tuo prodotto — siti, app, dashboard, widget, comparatori (senza, l'uso resta interno). Non autorizza a creare o commercializzare servizi di surebet/arbitraggio, value betting o piattaforme equivalenti, né a ridistribuire le API o i dati grezzi: per quelli serve una licenza commerciale dedicata. Leggi la licenza

Con questa configurazione

199 € al mese + IVA

Da 199 € a 749 € al mese, IVA esclusa.

Attiva Enterprise

Procedendo accetti la Licenza Enterprise e di Redistribuzione (leggibile dal link qui sopra) oltre ai Termini del servizio.

I prezzi indicati sono al netto dell'IVA. L'imposta applicabile viene aggiunta al momento del pagamento in base al tuo paese e al tuo status fiscale: 22% per l'Italia (anche per le imprese con partita IVA italiana); inversione contabile, imposta 0, per le imprese di altri Stati UE con partita IVA valida; operazione fuori campo IVA italiana per i clienti extra-UE. L'importo totale che paghi è quello indicato dal riepilogo del checkout, che confermi prima di inoltrare l'ordine (§4 dei Termini). La quota vale 30 giorni dalla prima richiesta del periodo.

Soluzioni commerciali

Tre livelli, un solo motore.

Le quote normalizzate sono il primo livello. Se il prodotto che vuoi vendere sono gli arbitraggi, il livello che ti serve è un altro: le surebet già calcolate, con il diritto di rivenderle incluso nell'abbonamento.

Livello 1 · self-serve

Odds API

Quote e dati normalizzati. Dal piano Free all'Enterprise, prezzo pubblico e attivazione immediata.

Vedi i prezzi

Livello 2 · piano API

Surebet API

Licenza di rivendita inclusa

Per chi ci costruisce sopra un prodotto proprio. Non restituisce soltanto le quote: restituisce le surebet già individuate e calcolate dal nostro motore, ricalcolate a ogni ciclo di scansione. Se non devi rivenderle a nessuno non ti serve: ti basta surebett.app.

950 € al mese, al netto dell'IVA · licenza di rivendita inclusa · si disdice in un click dal portale.

  • Evento e mercato
  • Bookmaker coinvolti e quote delle singole gambe
  • Percentuale/margine di arbitraggio
  • Stake ottimali
  • Timestamp e freschezza delle quote
  • Identificativi necessari all'integrazione

I campi elencati sono quelli previsti dove disponibili: la risposta porta ciò che il motore ha davvero calcolato per quell'evento. La licenza di rivendita è inclusa nell'abbonamento: puoi usare le surebet calcolate in un prodotto commerciale tuo, destinato ai tuoi utenti finali, nei limiti dell'uso dichiarato e dei Termini. Non comprende il White Label, che resta un contratto a parte.

Attivazione al pagamento, disdetta in un click dal portale. È un piano a sé e non si somma a un piano a listino: se sull'account ne hai già uno attivo a pagamento, va disdetto prima. Procedendo sottoscrivi la Surebet API Commercial License, nei limiti dell'uso che hai dichiarato qui sopra, e accetti i Termini del servizio (§5).

Livello 3 · a contratto

Surebet White Label

Piattaforma come servizio

Per le aziende che non vogliono sviluppare autonomamente la piattaforma: la Surebet completa, fornita come servizio con il tuo marchio.

2.000 € al mese, al netto dell'IVA · attivazione e durata secondo il contratto White Label.

  • Motore Surebet
  • Dati e aggiornamenti
  • Frontend completo
  • Personalizzazione di logo, nome e colori
  • Hosting e infrastruttura
  • Manutenzione e aggiornamenti

Software, motore e codice sorgente restano di nostra proprietà e vengono concessi in uso secondo il contratto White Label.

La licenza «Redistribuzione Display» dei piani API autorizza a mostrare le quote dentro il tuo prodotto: non autorizza a creare o commercializzare servizi di surebet/arbitraggio, value betting o piattaforme sostanzialmente equivalenti, né a ridistribuire le API o i dati grezzi. Per questi usi servono la Surebet API Commercial License o il contratto White Label — vedi le licenze commerciali e i Termini, §5.

Domande frequenti.

Altre domande? Scrivici a [email protected] o apri un ticket: risponde una persona, via email.

Esiste un'API per le quote dei bookmaker italiani con licenza ADM?

Sì: l'API espone le quote dei concessionari italiani presenti nel feed, filtrabili col parametro bookmakers. L'elenco attivo in questo momento è su GET /api/v1/bookmakers, che richiede una chiave API (la Free si genera in un minuto, senza carta); senza chiave sono pubblici /api/v1/leagues e /api/v1/coverage. Ogni quota porta il suo last_update.

Posso scaricare le quote in un database o in Excel?

Sì: l'API risponde JSON standard, quindi va dritta in Postgres, SQLite, pandas o Google Sheets. Con gli SDK Python e TypeScript bastano poche righe; il piano Free (500 richieste/mese) è sufficiente per provarci senza carta.

Quanto costa un'API di quote sportive?

Da noi: Free 500 richieste/mese senza carta, Hobby 19 €/mese + IVA (10.000), Starter 79 €/mese + IVA (100.000), Pro 159 €/mese + IVA (500.000), Enterprise configurabile da 199 € + IVA. Tutti gli importi sono al netto dell'IVA: a un privato italiano si aggiunge il 22%. Per le imprese di altri Stati UE con partita IVA valida si applica l'inversione contabile (imposta 0); per i clienti extra-UE l'operazione è fuori campo IVA italiana. Il totale è sempre indicato nel riepilogo del checkout, che confermi prima dell'ordine (§4 dei Termini). Stessa copertura su tutti i piani: paghi solo il volume.

Le quote sono in tempo reale?

L'età delle quote che ricevi è misurata, non promessa: p50 e p95 delle ultime 24 ore sono pubblici sulla status page, misurati sullo snapshot servito. Per il push c'è lo streaming SSE; il live in-play ha il suo feed, che si rinnova ogni pochi secondi.

Posso usare i dati in un prodotto commerciale (SaaS)?

L'uso interno — modelli, bot, analisi, strumenti tuoi — è incluso in tutti i piani. Mostrare i dati agli utenti finali di un tuo prodotto richiede la licenza di Redistribuzione Display (add-on Enterprise): autorizza la sola visualizzazione. Se il prodotto che vuoi vendere sono le surebet — arbitraggio, value betting o servizi equivalenti — serve la Surebet API, un piano a sé da 950 €/mese + IVA, con la licenza per rivenderle inclusa nell'abbonamento e la dichiarazione d'uso obbligatoria: vedi come si attiva. Se non devi rivendere nulla non ti serve: ti basta surebett.app. La piattaforma completa col tuo marchio resta il White Label, a contratto — vedi Surebet API e White Label.

Ogni quanto si aggiornano le quote?

Il motore rilegge i book italiani a ciclo continuo, ma ciò che conta è l'età delle quote che ricevi: la misuriamo sullo snapshot servito e la pubblichiamo sulla status page, con p50 e p95 delle ultime 24 ore (a ottobre 2026: p50 di 11-14 minuti di giorno, circa 18 la sera). Il contenuto italiano del feed si rinnova in media ogni 7-12 minuti, il live ogni pochi secondi. Non devi fidarti sulla parola: ogni quota nella risposta porta il suo last_update.

C'è un trial dei piani a pagamento?

Il piano Free è per sempre e ha la stessa copertura dei piani a pagamento: così verifichi i dati prima di pagare. Se ti serve più volume per una prova, scrivici a [email protected].

Che differenza c'è con surebett.app?

Stesso motore, due prodotti: odss-api vende le quote grezze normalizzate per costruirci sopra; surebett.app è il prodotto finito, con gli arbitraggi già calcolati e gli stake bilanciati.

Per chi sviluppa

Documentazione

Base URL https://odss-api.com. Autenticazione con header x-api-key: odss_live_… oppure Authorization: Bearer. Risposte JSON, quote decimali europee.

GET /api/v1/mock/odds senza chiave

Ogni endpoint ha un gemello sotto /api/v1/mock/ che risponde subito, senza registrarti e senza consumare quota: stessa forma della risposta, stessi parametri, stessa validazione stretta del feed vero. I prezzi sono sintetici — mock: true, header X-Odss-Mock: 1, id con prefisso mock_ — servono a scrivere e collaudare il codice, non a giocarci.

curl "https://odss-api.com/api/v1/mock/odds?sport=calcio&limit=3"

Disponibili: /mock/odds · /mock/odds/history · /mock/sports · /mock/bookmakers · /mock/leagues · /mock/status · /mock/stream (SSE) · /mock/ticker (un frame di quote 1X2 d'esempio ogni 5 s, senza parametri). Il parametro seed rende la risposta riproducibile: usalo nella CI invece di bruciare quota a ogni run.

Sul feed VERO sono pubblici senza chiave anche /api/v1/leagues, /api/v1/coverage, /api/v1/status e /api/v1/pulse.

Prima chiamata in 3 passi

  1. Crea la chiave Registrati e genera una chiave nella dashboard. Il piano Free è per sempre.
  2. Elenca gli sport Verifica la chiave con una chiamata a /sports.
  3. Chiedi le quote Chiama /odds con sport e mercato: ricevi le quote cross-book.

GET /api/v1/odds esempio

curl "https://odss-api.com/api/v1/odds?sport=calcio&league=serie%20a&limit=5" \
  -H "x-api-key: odss_live_..."

GET /api/v1/odds

Le quote cross-book correnti, raggruppate per evento, mercato e linea. Ogni record elenca i bookmaker con i loro esiti e il timestamp dell'ultimo aggiornamento.

Parametri

ParametroDescrizione
sport stringFiltro esatto sullo sport (es. calcio, tennis, basket). Valori: vedi /api/v1/sports.
market stringMercato canonico: 1x2, ou, btts, dc, ah (handicap asiatico), eh (handicap europeo), moneyline…
bookmakers stringLista CSV di chiavi book (es. snai,bet365). Valori: vedi /api/v1/bookmakers.
league stringFiltro per sottostringa, case-insensitive (es. serie a). Valori: vedi /api/v1/leagues.
event_id stringUn solo evento, per id esatto.
state prematch | live | allprematch (default), live (in-play, con punteggio e minuto) o all (entrambi). Con live, se il motore in-play è spento la lista è vuota e live_enabled=false. Se la chiave ha un ambito di feed (solo prematch o solo live), uno state fuori ambito risponde 403 e all degrada allo stato permesso.
limit integerRecord per pagina. Default 500, max 5000.
offset integerIndice di partenza per la paginazione. Default 0.
content match | player | allmatch = solo righe di incontro; player = solo player props; all (default) = entrambi. I props sono inclusi in ogni piano: il parametro restringe la risposta, non sblocca nulla.
player stringSottostringa del nome del giocatore, senza distinzione di maiuscole; implica content=player.
commence_from · commence_to date-timeFinestra sull'inizio dell'evento (ISO 8601), estremi inclusi. Con una finestra i record senza commence_time sono esclusi; una data illeggibile, o from dopo to, è un 400.
playable_it booleantrue = in ogni record solo i book giocabili dall'Italia (concessione ADM); false = solo gli altri. I record rimasti senza book vengono tolti.
country stringCSV di paesi di licenza (ISO 3166-1 alpha-2, oppure world): in ogni record restano solo quei book, es. IT oppure GB,SE.
after stringPaginazione STABILE a cursore: after= vuoto per la prima pagina, poi il next_after della risposta finché è null. L'ordine non dipende dall'aggiornamento dello snapshot, quindi una sincronizzazione completa non ha buchi né doppioni. Alternativo a offset; si combina con changed_since.
format full | compactcompact = gli stessi dati senza ripetizioni (i metadati dei book una volta in books, i dati dell'evento una volta in events): circa il 40% di byte in meno. Default full, lo schema di sempre.
changed_since stringSincronizzazione DELTA, su ogni piano. La prima volta changed_since= vuoto: risposta completa più un delta_token. Poi rimanda il token: solo i record cambiati o comparsi (in odds, nello stato attuale) e quelli spariti (in removed), con un nuovo delta_token. Un token vecchio (oltre circa 10 minuti) o di un altro avvio del server risponde 410 resync_required: si riparte con changed_since= vuoto. A prezzo invariato un record non torna nel delta: il suo last_update resta quello dell'ultimo cambio, anche se il book è stato riletto dopo.

Campi della risposta

CampoDescrizione
countTotale record che soddisfano i filtri (su tutte le pagine).
offset · returnedEco dell'offset richiesto e record effettivamente restituiti in questa pagina.
odds[].event_idId deterministico dell'evento: identico per tutti i mercati dello stesso incontro e stabile per l'intera finestra prematch.
odds[].eventNome normalizzato dell'evento (Casa - Ospite).
odds[].sport · leagueSport e lega/competizione dell'evento.
odds[].home_team · away_teamLe due squadre, quando disponibili.
odds[].commence_timeInizio dell'evento, ISO 8601 UTC.
odds[].market · line · scope · periodMercato canonico, eventuale linea (es. 2.5), ambito (es. squadra) e periodo (es. 1° tempo).
odds[].state · score · minutestate = prematch o live. Per il live: score (es. «1-0») e minute (es. «63'») correnti. Stesso event_id del prematch per correlare la stessa partita nei due stati.
…bookmakers[].keyChiave del bookmaker, con country, playable_it e is_exchange.
…bookmakers[].outcomesMappa esito → quota decimale (es. HOME: 2.10).
…bookmakers[].suspendedEsiti che quel book quota ma su cui ora non accetta giocate. Non stanno in outcomes (un esito sospeso non ha un prezzo giocabile) ma sono nominati qui, così «questo book non quota l'esito» e «lo quota ed è chiuso adesso» restano due fatti distinti. Campo opzionale, e l'assenza vuol dire qualcosa: se manca, quel book non dichiara lo stato; [] vuol dire dichiarata, e niente di sospeso. Non leggere l'assenza come lista vuota.
…bookmakers[].last_updateTimestamp ISO dell'ultimo aggiornamento riuscito delle quote di quel book.
…bookmakers[].familyPiattaforma da cui arriva il listino. Marchi della stessa famiglia possono servire lo STESSO listino: contarli come listini indipendenti inventa arbitraggi che non esistono. Stessa famiglia non vuol dire sempre stesso prezzo: è un avviso di correlazione, non una regola di esclusione.
odds[].player · player_idSolo nelle righe dei player props (assenti, non null, nelle righe di incontro): player fa parte dell'identità della riga; player_id è l'id stabile del giocatore per quel book, per seguirlo da un aggiornamento all'altro (non è un id valido tra book diversi).

Paginazione

Ripeti la chiamata aumentando offset di returned, finché offset + returned < count. Il palinsesto è vivo: count può variare leggermente tra le pagine.

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

Gli sport disponibili in questo momento nel feed (i valori del parametro sport).

GET /api/v1/bookmakers

I bookmaker attivi nel feed, ognuno con questi campi.

CampoDescrizione
countryCodice ISO 3166-1 alpha-2 del paese di licenza (IT, GB, US, SE…), oppure world quando non è attribuito.
playable_ittrue solo per i book con concessione ADM, cioè giocabili dall'Italia; false per tutti gli altri book del feed, dalle sharp di riferimento come Pinnacle ai marchi esteri.
is_exchangeExchange, con commissione sulla vincita.
feed_keysLe chiavi con cui le quote di questo operatore escono in /odds: il marchio e, se c'è, la sua corsia di mercato dedicata (es. <marchio>-corners). Un operatore è una riga sola.
derived_fromSolo se le quote pre-partita dell'operatore sono copiate da un altro: la chiave del book d'origine, come derived_from su ogni quota (derived_states dice in quale stato).
sourceTipo di canale del listino: direct | partner_feed.

GET /api/v1/leagues pubblico, senza chiave

Il palinsesto corrente aggregato: per ogni sport le leghe quotate, con numero di eventi e di bookmaker. Utile per scoprire i valori del filtro league.

GET /api/v1/stream Pro ed Enterprise

Server-Sent Events: arrivano solo i record cambiati e quelli rimossi, niente polling. Con state=live il live arriva di solito in 10-30 secondi (mediana misurata circa 15 s). Limite di oggi, misurato l'8 ottobre 2026: con state=all un giro pre-partita completo pesa centinaia di MB e la connessione cade prima di riceverlo; lo stream è rimasto senza variazioni il 79% del tempo, con un resync ogni 12 minuti circa. Il pre-partita arriva solo con filtri stretti (sport, mercato, lega), a ondate, quando si rinnova lo snapshot servito. Stiamo riscrivendo la consegna a pagine piccole con contropressione; fino ad allora, per tutto il pre-partita usa lo snapshot paginato di /odds.

VoceDescrizione
helloAlla connessione.
oddsI record CAMBIATI (stesso schema di /odds, ognuno col suo state) e i rimossi.
sport · stateParametri opzionali (state: prematch | live | all). Snapshot iniziale via GET /odds?state=….
CadenzaQuella dello snapshot servito: il live si rinnova ogni pochi secondi, il pre-partita in media ogni 4-6 minuti (il contenuto italiano ogni 7-12). Fa fede last_update, con un limite: a prezzo invariato il record non viene rimandato, quindi il last_update che hai resta quello dell'ultimo cambio anche se il book è stato riletto dopo. L'età vera del pre-partita servito è su /status (served_age).
LimitiMax 3 stream concorrenti; la connessione conta 1 richiesta di quota.

GET /api/v1/odds/history

Non ancora attivo. Oggi la cattura è spenta: ogni chiamata risponde 200 con count: 0 e history_enabled: false, e conta nella quota. Quando sarà attivo: storico delle variazioni di quota per un evento, una riga ogni volta che un bookmaker cambia prezzo su un gruppo. Filtri event_id (obbligatorio), book, market, from/to (ISO), limit. Ordine dal più recente: la prima riga di un evento iniziato è la sua chiusura. Rispetta l'ambito della chiave.

curl "https://odss-api.com/api/v1/odds/history?event_id=a3f9c1e07b2d4865&book=snai" \
  -H "x-api-key: odss_live_..."

GET /api/v1/middles

Middle Over/Under calcolati dal feed corrente: OVER su una linea bassa da un book, UNDER su una linea alta da un altro. Se il totale cade nella finestra vincono entrambe le giocate. Campi middle_window, hit_return_pct, miss_return_pct, safe (nessuna perdita nemmeno a vuoto). Filtri: sport, min_return, safe, limit.

Regola di freschezza: una quota ferma da più di stale_after_seconds (900s di default) resta nelle risposte di /odds col suo last_update, ma non viene accoppiata in un middle: una gamba vecchia probabilmente non esiste più sul sito del bookmaker. La soglia applicata e il numero di gambe scartate sono nella risposta.

Limiti di safe, oggi: alcune famiglie di mercato non sono ancora separate per unità (nel tennis e nel volley un totale di set può finire accanto a un totale di game o di punti), alcuni pseudo-eventi «Home - Away» di una piattaforma sono serviti come partite, e due partite omonime possono condividere un event_id. In questi casi safe: true non è un middle vero: prima di agire controlla che le due gambe siano la stessa partita, la stessa unità e lo stesso orario. La risposta lo ricorda nel campo safe_note.

curl "https://odss-api.com/api/v1/middles?sport=calcio&safe=true" \
  -H "x-api-key: odss_live_..."

GET /api/v1/coverage pubblico, senza chiave

Quanti marchi di bookmaker hanno una quota valida nel feed di questo momento, per regione (Italia, USA, UK, mondo). Coincide con le voci di /api/v1/bookmakers: entrambi contano un operatore una volta sola, con le corsie di mercato dedicate (es. <marchio>-corners) sotto il marchio; in /bookmakers le chiavi con cui le sue quote escono stanno in feed_keys.

GET /api/v1/coverage/matrix pubblico, senza chiave

Per ogni bookmaker, sport per sport: i mercati normalizzati che quota adesso, con le linee viste. Serve a distinguere tre cose che un elenco piatto confonde.

Un mercato non elencato sotto un operatore attivo è un'assenza strutturale: non lo quota, e domani sarà uguale. Gli operatori in live_only_bookmakers hanno righe ma non nel prematch, quindi sui loro mercati prematch la risposta non dice nulla; se una corsia del feed non ha risposto, incomplete_lanes la nomina e la copertura è parziale, non assente.

E un mercato che il motore non sa mappare con certezza non viene indovinato: esce come other:<etichetta> e qui viene solo contato (other_markets), perché due book lo chiamano in modi diversi e confrontare quelle etichette sarebbe sbagliato — quelle che molti book scrivono uguale stanno in other_markets_common. Ambito prematch, ricalcolata al massimo ogni 10 minuti (generated_at).

GET /api/v1/pulse pubblico, senza chiave

Il battito del feed, solo numeri aggregati (niente prezzi, niente nomi di book): è ciò che interrogano da sole le pagine di questo sito. Nessun parametro, Cache-Control: public, max-age=5, limite per IP a sé (60 al minuto).

CampoDescrizione
prematch_it_atL'istante in cui è stato pubblicato lo snapshot che contiene la corsia italiana attuale: mai più nuovo delle pagine servite.
beatsGli ultimi ingressi di una corsia italiana nuova nello snapshot servito, fino a 30, raccolti dall'avvio del server (beats_since).
freshness_24hPer ogni mezz'ora delle ultime 24 ore: served_p50 e served_p95, l'età delle quote italiane che ricevevi (campionata ogni 2 minuti sullo snapshot servito), e p50/p95, l'età dentro il motore. In served gli stessi percentili sulle 24 ore. Una mezz'ora senza campioni resta vuota, mai stimata.

POST /api/mcp MCP

Server MCP (JSON-RPC 2.0) per agenti AI e connettori (Claude, ChatGPT…). Autenticazione con la stessa chiave (Authorization: Bearer odss_live_… o x-api-key). Tool: get_odds (con state=live), list_sports, list_bookmakers, list_leagues. Solo tools/call consuma quota; l'handshake è gratis. Stateless: ogni richiesta è autosufficiente.

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

Registra una URL https e ricevi le variazioni di quota via POST, con lo stesso payload {changed, removed} dello stream.

VoceDescrizione
POST /api/account/webhooksDalla dashboard o via API, con la sessione account. Body {url, sport?, state?}; il secret è mostrato una volta, max 20 per account.
X-Odss-Signaturet=<unix>,v1=<hex> = HMAC-SHA256 di «{timestamp}.{body}» col secret del webhook. Ogni consegna è firmata: verifica la firma, rifiuta i timestamp vecchi.
X-Odss-Pagepagina/totale: una consegna può arrivare in più POST consecutivi, ognuno firmato per conto suo. Ogni corpo porta page, pages, changed_total e removed_total, così dalla prima pagina sai già quanto sta arrivando.
RegoleRispondi 2xx. Solo https, niente redirect seguiti; gli endpoint che falliscono a ripetizione si auto-disabilitano. Non limitare la frequenza dell'endpoint: una pagina rifiutata ferma le successive.

Limiti, header ed errori

Ogni risposta autenticata include X-RateLimit-Limit (quota mensile del piano), X-RateLimit-Remaining e X-RateLimit-Reset (unix time in secondi in cui la finestra si riapre; sul 429 da quota la stessa data è nel corpo come retry_at). La quota vale per una finestra di 30 giorni che parte dalla prima richiesta del periodo: alla scadenza il contatore si azzera e riparte con la richiesta successiva.

CodiceDescrizione
400Richiesta non valida: parametro sconosciuto, valore fuori da quelli ammessi (es. state) o parametro obbligatorio mancante (es. event_id su /odds/history). Il corpo della risposta dice quale.
401Chiave mancante, non valida o revocata.
403Fuori ambito: account sospeso, feed fuori dallo scope della chiave (es. live con chiave solo-prematch) o funzione riservata al piano (stream: Pro ed Enterprise; webhook: Enterprise).
429Burst: superate le richieste al minuto del piano. Header Retry-After: 60.
429Quota mensile esaurita: passa a un piano superiore o attendi la finestra.
502Feed momentaneamente non disponibile: riprova con backoff.

Parametri: nessun silenzio

Su tutti gli endpoint /api/v1 un parametro che non riconosciamo non viene mai ignorato: se scrivi bookmaker invece di bookmakers ricevi 400 con il nome sbagliato, l'elenco di quelli ammessi su quell'endpoint e, se è un refuso, il suggerimento del nome giusto. Il confronto è esatto: anche Sport con la maiuscola viene rifiutato. Gli endpoint di catalogo (/sports, /bookmakers, /leagues, /coverage, /status) non accettano alcun parametro. Preferiamo un errore subito a una risposta 200 con dati non filtrati che sembrano corretti: il 400 è deterministico, va corretto e non ritentato, e non consuma quota.

La stessa regola vale per gli argomenti dei tool del server MCP (POST /api/mcp): un nome che non esiste, o un tipo sbagliato come una lista al posto della stringa CSV, riceve un errore JSON-RPC -32602 invece di essere ignorato. Il campo error.data porta i nomi ammessi, così l'agente si corregge da solo.

curl "https://odss-api.com/api/v1/odds?bookmaker=snai" -H "x-api-key: odss_live_..."

HTTP/1.1 400 Bad Request
{
  "error": "Parametro sconosciuto: \"bookmaker\" (forse intendevi \"bookmakers\"?). Ammessi su questo endpoint: after, bookmakers, changed_since, commence_from, commence_to, content, country, event_id, format, league, limit, market, offset, playable_it, player, sport, state"
}

Risorse per macchine e agenti

Per generare client, SDK o usare l'API da un agente AI: il contratto OpenAPI 3.1 e una guida sintetica per LLM sono pubblici e sempre allineati.

RisorsaDescrizione
/openapi.jsonContratto OpenAPI 3.1 (endpoint, parametri, schemi, auth x-api-key).
/llms.txtGuida markdown per LLM (llmstxt.org): riassunto e link alle risorse.
/postman_collection.jsonCollezione Postman: importala e imposta la variabile x-api-key per provare subito gli endpoint.
/sdk/odss_api.pySDK Python ufficiale (single-file, zero dipendenze): client tipizzato con paginazione automatica e supporto live.
/sdk/odss-api.tsSDK TypeScript ufficiale (single-file, zero dipendenze): tipi, iteratore async e helper per lo stream SSE.
/.well-known/api-catalogCatalogo API (RFC 9727, linkset JSON).

Licenza d'uso

L'uso interno (modelli, bot, analisi, backtest) è incluso in tutti i piani. La ridistribuzione dei dati — ad esempio mostrarli agli utenti finali di un tuo prodotto — richiede la licenza di Redistribuzione Display (add-on Enterprise, +€120/mese), che copre la sola visualizzazione. Creare, alimentare o commercializzare servizi di surebet/arbitraggio, di value betting o equivalenti richiede invece la Surebet API, il piano che include la licenza per rivendere le surebet calcolate: 950 €/mese + IVA. Ridistribuire le API o i dati grezzi resta fuori da ogni piano: per quello scrivici a [email protected].

Prova il feed adesso. Il sandbox non chiede nemmeno la chiave.

Quando sei pronto, la chiave Free si crea in un minuto. Senza carta.

Crea una chiave gratis
curl https://odss-api.com/api/v1/mock/odds
odss-api Torna al sito
Accesso
Password dimenticata?
Contatta il team
Scrivici: apriamo un ticket e ti rispondiamo via email. Niente bot.
Se riguarda una richiesta all'API, incolla l'URL senza la chiave e l'ora in cui l'hai fatta.
Prima del pagamento
Per chi acquisti?