Coincidencia de Eventos
El Problema
Cada casa de apuestas utiliza sus propios IDs de eventos internos. El mismo partido Lakers vs Celtics podría ser el evento 33483200 en DraftKings, nba-bos-lal-20260208 en FanDuel y 556677889 en Pinnacle. Sin un identificador unificado, crear herramientas de comparación entre casas de apuestas requiere implementar tu propia lógica de coincidencia de eventos.
Cómo lo Resuelve SharpAPI
SharpAPI genera un ID de evento canónico para cada evento. Este ID es determinista: el mismo evento del mundo real siempre obtiene el mismo id, independientemente de la casa de apuestas de la que provenga.
Format: {league}_{teamA}_{teamB}_{YYYY-MM-DD}_b{N}El _b{N} final es un bucket de hora de inicio de 6 horas — consulta Sufijo de bucket de hora de inicio más abajo.
Ejemplo: Un partido Celtics vs Lakers el 8 de febrero de 2026 produce el mismo ID en todas las casas de apuestas:
| Casa de apuestas | ID de evento nativo | id de SharpAPI |
|---|---|---|
| DraftKings | 33483200 | nba_celtics_lakers_2026-02-08_b3 |
| FanDuel | nba-bos-lal-20260208 | nba_celtics_lakers_2026-02-08_b3 |
| Pinnacle | 556677889 | nba_celtics_lakers_2026-02-08_b3 |
| BetMGM | ms_44556 | nba_celtics_lakers_2026-02-08_b3 |
Dos Tipos de IDs de Eventos
Cada evento en la API tiene dos campos de ID:
| Campo | Ámbito | Propósito |
|---|---|---|
id | Entre casas (canónico) | Úsalo como clave principal para hacer coincidir eventos entre casas de apuestas |
external_ids | Por casa de apuestas | Mapa del ID nativo del evento de cada casa, útil para enlaces directos |
{
"id": "nba_celtics_lakers_2026-02-08_b3",
"external_ids": {
"draftkings": "33483200",
"fanduel": "nba-bos-lal-20260208",
"pinnacle": "556677889",
"betmgm": "ms_44556"
}
}Cómo se Generan los IDs Canónicos
El ID canónico se construye a partir de cuatro componentes:
- Código de liga — deporte asignado a una liga (p. ej.,
basketball→nba) - Nombres de los equipos — normalizados y ordenados alfabéticamente
- Fecha — fecha de inicio del evento en formato
YYYY-MM-DD - Bucket de hora de inicio — sufijo
_b{N}dondeNestá en0..3
Normalización de Nombres de Equipos
Los nombres de los equipos se normalizan para gestionar las variaciones entre casas de apuestas:
"Los Angeles Lakers"→lakers"LA Lakers"→lakers"LAL"→lakers
La normalización elimina prefijos (“The”, “Los”, “Las”), sufijos (“FC”, “United”, “City”), signos de puntuación y acentos. A continuación, los equipos se ordenan alfabéticamente para que el ID sea idéntico independientemente del orden local/visitante.
Sufijo de bucket de hora de inicio (_b{N})
El sufijo _b{N} es un bucket (intervalo) de hora de inicio de 6 horas. N está en 0..3:
| Bucket | Rango horario |
|---|---|
_b0 | 00:00–05:59 |
_b1 | 06:00–11:59 |
_b2 | 12:00–17:59 |
_b3 | 18:00–23:59 |
Para los deportes de ligas estadounidenses (NBA, NFL, NHL, MLB, NCAAB, NCAAF, WNBA, NCAAW), el bucket está anclado a la hora del este de EE. UU. (ET), de modo que un partido que empieza a las 7:30 PM ET cae en _b3 independientemente de cómo cada casa registre sus desfases UTC. Para el resto de deportes (fútbol, tenis, críquet, etc.), el bucket está anclado a UTC.
Por qué existe. Es posible tener el mismo enfrentamiento, en la misma fecha de calendario, pero en partidos reales distintos:
- Un doubleheader de la MLB con dos partidos el mismo día.
- Un partido de la MLB en la tarde-noche de EE. UU. cuyo sello UTC cae en el día de calendario siguiente, más una revancha real al día siguiente cuyo sello UTC cae en la misma fecha.
Sin el bucket, ambos partidos colisionarían en un solo ID y las cuotas se mezclarían. Con él, los dos partidos caen en sufijos _bN distintos y se mantienen separados.
Qué significa esto para la coincidencia entre casas. Dentro de un mismo partido, todas las casas que reportan una hora de inicio dentro de la misma ventana de 6 horas convergen en el mismo _b{N}. Al cruzar el límite de un bucket — por ejemplo, una casa registra el inicio de un partido de fútbol a las 17:55 UTC (_b2) y otra a las 18:10 UTC (_b3) — las casas pueden fragmentarse en dos IDs canónicos. Es una limitación conocida. Si lo observas, abre un ticket con los detalles del evento.
Sufijo de doubleheader (_g{N})
Cuando una casa reporta los dos partidos de un doubleheader del mismo día en una sola actualización, los dos partidos se desambiguan con un sufijo _g{N} colocado después del bucket — p. ej. mlb_athletics_mariners_2026-05-02_b0 y mlb_athletics_mariners_2026-05-02_b0_g1. Las casas que solo ven uno de los dos partidos emiten el ID con bucket sin sufijo adicional. Por tanto, el desajuste residual entre casas para los doubleheaders es: misma base _b{N}, con un lado llevando el sufijo _g{N} y el otro no.
Agrupar un enfrentamiento entre varios IDs
Para colapsar las filas que pertenecen a un único partido físico pero acabaron en IDs canónicos distintos, elige el nivel que se ajuste a tu tolerancia a la fusión:
-
Colapso al mismo partido (recomendado). Elimina el sufijo
_g{N}final y compara el resto, manteniendo intacto el bucket_b{N}:key = event_id sin el sufijo _g{N} final # ..._b0_g1 → ..._b0 agrupa los eventos cuyo key resultante sea idénticoEsto reúne el desajuste del sufijo de doubleheader descrito arriba sin fusionar partidos distintos. Refleja el predicado same-event del lado del servidor.
-
Agrupación laxa por enfrentamiento (visualización). Para reunir todos los precios de un enfrentamiento en una fecha sin importar el bucket — p. ej. para mostrar una tarjeta por partido en una UI y absorber la fragmentación en los límites de bucket descrita arriba — elimina tanto el sufijo
_g{N}como el_b{N}y agrupa por{league}_{teamA}_{teamB}_{date}, tolerando ±1 día para los inicios que cruzan la medianoche UTC:key = "{league}_{teamA}_{teamB}_{date}" # los equipos ya están ordenados alfabéticamente; _b{N}/_g{N} eliminados agrupa los keys que comparten liga + equipos y cuyas fechas difieren como máximo en 1 díaCompensación: como esto descarta el bucket, un doubleheader genuino del mismo día colapsa en un solo grupo. Usa el nivel 1 cuando los dos partidos deban mantenerse separados.
Uso de los IDs Canónicos en tu Aplicación
Como Clave Principal
Utiliza el campo id como clave principal de tu base de datos al almacenar eventos:
// Fetch events from the API
const { data: events } = await fetch(
'https://api.sharpapi.io/api/v1/events?league=nba',
{ headers: { 'X-API-Key': API_KEY } }
).then(r => r.json());
// Store using canonical ID as primary key
for (const event of events) {
await db.events.upsert({
id: event.id, // "nba_celtics_lakers_2026-02-08_b3"
home_team: event.home_team,
away_team: event.away_team,
start_time: event.start_time,
external_ids: event.external_ids
});
}Comparación de Cuotas Entre Casas de Apuestas
El ID canónico te permite comparar las cuotas del mismo evento en todas las casas de apuestas:
// Get odds filtered to a specific event
const { data } = await fetch(
'https://api.sharpapi.io/api/v1/events/nba_celtics_lakers_2026-02-08_b3/odds',
{ headers: { 'X-API-Key': API_KEY } }
).then(r => r.json());
// All odds in the response are for the same canonical event
// Group by sportsbook to compare
const byBook = {};
for (const odds of data.odds) {
byBook[odds.sportsbook] = byBook[odds.sportsbook] || [];
byBook[odds.sportsbook].push(odds);
}Enlaces Directos a Casas de Apuestas
Utiliza external_ids para redirigir a los usuarios a la página del evento de una casa de apuestas concreta:
const event = await getEvent('nba_celtics_lakers_2026-02-08_b3');
// Build a sportsbook-specific link
const dkEventId = event.external_ids['draftkings'];
// → "33483200"Cómo Esto Impulsa la Detección de EV y Arbitraje
Los motores de detección de oportunidades de SharpAPI dependen internamente de los IDs de eventos canónicos:
- El cálculo de EV localiza las cuotas de referencia sharp (Pinnacle) para el mismo
eventIdy las compara con las cuotas de las casas blandas - La detección de arbitraje agrupa todas las cuotas por
eventId+ tipo de mercado para encontrar discrepancias de precios entre casas de apuestas - La detección de middles encuentra líneas que se solapan entre casas para el mismo
eventId
Este es el mismo sistema de coincidencia que se te expone a través de la API: cuando ves una oportunidad de arbitraje con segmentos de distintas casas de apuestas, el ID de evento canónico es lo que vinculó esas cuotas.
Propiedades Clave
| Propiedad | Detalle |
|---|---|
| Determinista | Las mismas entradas siempre producen el mismo ID, sin UUIDs aleatorios |
| Estable | El ID no cambia una vez generado |
| Legible para humanos | nba_celtics_lakers_2026-02-08_b3 es significativo a primera vista |
| Ordenable | Los IDs se ordenan de forma natural por liga, equipo y fecha |