API de cuotas deportivas · para desarrolladores y plataformas

Las cuotas de las casas ADM italianas, extranjeras y exchanges en una sola API.

Un único formato JSON para fútbol, tenis, baloncesto y todos los demás deportes del calendario. Cada cuota lleva su last_update, y la frescura del feed se mide y es pública.

  • Free: 500 peticiones al mes, sin tarjeta
  • Sandbox público, sin clave
curl "https://odss-api.com/api/v1/mock/odds?sport=calcio&market=1x2&limit=2"

Feed real: /api/v1/odds con la cabecera x-api-key · SDK Python · TypeScript

Ejemplo · datos sintéticosRespuesta · extractoapplication/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"
        }
      ]
    }
  ]
}

El campo notice está siempre en italiano, sea cual sea el idioma de la página.

GET /api/v1/mock/oddscasas mockbook_*, misma forma que /api/v1/odds
—casas en el feed
—deportes en el calendario
—ligas en el calendario
—antigüedad p50 · 24 h
—antigüedad p95 · 24 h
Estado del feed

Antigüedad de las cuotas italianas que recibes, en las últimas 24 horas. Cómo la medimos

Cómo funciona

De la clave a la primera cuota en tres pasos.

Crea la clave

Regístrate con tu email. La clave Free se genera al momento, sin tarjeta, y la ves una sola vez: guárdala donde guardas tus secretos.

export ODSS_KEY="odss_live_…"

Pide las cuotas

Filtra por deporte, liga y mercado con los nombres del feed. Un parámetro que no existe responde 400 y te sugiere el correcto.

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

Lee frescura y consumo

Cada cuota dice cuándo se leyó (last_update); cada respuesta dice cuántas peticiones te quedan y cuándo se reinicia la cuota.

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

Frescura

Qué antigüedad tiene una cuota cuando te llega.

No prometemos tiempo real: medimos la antigüedad de las cuotas y la publicamos, así decides tú cuánto fiarte de un precio.

Antigüedad de las cuotas italianas que recibes, últimas 24 horas
p50
la mitad de las cuotas servidas por debajo de esta antigüedad
p95
95 de cada 100 cuotas servidas por debajo de esta antigüedad

Cómo la medimos

Cada 2 minutos, sobre el snapshot que la API está sirviendo, medimos la antigüedad de cada cuota prematch de las casas italianas (ahora − last_update): es la antigüedad de las cuotas que recibes, no la de dentro del motor. p50 y p95 son la mediana de las muestras de las últimas 24 horas; la marca discontinua es el ciclo con el que el motor relee una casa.

Lo que no es

No es el uptime, que no declaramos, ni la latencia de tu petición: es lo vieja que es la cuota que recibes. Un límite, dicho: last_update es el final de la lectura de la casa, y en las lecturas de detalle que duran minutos las primeras filas leídas son algo más viejas que su marca de tiempo.

Abrir el estado del feed

Producto

Todo lo que necesitas para trabajar con cuotas.

REST para consultar y streaming para recibir, con una documentación que también leen las máquinas. El histórico de movimientos aún no está activo.

Un formato para todas las casas

Los mismos nombres de deportes, mercados y resultados para casas ADM, extranjeras y exchanges. Un mercado que no sabemos mapear con certeza sale como other:<etiqueta>, nunca adivinado.

Del sandbox · Juventus - Inter · 1x2 · datos sintéticos
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 resultado que la casa cotiza pero ahora no acepta está en suspended, no en outcomes: «no cotizado» y «cotizado pero cerrado» siguen siendo dos hechos distintos.

40+ casas con licencia ADM en un solo feed

Decenas de operadores italianos con licencia ADM, más casas de referencia internacionales y exchanges. La lista activa está en /api/v1/bookmakers, con una clave: ninguna lista de marcas que creer a ciegas.

keycountryplayable_itis_exchangesource

Campos de la respuesta de /api/v1/bookmakers: el endpoint no acepta parámetros. En /api/v1/odds, country y playable_it también sirven como filtros.

Pro y Enterprise

Streaming SSE

En /api/v1/stream solo llegan los registros cambiados y los eliminados, sin polling: con state=live, el live normalmente en 10-30 segundos. El prematch completo hoy no llega de forma fiable (una vuelta completa pesa cientos de MB): llega con filtros estrechos, por oleadas; para todo el prematch usa /odds.

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

: ping

GET /api/v1/mock/stream Stream de ejemplo, sin clave · datos sintéticos

Histórico de movimientos · aún no activo

Aún no activo: hoy /odds/history responde vacío (history_enabled: false) y la llamada cuenta en la cuota. Cuando lo esté: una fila cada vez que una casa cambia un precio, y con el partido empezado la primera fila es el cierre.

aperturacierre

Cobertura verificable, sin clave

/coverage cuenta las marcas con una cuota válida ahora; /coverage/matrix dice, casa por casa y deporte por deporte, qué mercados cotizan.

Marcas con una cuota válida ahora, por región · GET /api/v1/coverage

Enterprise

Webhooks firmados

Las variaciones llegan por POST a tu URL, firmadas con HMAC-SHA256; una entrega grande llega en varias páginas numeradas.

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>, …}

Servidor MCP para agentes de IA

Un agente descubre las herramientas sin clave y sin consumir cuota; la clave sirve para llamarlas.

Método JSON-RPCClave y cuota
initializeno
tools/listno
tools/callsí

Comparación

La comparación, sin nombres.

Dónde estamos frente a las APIs globales y la media del mercado. Sin nombres, sin promesas.

Característicaodss-apiMedia del mercado
Casas ADM italianasSí, verificables. /coverage público, /bookmakers con clave; la antigüedad de las cuotas que recibes se mide y es pública (p50/p95 en /status).Pocas, a menudo por casa. Pensadas para casas extranjeras (US/UK/offshore): las concesionarias ADM, cuando están, son pocas y a menudo se pagan por casa.
Cómo se pagaPor cuenta. Cuota mensual + rate/min: más casas o mercados por evento no suben el coste.Por casa o por créditos. Créditos mercados×regiones: en multi-casa el coste se dispara.
Cross-bookDeterminista. Un event_id compartido por todos los mercados del partido: comparación nativa, sin matching heurístico.A menudo heurístico. Cuotas propietarias o matching no determinista.
FrescuraPor casa, a la vista. last_update ISO en cada casa: sabes cómo de reciente es cada pata.A menudo ausente. No expuesta por casa individual.
Lista para agentesSí, estándares abiertos. OpenAPI 3.1, llms.txt, JSON-LD, /.well-known/api-catalog: un agente la encuentra y la lee solo.Rara vez. Docs tras login o crawlers bloqueados, sin estándar agéntico.
Precio y altaTarifas públicas. Free tier, Enterprise self-serve configurable. Clave en un minuto.A menudo bajo negociación. Enterprise opaco, o self-serve con pocas casas italianas, a menudo de pago por casa.
Claves específicasPor deporte o liga. P. ej. una clave «solo fútbol», sin límite de número.No documentado.

Comparación con la media de los proveedores globales/enterprise evaluados (jul 2026). Nuestro lado es verificable desde los endpoints públicos y la documentación.

Cobertura

Qué hay en el feed, contado ahora mismo.

No es un catálogo: deportes, ligas, eventos y casas leídos ahora mismo del endpoint público /api/v1/leagues. Cambian con el calendario, y puedes comprobarlos sin clave.

Cobertura por casa y mercado

No excluimos ninguna liga. Seguimos las principales casas ADM — la lista exacta está en /api/v1/bookmakers — y mostramos todo lo que cotizan: si una casa del feed cotiza un partido, lo ves aquí también — desde las grandes ligas europeas hasta divisiones menores y competiciones internacionales. Lo que aparece depende de la temporada y el momento: sin partidos, las casas no cotizan, así que no aparecen. La lista de abajo es el calendario de este momento.

Cargando el calendario…

La lista nominal de las casas activas en este momento está en GET /api/v1/bookmakers, con los campos country, playable_it, is_exchange y source: requiere una clave API (la Free se genera en un minuto, sin tarjeta). Sin clave son públicos GET /api/v1/leagues — de donde salen los recuentos de arriba — y GET /api/v1/coverage.

El tablero sigue la temporada: en verano el fútbol de clubes es naturalmente menor.

Precios

La misma cobertura en todos los planes. Solo pagas el volumen.

El streaming SSE llega con Pro, los webhooks con Enterprise. Empieza gratis y cancela cuando quieras.

En todos los planes, Free incluido:

  • Todos los deportes y todas las casas del feed
  • Player props
  • Sincronización delta con changed_since
  • Uso interno (modelos, bots, análisis)

Free

Para explorar la API. Para siempre, sin tarjeta.

0 € para siempre, sin tarjeta

500 peticiones/mes · 30/min

Ejemplo: escribir y probar la integración, también con el sandbox.

Empezar gratis

Hobby

Para proyectos personales y bots pequeños.

19 € al mes + IVA

10.000 peticiones/mes · 60/min

Ejemplo: una liga leída cada 5 minutos, unas 8.600 peticiones al mes.

Elegir Hobby

Starter

Recomendado

Para bots e integraciones en producción.

79 € al mes + IVA

100.000 peticiones/mes · 120/min

Ejemplo: tres ligas con el live, leídas cada 90 segundos: unas 86.000 peticiones al mes.

Elegir Starter

Pro

Para plataformas y volúmenes altos.

159 € al mes + IVA

500.000 peticiones/mes · 600/min

  • Streaming SSE (/api/v1/stream)
  • Prioridad de asistencia

Ejemplo: diez ligas con el live, leídas cada 90 segundos (unas 288.000 peticiones al mes), o el stream.

Elegir Pro

  • Pago vía Stripe Confirmas el total en el resumen, antes de pagar
  • Factura electrónica italiana Vía SDI o PEC, con NIF-IVA italiano
  • Baja en un clic Desde el área de cliente, en el portal de pago
  • PRAXIS 3 S.r.l. NIF-IVA y código fiscal 01434870661

Enterprise

Para plataformas, empresas y revendedores: configura volumen, rate y licencia — el precio se actualiza solo y activas en el checkout, sin negociación.

  • Streaming SSE incluido (/api/v1/stream)
  • Cuota y rate configurados en tu cuenta
  • Activación automática al pagar, cancela cuando quieras
1 milione
+30 € per ogni milione oltre il primo.
600
+20 € per ogni 300 richieste al minuto oltre le 600.
+120 €

Te autoriza a mostrar los datos a los usuarios finales de tu producto — sitios, apps, paneles, widgets, comparadores (sin ella, el uso queda interno). No autoriza a crear ni comercializar servicios de surebet/arbitraje, value betting o plataformas equivalentes, ni a redistribuir la API o los datos brutos: para eso hace falta una licencia comercial dedicada. Lee la licencia

Con esta configuración

199 € al mes + IVA

De 199 € a 749 € al mes, IVA excluido.

Activar Enterprise

Al continuar aceptas la Licencia Enterprise y de Redistribución (legible desde el enlace de arriba) además de los Términos del servicio.

Los precios indicados no incluyen IVA. El impuesto aplicable se añade en el momento del pago según tu país y tu condición fiscal: 22% para Italia (también para empresas con NIF-IVA italiano); inversión del sujeto pasivo, impuesto 0, para empresas de otros Estados miembros de la UE con NIF-IVA válido; operación fuera del ámbito del IVA italiano para clientes de fuera de la UE. El importe total que pagas es el que muestra el resumen del checkout, que confirmas antes de realizar el pedido (§4 de los Términos). La cuota vale 30 días desde la primera petición del período.

Soluciones comerciales

Tres niveles, un solo motor.

Las cuotas normalizadas son el primer nivel. Si el producto que quieres vender son los arbitrajes, el nivel que necesitas es otro: las surebets ya calculadas, con el derecho a revenderlas incluido en la suscripción.

Nivel 1 · self-serve

Odds API

Cuotas y datos normalizados. Del plan Free al Enterprise, precio público y activación inmediata.

Ver precios

Nivel 2 · plan API

Surebet API

Licencia de reventa incluida

Para quien construye encima un producto propio. No devuelve solo las cuotas: devuelve las surebets ya identificadas y calculadas por nuestro motor, recalculadas en cada ciclo de escaneo. Si no tienes a quien revenderlas no te hace falta: te basta con surebett.app.

950 € al mes, sin IVA · licencia de reventa incluida · se cancela con un clic desde el portal.

  • Evento y mercado
  • Casas implicadas y cuotas de cada pata
  • Porcentaje/margen de arbitraje
  • Stakes óptimos
  • Timestamp y frescura de las cuotas
  • Identificadores necesarios para la integración

Los campos indicados son los previstos donde estén disponibles: la respuesta contiene lo que el motor ha calculado realmente para ese evento. La licencia de reventa está incluida en la suscripción: puedes usar las surebets calculadas en un producto comercial tuyo, destinado a tus usuarios finales, dentro de los límites del uso declarado y de los Términos. No incluye el White Label, que sigue siendo un contrato aparte.

Activación al efectuar el pago, baja en un clic desde el portal. Es un plan aparte y no se suma a un plan del listado: si la cuenta ya tiene uno de pago activo, hay que darlo de baja antes. Al continuar suscribes la Surebet API Commercial License, dentro de los límites del uso que has declarado arriba, y aceptas los Términos del servicio (§5).

Nivel 3 · por contrato

Surebet White Label

Plataforma como servicio

Para las empresas que no quieren desarrollar la plataforma por su cuenta: la Surebet completa, entregada como servicio con tu marca.

2.000 € al mes, sin IVA · activación y duración según el contrato White Label.

  • Motor Surebet
  • Datos y actualizaciones
  • Frontend completo
  • Personalización de logo, nombre y colores
  • Hosting e infraestructura
  • Mantenimiento y actualizaciones

El software, el motor y el código fuente siguen siendo de nuestra propiedad y se conceden en uso según el contrato White Label.

La licencia «Redistribución Display» de los planes API te autoriza a mostrar las cuotas dentro de tu producto: no autoriza a crear ni comercializar servicios de surebet/arbitraje, value betting o plataformas sustancialmente equivalentes, ni a redistribuir la API o los datos brutos. Para esos usos hacen falta la Surebet API Commercial License o el contrato White Label — véanse las licencias comerciales y los Términos, §5.

Preguntas frecuentes.

¿Más preguntas? Escríbenos a [email protected] o abre un ticket: responde una persona, por email.

¿Existe una API para las cuotas de las casas italianas con licencia ADM?

Sí: la API expone las cuotas de las casas italianas presentes en el feed, filtrables con el parámetro bookmakers. La lista activa en este momento está en GET /api/v1/bookmakers, que requiere una clave API (la Free se genera en un minuto, sin tarjeta); sin clave son públicos /api/v1/leagues y /api/v1/coverage. Cada cuota lleva su last_update.

¿Puedo exportar las cuotas a una base de datos o a Excel?

Sí: la API devuelve JSON estándar, así que va directa a Postgres, SQLite, pandas o Google Sheets. Con los SDK de Python y TypeScript bastan pocas líneas; el plan Free (500 peticiones/mes) alcanza para probar, sin tarjeta.

¿Cuánto cuesta una API de cuotas deportivas?

Aquí: Free 500 peticiones/mes sin tarjeta, Hobby 19 €/mes + IVA (10.000), Starter 79 €/mes + IVA (100.000), Pro 159 €/mes + IVA (500.000), Enterprise desde 199 € + IVA. Todos los importes no incluyen IVA: a un particular italiano se le añade el 22%. A las empresas de otros Estados miembros de la UE con NIF-IVA válido se les aplica la inversión del sujeto pasivo (impuesto 0); para clientes de fuera de la UE la operación está fuera del ámbito del IVA italiano. El total siempre aparece en el resumen del checkout, que confirmas antes del pedido (§4 de los Términos). Misma cobertura en todos los planes: solo pagas el volumen.

¿Las cuotas son en tiempo real?

La antigüedad de las cuotas que recibes se mide, no se promete: p50 y p95 de las últimas 24 h son públicos en la status page, medidos sobre el snapshot servido. Streaming SSE para push; el live tiene su propio feed, que se renueva cada pocos segundos.

¿Puedo usar los datos en un producto comercial (SaaS)?

El uso interno — tus modelos, bots, análisis, herramientas — está incluido en todos los planes. Mostrar los datos a los usuarios finales de tu producto requiere la licencia de Redistribución Display (complemento Enterprise): autoriza solo la visualización. Si el producto que quieres vender son las surebets — arbitraje, value betting o servicios equivalentes — hace falta la Surebet API, un plan propio de 950 €/mes + IVA, con la licencia para revenderlas incluida en la suscripción y la declaración de uso obligatoria: mira cómo se activa. Si no tienes a quien revender no te hace falta: te basta con surebett.app. La plataforma completa con tu marca sigue siendo el White Label, por contrato — véase Surebet API y White Label.

¿Cada cuánto se actualizan las cuotas?

El motor relee las casas italianas en ciclo continuo, pero lo que cuenta es la antigüedad de las cuotas que recibes: la medimos sobre el snapshot servido y la publicamos en la status page, con p50 y p95 de las últimas 24 horas (octubre de 2026: p50 de 11-14 minutos de día, unos 18 a última hora de la tarde). El contenido italiano del feed se renueva de media cada 7-12 minutos, el live cada pocos segundos. No hace falta que nos creas: cada cuota de la respuesta lleva su last_update.

¿Hay prueba de los planes de pago?

El plan Free es para siempre y tiene la misma cobertura que los planes de pago: así compruebas los datos antes de pagar. Si necesitas más volumen para una evaluación, escribe a [email protected].

¿En qué se diferencia de surebett.app?

Mismo motor, dos productos: odss-api vende las cuotas en bruto normalizadas para construir encima; surebett.app es el producto final, con los arbitrajes ya calculados y stakes equilibrados.

Para desarrolladores

Documentación

Base URL https://odss-api.com. Autentícate con la cabecera x-api-key: odss_live_… o Authorization: Bearer. Respuestas JSON, cuotas decimales europeas.

GET /api/v1/mock/odds sin clave

Cada endpoint tiene un gemelo bajo /api/v1/mock/ que responde ya, sin registrarte y sin consumir cuota: misma forma de respuesta, mismos parámetros, misma validación estricta que el feed real. Los precios son sintéticos — mock: true, cabecera X-Odss-Mock: 1, ids con prefijo mock_ — sirven para escribir y probar tu código, no para apostar.

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

Disponibles: /mock/odds · /mock/odds/history · /mock/sports · /mock/bookmakers · /mock/leagues · /mock/status · /mock/stream (SSE) · /mock/ticker (un frame de cuotas 1X2 de ejemplo cada 5 s, sin parámetros). El parámetro seed hace la respuesta reproducible: úsalo en CI en vez de gastar cuota en cada ejecución.

En el feed REAL también son públicos sin clave /api/v1/leagues, /api/v1/coverage, /api/v1/status y /api/v1/pulse.

Primera llamada en 3 pasos

  1. Crea la clave Regístrate y genera una clave en el panel. El plan Free es para siempre.
  2. Lista los deportes Verifica la clave con una llamada a /sports.
  3. Pide las cuotas Llama a /odds con deporte y mercado: recibes las cuotas cross-book.

GET /api/v1/odds ejemplo

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

Las cuotas cross-book actuales, agrupadas por evento, mercado y línea. Cada registro lista las casas con sus resultados y el timestamp de su última actualización.

Parámetros

ParámetroDescripción
sport stringFiltro exacto de deporte (ej. calcio, tennis, basket). Valores: ver /api/v1/sports.
market stringMercado canónico: 1x2, ou, btts, dc, ah (hándicap asiático), eh (hándicap europeo), moneyline…
bookmakers stringLista CSV de claves de casa (ej. snai,bet365). Valores: ver /api/v1/bookmakers.
league stringFiltro por subcadena, sin distinguir mayúsculas (ej. serie a). Valores: ver /api/v1/leagues.
event_id stringUn solo evento, por id exacto.
state prematch | live | allprematch (por defecto), live (in-play, con marcador y minuto) o all (ambos). Con live, si el motor in-play está apagado la lista está vacía y live_enabled=false. Si la clave tiene un ámbito de feed (solo prematch o solo live), un state fuera del ámbito devuelve 403 y all degrada al estado permitido.
limit integerRegistros por página. Por defecto 500, máx. 5000.
offset integerÍndice de inicio para la paginación. Por defecto 0.
content match | player | allmatch = solo líneas de partido; player = solo player props; all (por defecto) = ambos. Los props están incluidos en todos los planes: el parámetro restringe la respuesta, no desbloquea nada.
player stringSubcadena del nombre del jugador, sin distinguir mayúsculas; implica content=player.
commence_from · commence_to date-timeVentana sobre el inicio del evento (ISO 8601), extremos incluidos. Con una ventana se excluyen los registros sin commence_time; una fecha ilegible, o from posterior a to, es un 400.
playable_it booleantrue = en cada registro solo las casas jugables desde Italia (licencia ADM); false = solo las demás. Se eliminan los registros que quedan sin casas.
country stringCSV de países de licencia (ISO 3166-1 alfa-2, o world): en cada registro quedan solo esas casas, p. ej. IT o GB,SE.
after stringPaginación ESTABLE con cursor: after= vacío para la primera página, luego el next_after de la respuesta hasta que sea null. El orden no depende de la actualización del snapshot, así que una sincronización completa no tiene huecos ni duplicados. Alternativo a offset; se combina con changed_since.
format full | compactcompact = los mismos datos sin repeticiones (metadatos de las casas una vez en books, datos del evento una vez en events): alrededor de un 40% menos de bytes. Por defecto full, el esquema de siempre.
changed_since stringSincronización DELTA, en todos los planes. La primera vez changed_since= vacío: respuesta completa más un delta_token. Después devuelve el token: solo los registros que cambiaron o aparecieron (en odds, en su estado actual) y los que desaparecieron (en removed), con un nuevo delta_token. Un token viejo (más de unos 10 minutos) o de otro arranque del servidor responde 410 resync_required: vuelve a empezar con changed_since= vacío. Un registro cuyo precio no cambia no vuelve en el delta: su last_update sigue siendo el del último cambio, aunque la casa se haya releído después.

Campos de la respuesta

CampoDescripción
countTotal de registros que cumplen los filtros (en todas las páginas).
offset · returnedEco del offset pedido y registros devueltos en esta página.
odds[].event_idId determinista del evento: idéntico para todos los mercados del mismo partido y estable durante toda la ventana prepartido.
odds[].eventNombre normalizado del evento (Local - Visitante).
odds[].sport · leagueDeporte y liga/competición del evento.
odds[].home_team · away_teamLos dos equipos, cuando están disponibles.
odds[].commence_timeInicio del evento, ISO 8601 UTC.
odds[].market · line · scope · periodMercado canónico, línea opcional (ej. 2.5), ámbito (ej. equipo) y periodo (ej. 1ª parte).
odds[].state · score · minutestate = prematch o live. Para el live: score (ej. "1-0") y minute (ej. "63'") actuales. Mismo event_id que el prematch → correlaciona el mismo partido en ambos estados.
…bookmakers[].keyClave de la casa, con country, playable_it e is_exchange.
…bookmakers[].outcomesMapa resultado → cuota decimal (ej. HOME: 2.10).
…bookmakers[].suspendedResultados que esa casa cotiza pero en los que ahora no acepta apuestas. No están en outcomes (un resultado suspendido no tiene precio jugable) y se nombran aquí, para que «la casa no ofrece este resultado» y «lo ofrece y está cerrado ahora» sigan siendo dos hechos distintos. Campo opcional, y su ausencia significa algo: si falta, esa casa no declara el estado; [] significa declarada y nada suspendido. No leas la ausencia como lista vacía.
…bookmakers[].last_updateTimestamp ISO de la última actualización correcta de esa casa.
…bookmakers[].familyPlataforma de la que llega la lista de precios. Marcas de la misma familia pueden servir la MISMA lista: contarlas como listas independientes inventa arbitrajes que no existen. Misma familia no siempre significa mismo precio: es un aviso de correlación, no una regla de exclusión.
odds[].player · player_idSolo en las filas de player props (ausentes, no null, en las filas de partido): player forma parte de la identidad de la fila; player_id es el id estable del jugador en esa casa, para seguirlo entre actualizaciones (no es un id válido entre casas).

Paginación

Repite la llamada aumentando offset en returned, mientras offset + returned < count. El tablero está vivo: count puede variar ligeramente entre páginas.

GET /api/v1/odds?sport=calcio&limit=1000&offset=0
GET /api/v1/odds?sport=calcio&limit=1000&offset=1000
# … mientras offset + returned < count

GET /api/v1/sports

Los deportes disponibles ahora mismo en el feed (los valores del parámetro sport).

GET /api/v1/bookmakers

Las casas activas en el feed, cada una con estos campos.

CampoDescripción
countryCódigo ISO 3166-1 alpha-2 del país de licencia (IT, GB, US, SE…), o world cuando no está atribuido.
playable_ittrue solo para las casas con licencia ADM italiana, es decir jugables desde Italia; false para todas las demás del feed, desde referencias sharp como Pinnacle hasta las marcas extranjeras.
is_exchangeExchange, con comisión sobre la ganancia.
feed_keysLas claves con las que salen las cuotas de este operador en /odds: la marca y, si la hay, su línea de mercado dedicada (p. ej. <marca>-corners). Un operador, una fila.
derived_fromSolo si las cuotas prematch del operador se copian de otro: la clave de la casa de origen, como derived_from en cada cuota (derived_states dice en qué estado).
sourceTipo de canal de la lista de precios: direct | partner_feed.

GET /api/v1/leagues público, sin clave

El calendario actual agregado: para cada deporte las ligas cotizadas, con número de eventos y de casas. Útil para descubrir valores del filtro league.

GET /api/v1/stream Pro y Enterprise

Server-Sent Events: solo llegan los registros cambiados y los eliminados, sin polling. Con state=live, el live llega normalmente en 10-30 segundos (mediana medida, unos 15 s). Límite de hoy, medido el 8 de octubre de 2026: con state=all una vuelta prematch completa pesa cientos de MB y la conexión se cae antes de recibirla; el stream estuvo sin cambios el 79% del tiempo, con un resync cada 12 minutos aproximadamente. El prematch solo llega con filtros estrechos (deporte, mercado, liga), por oleadas, cuando se renueva el snapshot servido. Estamos reescribiendo la entrega en páginas pequeñas con contrapresión; hasta entonces, para todo el prematch usa el snapshot paginado de /odds.

ElementoDescripción
helloAl conectar.
oddsLos registros CAMBIADOS (mismo esquema que /odds, cada uno con su state) y los eliminados.
sport · stateParámetros opcionales (state: prematch | live | all). Snapshot inicial vía GET /odds?state=….
CadenciaLa del snapshot servido: el live se renueva cada pocos segundos, el prematch de media cada 4-6 minutos (el contenido italiano cada 7-12). Manda last_update, con un límite: si el precio no cambia el registro no se reenvía, así que el last_update que tienes sigue siendo el del último cambio aunque la casa se haya releído después. La antigüedad real del prematch servido está en /status (served_age).
LímitesMáx. 3 streams concurrentes; la conexión cuenta como 1 petición de cuota.

GET /api/v1/odds/history

Aún no activo. Hoy la captura está apagada: cada llamada responde 200 con count: 0 y history_enabled: false, y cuenta en la cuota. Cuando esté activo: histórico de cambios de cuota de un evento, una fila cada vez que una casa mueve un precio en un grupo. Filtros event_id (obligatorio), book, market, from/to (ISO), limit. Del más reciente: en un evento ya empezado la primera fila es su cierre. Respeta el ámbito de la clave.

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

GET /api/v1/middles

Middles Over/Under calculados del feed actual: OVER en una línea baja en una casa, UNDER en una línea alta en otra. Si el total cae en la ventana ganan ambas apuestas. Campos middle_window, hit_return_pct, miss_return_pct, safe (sin pérdida ni fallando). Filtros: sport, min_return, safe, limit.

Regla de frescura: una cuota parada más de stale_after_seconds (900s por defecto) sigue en las respuestas de /odds con su last_update, pero no se empareja en un middle: una pata vieja probablemente ya no existe en la web de la casa. El umbral aplicado y las patas descartadas están en la respuesta.

Límites de safe, hoy: algunas familias de mercado aún no están separadas por unidad (en tenis y vóley un total de sets puede quedar junto a un total de juegos o de puntos), algunos pseudoeventos «Home - Away» de una plataforma se sirven como partidos, y dos partidos con el mismo nombre pueden compartir un event_id. En esos casos safe: true no es un middle real: antes de actuar comprueba que las dos patas sean el mismo partido, la misma unidad y la misma hora. La respuesta lo recuerda en el 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 público, sin clave

Cuántas marcas de casas tienen una cuota válida en el feed de este momento, por región (Italia, USA, UK, mundo). Coincide con las entradas de /api/v1/bookmakers: ambos cuentan un operador una sola vez, con sus líneas de mercado dedicadas (p. ej. <marca>-corners) bajo la marca; en /bookmakers las claves con las que salen sus cuotas están en feed_keys.

GET /api/v1/coverage/matrix público, sin clave

Para cada casa, deporte por deporte: los mercados normalizados que cotiza ahora, con las líneas vistas. Sirve para distinguir tres cosas que una lista plana confunde.

Un mercado no listado bajo una casa attivo es una ausencia estructural: no lo cotiza, y mañana será igual. Las casas en live_only_bookmakers tienen filas pero no en el prepartido, así que sobre sus mercados de prepartido esta respuesta no dice nada; si un carril del feed no respondió, incomplete_lanes lo nombra y la cobertura es parcial, no ausente.

Y un mercado que el motor no sabe mapear con certeza no se adivina: sale como other:<etiqueta> y aquí solo se cuenta (other_markets), porque dos casas lo llaman de formas distintas y comparar esas etiquetas sería un error — las que muchas casas escriben igual están en other_markets_common. Ámbito prematch, recalculada como mucho cada 10 minutos (generated_at).

GET /api/v1/pulse público, sin clave

El latido del feed, solo números agregados (sin precios, sin nombres de casas): es lo que consultan por sí solas las páginas de este sitio. Sin parámetros, Cache-Control: public, max-age=5, límite propio por IP (60 por minuto).

CampoDescripción
prematch_it_atEl instante en que se publicó el snapshot que contiene el carril italiano actual: nunca más nuevo que las páginas servidas.
beatsLas últimas entradas de un carril italiano nuevo en el snapshot servido, hasta 30, recogidas desde el arranque del servidor (beats_since).
freshness_24hPara cada media hora de las últimas 24 horas: served_p50 y served_p95, la antigüedad de las cuotas italianas que recibías (muestreada cada 2 minutos sobre el snapshot servido), y p50/p95, la antigüedad dentro del motor. En served los mismos percentiles de las 24 horas. Una media hora sin muestras queda vacía, nunca estimada.

POST /api/mcp MCP

Servidor MCP (JSON-RPC 2.0) para agentes IA y conectores (Claude, ChatGPT…). Autenticación con la misma clave (Authorization: Bearer odss_live_… o x-api-key). Herramientas: get_odds (con state=live), list_sports, list_bookmakers, list_leagues. Solo tools/call consume cuota; el handshake es gratis. Stateless.

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 y recibe los cambios de cuota por POST, con el mismo payload {changed, removed} que el stream.

ElementoDescripción
POST /api/account/webhooksDesde el panel o vía API, con la sesión de cuenta. Body {url, sport?, state?}; el secret se muestra una vez, máx. 20 por cuenta.
X-Odss-Signaturet=<unix>,v1=<hex> = HMAC-SHA256 de «{timestamp}.{body}» con el secreto. Cada entrega va firmada: verifícala, rechaza timestamps viejos.
X-Odss-Pagepágina/total: una entrega puede llegar en varios POST consecutivos, cada uno firmado por separado. Cada cuerpo lleva page, pages, changed_total y removed_total, así desde la primera página ya sabes cuánto está llegando.
ReglasResponde 2xx. Solo https, sin redirecciones; los endpoints que fallan se autodesactivan. No limites la frecuencia del endpoint: una página rechazada detiene las siguientes.

Límites, cabeceras y errores

Cada respuesta autenticada incluye X-RateLimit-Limit (cuota mensual del plan), X-RateLimit-Remaining y X-RateLimit-Reset (unix time en segundos en que la ventana se reabre; en el 429 por cuota la misma fecha está en el cuerpo como retry_at). La cuota vale para una ventana de 30 días que empieza con la primera petición del período: al vencer, el contador se pone a cero y vuelve a empezar con la petición siguiente.

CódigoDescripción
400Petición no válida: parámetro desconocido, valor fuera de los admitidos (ej. state) o parámetro obligatorio ausente (ej. event_id en /odds/history). El cuerpo de la respuesta dice cuál.
401Clave ausente, no válida o revocada.
403Fuera de ámbito: cuenta suspendida, feed fuera del ámbito de la clave (ej. live con clave solo-prematch) o función según el plan (stream: Pro y Enterprise; webhooks: Enterprise).
429Burst: superadas las peticiones por minuto del plan. Cabecera Retry-After: 60.
429Cuota mensual agotada: sube de plan o espera la ventana.
502Feed temporalmente no disponible: reintenta con backoff.

Parámetros: sin silencios

En todos los endpoints /api/v1, un parámetro que no reconocemos no se ignora nunca: si escribes bookmaker en lugar de bookmakers recibes 400 con el nombre equivocado, la lista de los admitidos en ese endpoint y, si es una errata, la sugerencia del nombre correcto. La comparación es exacta: incluso Sport con mayúscula inicial se rechaza. Los endpoints de catálogo (/sports, /bookmakers, /leagues, /coverage, /status) no aceptan ningún parámetro. Preferimos un error inmediato a una respuesta 200 con datos sin filtrar que parecen correctos: el 400 es determinista, hay que corregirlo y no reintentarlo, y no consume cuota.

La misma regla vale para los argumentos de las herramientas del servidor MCP (POST /api/mcp): un nombre que no existe, o un tipo equivocado como una lista en lugar de la cadena CSV, recibe un error JSON-RPC -32602 en vez de ignorarse. El campo error.data incluye los nombres admitidos, así el agente se corrige 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"
}

Recursos para máquinas y agentes

Para generar clientes, SDKs o usar la API desde un agente IA: el contrato OpenAPI 3.1 y una guía breve para LLM son públicos y siempre sincronizados.

RecursoDescripción
/openapi.jsonContrato OpenAPI 3.1 (endpoints, parámetros, esquemas, auth x-api-key).
/llms.txtGuía markdown para LLM (llmstxt.org): resumen y enlaces a recursos.
/postman_collection.jsonColección Postman: impórtala y define la variable x-api-key para probar los endpoints al momento.
/sdk/odss_api.pySDK de Python oficial (un solo archivo, sin dependencias): cliente tipado con paginación automática y soporte live.
/sdk/odss-api.tsSDK de TypeScript oficial (un solo archivo, sin dependencias): tipos, iterador async y helper para el stream SSE.
/.well-known/api-catalogCatálogo de API (RFC 9727, linkset JSON).

Licencia de uso

El uso interno (modelos, bots, análisis, backtests) está incluido en todos los planes. Redistribuir los datos — p. ej. mostrarlos a los usuarios finales de tu producto — requiere la licencia de Redistribución Display (complemento Enterprise, +120 €/mes), que cubre solo la visualización. Crear, alimentar o comercializar servicios de surebet/arbitraje, de value betting o equivalentes exige en cambio la Surebet API, el plan que incluye la licencia para revender las surebets calculadas: 950 €/mes + IVA. Redistribuir la API o los datos brutos queda fuera de todos los planes: para eso, escribe a [email protected].

Prueba el feed ahora. El sandbox ni siquiera pide la clave.

Cuando estés listo, la clave Free se crea en un minuto. Sin tarjeta.

Crea una clave gratis
curl https://odss-api.com/api/v1/mock/odds
odss-api Volver al sitio
Acceso
¿Has olvidado la contraseña?
Contacta al equipo
Escríbenos: abrimos un ticket y respondemos por email. Sin bots.
Si se trata de una petición a la API, pega la URL sin la clave y la hora en que la hiciste.
Antes del pago
¿Para quién compras?