http://TU_HOST:5000
Formato JSON UTF-8
Idiomas ?lang=en | ?lang=es (default en)
Para construir un panel de resultados, consumir en este orden:
1. GET /api/sports -> lista de deportes disponibles
2. GET /api/sports/{sport}/leagues -> ligas de ese deporte
3. GET /api/sports/{sport}/leagues/{liga}/matches -> partidos de la liga (+ tabla de posiciones)
4. GET /api/events/{id} -> detalle del partido (todas las pestanas)
(o) POST /api/leagues/matches -> partidos de varias ligas de una sola vez
/api/sports?lang=es /api/sports/basketball/leagues?lang=es /api/sports/basketball/leagues/Liga%20Nacional/matches?lang=es /api/leagues/matches?lang=es&leagues=MLB,WNBA
| Funcion | Detalle |
|---|---|
| Ventana de datos | Solo se mantienen los partidos de hoy + los proximos 6 dias (configurable con RETENTION_DAYS, default 7). Lo demas se borra automaticamente. |
| Zona horaria | Todo se calcula en America/Los_Angeles (TIMEZONE). Cada evento trae date, date_display (ej. jue 24 sep) y time. |
| Tiempo real | El scheduler actualiza los partidos de hoy cada minuto (minuto/estado/marcador en vivo). |
| Canales de TV | Campo channels por evento, segun TV_COUNTRY_ID (18=USA, 31=Mexico, 10=Argentina, 21=Brasil, 2=Espana). |
| Detalle completo | GET /api/events/{id} incluye detail con: alineaciones (confirmada o probable, con fotos), timeline, estadisticas, tendencias, clasificacion, duelos previos, predicciones, estadio, arbitros, stages y TV. |
| Tabla de posiciones | /api/sports/{sport}/leagues/{liga}/standings (y dentro de .../matches) para cualquier deporte. |
| Varias ligas | POST /api/leagues/matches recibe una lista de ligas de cualquier deporte y devuelve los partidos (hoy o una ventana). |
| Clave | ID 365scores | Nombre (en) | Nombre (es) |
|---|---|---|---|
| football | 1 | Football | Fútbol |
| basketball | 2 | Basketball | Básquetbol |
| tennis | 3 | Tennis | Tenis |
| hockey | 4 | Hockey | Hockey |
| handball | 5 | Handball | Balonmano |
| american_football | 6 | A. Football | Fútbol Am. |
| baseball | 7 | Baseball | Béisbol |
| volleyball | 8 | Volleyball | Voleibol |
| rugby | 9 | Rugby | Rugby |
Todos los errores devuelven un objeto JSON con la clave error:
{ "error": "Deporte invalido. Opciones: football, basketball, tennis, hockey, handball, american_football, baseball, volleyball, rugby" }
Error 404 - recurso no encontrado
{ "error": "Liga no encontrada para el deporte 'baseball'" }
{ "error": "Evento no encontrado" }
{ "error": "No hay alineaciones disponibles" }
| Codigo | Significado |
|---|---|
| 200 | OK |
| 400 | Parametro invalido (deporte desconocido, fecha mal formada) |
| 404 | Evento, liga o alineacion inexistente |
| 500 | Error interno del scraper o de la base de datos |
El campo status de cada evento puede contener:
| Valor | Significado |
|---|---|
| UPCOMING | No ha comenzado |
| LIVE | En juego. En futbol tambien llega 1', 45', 90'; en otros deportes 1st, 2nd, Q3, Set 2 |
| FT | Finalizado. Tambien puede llegar Canc., Postp., Susp. |
El parametro status de los filtros acepta solamente UPCOMING, LIVE o FT.
Lista los deportes que tienen eventos almacenados, con la cantidad de eventos disponibles.
| Parametro | Tipo | Requerido | Default | Descripcion |
|---|---|---|---|---|
| lang | string | opcional | en | en o es |
{
"lang": "es",
"total": 4,
"sports": [
{ "sport": "baseball", "name": "Béisbol", "count": 22 },
{ "sport": "basketball", "name": "Básquetbol", "count": 36 },
{ "sport": "football", "name": "Fútbol", "count": 367 },
{ "sport": "tennis", "name": "Tenis", "count": 114 }
]
}
/api/sports?lang=en | /api/sports?lang=es
Lista las ligas/competiciones de un deporte, con pais, cantidad de partidos y rango de fechas cubierto.
| Parametro | Tipo | Requerido | Ubicacion | Descripcion |
|---|---|---|---|---|
| sport | string | REQUERIDO | path | Clave del deporte (ver tabla en Conceptos generales) |
| lang | string | opcional | query | en o es (default en) |
{
"lang": "en",
"sport": "baseball",
"sport_name": "Baseball",
"total": 3,
"leagues": [
{
"sport": "baseball",
"competition": "MLB",
"competition_country": "USA",
"competition_flag": "us",
"count": 15,
"first_date": "2026-09-18",
"last_date": "2026-09-18",
"sport_name": "Baseball"
}
]
}
Errores
400 { "error": "Deporte invalido. Opciones: football, basketball, ..." }
/api/sports/baseball/leagues?lang=en
Alternativa con query params al endpoint anterior. Sin sport devuelve las ligas de todos los deportes.
| Parametro | Tipo | Requerido | Default | Descripcion |
|---|---|---|---|---|
| sport | string | opcional | - | Filtrar por deporte |
| lang | string | opcional | en | en o es |
/api/leagues?lang=en&sport=basketball
Todos los partidos de una liga con el detalle completo de cada evento (equipos, banderas, marcador, estado, canales y disponibilidad de alineacion) mas la tabla de posiciones de la competicion. La liga debe ir URL-encoded.
| Parametro | Tipo | Requerido | Default | Descripcion |
|---|---|---|---|---|
| sport | string | REQUERIDO (path) | - | Clave del deporte |
| liga | string | REQUERIDO (path) | - | Nombre exacto de la liga, URL-encoded. Ej: Liga%20Nacional |
| lang | string | opcional | en | en o es. El nombre de la liga depende del idioma |
| country | string | opcional | - | Filtrar por pais cuando hay ligas homonimas |
| from | string | opcional | - | Fecha inicio YYYY-MM-DD |
| to | string | opcional | - | Fecha fin YYYY-MM-DD |
| status | string | opcional | - | FT, LIVE o UPCOMING |
| limit | integer | opcional | todos | Maximo de partidos a devolver |
| offset | integer | opcional | 0 | Desplazamiento para paginacion |
{
"lang": "es",
"sport": "baseball",
"sport_name": "Béisbol",
"league": {
"name": "MLB",
"country": "Estados Unidos",
"total": 15,
"first_date": "2026-09-18",
"last_date": "2026-09-18"
},
"filters": { "country": null, "from": null, "to": null, "status": null, "limit": 3, "offset": 0 },
"has_standings": true,
"standings": [
{ "displayName": "MLB", "seasonNum": 223, "headers": [ { "key": "gamesWon", "name": "W" }, { "key": "pct", "name": "PCT" } ],
"rows": [ { "competitor": { "name": "Tampa Bay Rays" }, "gamesWon": 93, "pct": ".612", "position": 1 } ] }
],
"total": 3,
"matches": [
{
"id": 486,
"sport": "baseball",
"sport_name": "Béisbol",
"date": "2026-09-18",
"competition": "MLB",
"competition_country": "Estados Unidos",
"time": "6:40pm",
"status": "UPCOMING",
"home_team": "Cincinnati Reds",
"away_team": "Chicago Cubs",
"home_flag": "us",
"away_flag": "us",
"score": "",
"channels": [],
"match": "Cincinnati Reds vs Chicago Cubs",
"has_formation": false
}
]
}
Errores
400 { "error": "Deporte invalido. Opciones: football, basketball, ..." }
404 { "error": "Liga no encontrada para el deporte 'baseball'" }
/api/sports/baseball/leagues/MLB/matches?lang=en
/api/sports/basketball/leagues/Liga%20Nacional/matches?lang=es&limit=2
Tabla de posiciones de una liga, para cualquier deporte (futbol, basquet, beisbol, etc.). La liga se mapea a su competitionId por nombre y pais y se consulta la fuente.
| Parametro | Tipo | Requerido | Default | Descripcion |
|---|---|---|---|---|
| sport | string | REQUERIDO (path) | - | Clave del deporte |
| liga | string | REQUERIDO (path) | - | Nombre exacto de la liga, URL-encoded |
| lang | string | opcional | en | en o es |
| country | string | opcional | - | Desambiguar ligas homonimas |
{
"lang": "es", "sport": "baseball", "sport_name": "Béisbol",
"league": { "name": "MLB", "country": "Estados Unidos" },
"total": 1,
"standings": [
{ "displayName": "MLB", "headers": [ { "key": "gamesWon", "name": "W" } ],
"rows": [ { "competitor": { "name": "Tampa Bay Rays" }, "gamesWon": 93, "position": 1 } ] }
]
}
Errores
404 { "error": "Liga no encontrada para el deporte 'baseball'" }
/api/sports/baseball/leagues/MLB/standings?lang=es
Partidos de varias ligas (cualquier deporte) para hoy o una fecha/ventana. Lee de la base de datos ya scrapeada, sin consultar la fuente. Acepta POST con JSON o GET con ?leagues= separado por comas.
| Campo | Tipo | Requerido | Default | Descripcion |
|---|---|---|---|---|
| leagues | array | REQUERIDO | - | Lista de ligas. Cada item: string "LaLiga" u objeto {"name","sport","country"} |
| lang | string | opcional | en | en o es |
| sport | string | opcional | all | Filtrar todas las ligas a un deporte |
| date | string | opcional | hoy | Fecha base YYYY-MM-DD |
| days | integer | opcional | 1 | Dias desde date (max. RETENTION_DAYS) |
| limit | integer | opcional | todos | Maximo de partidos por liga |
curl -X POST "http://localhost:5007/api/leagues/matches" -H "Content-Type: application/json" -d '{"lang":"es","leagues":["LaLiga","MLB","WNBA","Liga de Expansión MX","NFL"]}'
Respuesta 200
{
"lang": "es", "date": "2026-09-22", "date_to": "2026-09-22", "days": 1,
"requested": 5, "found": 5, "not_found": [], "total_matches": 21,
"results": [
{
"query": "MLB",
"matched": [ { "sport": "baseball", "competition": "MLB", "country": "Estados Unidos", "flag": "us" } ],
"total": 16,
"matches": [ { "id": 486, "date_display": "mar 22 sep", "time": "10:05am", "match": "New York Yankees vs Tampa Bay Rays" } ]
}
]
}
- Apertura). Si hay ligas homonimas usá country o sport.400 { "error": "Envia 'leagues' (lista de ligas) en el body o como query param separado por comas" }
/api/leagues/matches?lang=es&leagues=MLB,WNBA,LaLiga
Lista de eventos con filtros combinables. Es la via generica si ya conoce el nombre exacto de la competicion.
| Parametro | Tipo | Requerido | Default | Descripcion |
|---|---|---|---|---|
| lang | string | opcional | en | en o es |
| sport | string | opcional | - | Clave del deporte |
| competition | string | opcional | - | Nombre exacto de la liga |
| date | string | opcional | - | Fecha exacta YYYY-MM-DD |
| from | string | opcional | - | Inicio del rango YYYY-MM-DD |
| to | string | opcional | - | Fin del rango YYYY-MM-DD |
| status | string | opcional | - | FT, LIVE o UPCOMING |
| limit | integer | opcional | 100 | Maximo de resultados |
| offset | integer | opcional | 0 | Desplazamiento para paginacion |
date ni from/to, el limit por defecto es 100 y puede que no vea todos los eventos. Use los filtros o /api/calendar para recorrer la agenda completa.{
"total": 2,
"lang": "en",
"filters": {
"date": null, "from": "2026-09-18", "to": "2026-09-18",
"sport": "baseball", "competition": null, "status": null
},
"events": [ { "id": 486, "match": "...", "...": "ver anexo Objeto Evento" } ]
}
/api/events?lang=en&sport=basketball&limit=3
/api/events?lang=en&sport=baseball&from=2026-09-18&to=2026-09-18&limit=2
Atajo de /api/events para la fecha actual del servidor. Por defecto devuelve hoy y mañana; con days se extiende hasta la ventana de retencion (default 7). Ordena los eventos por fecha, deporte, amistosos primero, pais, competicion y hora.
| Parametro | Tipo | Requerido | Default | Descripcion |
|---|---|---|---|---|
| lang | string | opcional | en | en o es |
| sport | string | opcional | - | Clave del deporte |
| competition | string | opcional | - | Nombre exacto de la liga |
| days | integer | opcional | 2 | Dias a incluir desde hoy (maximo RETENTION_DAYS) |
{
"date": "2026-09-22",
"date_to": "2026-09-23",
"days": 2,
"dates": ["2026-09-22", "2026-09-23"],
"total": 36,
"lang": "en",
"filters": { "sport": "basketball", "competition": null },
"events": [ { "id": 486, "date": "2026-09-24", "date_display": "Thu 24 Sep", "...": "ver anexo Objeto Evento" } ]
}
/api/events/today?lang=es
/api/events/today?lang=en&sport=basketball&days=7
Detalle de un evento por su ID numerico interno. Ademas de los campos del evento, incluye el objeto detail con todas las pestanas: alineaciones (titulares, suplentes, posicion, stats por jugador), timeline (goles, tarjetas, sustituciones), estadisticas, tendencias, clasificacion, duelos previos, predicciones, estadio, arbitros, stages y TV. Con ?detail=0 se omite el detalle (respuesta mas rapida).
| Parametro | Tipo | Requerido | Default | Descripcion |
|---|---|---|---|---|
| id | integer | REQUERIDO (path) | - | ID del evento (campo id del listado) |
| lang | string | opcional | en | en o es |
| detail | integer | opcional | 1 | 0 para omitir el objeto detail |
{
"id": 486, "match": "Arema FC vs Persik Kediri", "has_formation": true,
"detail": {
"venue": { "name": "Stadion Kanjuruhan", "capacity": 44912, "attendance": 4084 },
"referees": ["Dika Rahmat Hidayat"],
"status": { "text": "Ended", "game_time": 90.0 },
"tv": ["DAZN US - USA"],
"statistics": [ { "name": "Possession", "side": "home", "value": "44%", "value_percentage": 0.44, "is_major": true } ],
"trends": [ { "text": "Persik Kediri won - 6/7 Last Matches", "bet": "Persik Kediri to win", "percentage": 0.857 } ],
"standings": [ { "displayName": "Super League", "headers": [ { "key": "points", "name": "PTS" } ], "rows": [ { "competitor": { "name": "..." }, "points": 25 } ] } ],
"previous_meetings": [ { "date": "2026-05-03", "home_team": "Persik Kediri", "away_team": "Arema FC", "home_score": 3, "away_score": 2 } ],
"predictions": [ { "title": "Who Will Win?", "options": [ { "name": "Arema FC", "percentage": 59 } ] } ],
"lineups": {
"home": { "name": "Arema FC", "formation": "4-3-3", "starters": [ { "name": "A. Satryo", "jersey": 30, "position": "Goalkeeper", "stats": { "Minutes": "90'" } } ], "subs": [] },
"away": { "name": "Persik Kediri", "formation": "4-3-3", "starters": [], "subs": [] }
},
"timeline": [ { "minute": "6'", "type": "Goal", "subtype": "Field Goal", "team": "away", "player": "Zanadin Fariz" } ]
}
}
Errores
404 { "error": "Evento no encontrado" }
/api/events/1?lang=en
Calendario de juegos agrupado por dia (formato ideal para una vista de agenda). Sin filtros, recorre todo el rango de fechas almacenado.
| Parametro | Tipo | Requerido | Default | Descripcion |
|---|---|---|---|---|
| lang | string | opcional | en | en o es |
| sport | string | opcional | - | Clave del deporte |
| competition | string | opcional | - | Nombre exacto de la liga |
| from | string | opcional | primera fecha en BD | Fecha inicio YYYY-MM-DD |
| to | string | opcional | ultima fecha en BD | Fecha fin YYYY-MM-DD |
| limit | integer | opcional | 1000 | Maximo de eventos totales |
{
"lang": "en",
"sport": "tennis",
"sport_name": "Tennis",
"competition": null,
"from": "2026-09-18",
"to": "2026-09-18",
"total": 114,
"days": [
{
"date": "2026-09-18",
"total": 114,
"events": [ { "id": 530, "match": "Juan Pablo Varillas vs Adolfo Daniel Vallejo", "...": "ver anexo" } ]
}
]
}
/api/calendar?lang=en&sport=tennis
/api/calendar?lang=es&sport=basketball&from=2026-09-18&to=2026-09-18
Alineacion del partido: formacion tactica, titulares y suplentes con foto. Devuelve la alineacion probable cuando aun no hay confirmada (lineup_status: Confirmed/Probable). Disponible principalmente en futbol; si la fuente no publica ninguna alineacion devuelve 404. Solo se incluyen fotos de los jugadores que las tengan. La primera peticion descarga las fotos (puede tardar ~20s); las siguientes usan cache y responden al instante.
| Parametro | Tipo | Requerido | Default | Descripcion |
|---|---|---|---|---|
| id | integer | REQUERIDO (path) | - | ID del evento |
| lang | string | opcional | en | en o es (nombres de posiciones) |
{
"home_formation": "4-2-3-1",
"away_formation": "3-4-3",
"home_players": [
{
"athlete_id": 239541,
"name": "Leluma Mofoka",
"short_name": "L. Mofoka",
"jersey": 1,
"position": "Portero",
"position_short": "POR",
"formation_position": "GK",
"formation_short": "GK",
"status": "Starting",
"field_line": 0,
"field_side": 50,
"image": "/api/images/players/239541.png"
}
],
"away_players": [],
"home_subs": [],
"away_subs": [],
"lineup_status": "Probable",
"is_probable": true
}
field_line (0-100, 0 = arco propio, 100 = arco rival) y field_side (0-100, 50 = centro) permiten pintar al jugador sobre un campo. image puede ser "" si no existe foto. lineup_status indica si es Confirmed o Probable.404 { "error": "Evento no encontrado" }
404 { "error": "No hay alineaciones disponibles" }
/api/events/1/formation?lang=en | /api/events/1/formation?lang=es
Sirve la foto cacheada de un jugador. El campo image de cada jugador ya devuelve esta ruta lista para usar en un <img>. Responde image/png.
<img src="http://TU_HOST:5000/api/images/players/239541.png" alt="Leluma Mofoka" width="62" height="62">
Competiciones almacenadas con su pais y cantidad de partidos. Similar a /api/leagues pero sin rango de fechas ni deporte en la respuesta.
| Parametro | Tipo | Requerido | Default | Descripcion |
|---|---|---|---|---|
| lang | string | opcional | en | en o es |
| sport | string | opcional | - | Filtrar por deporte |
{
"lang": "en",
"sport": null,
"competitions": [
{ "competition": "MLB", "competition_country": "USA", "competition_flag": "us", "count": 15 },
{ "competition": "NPB", "competition_country": "Japan", "competition_flag": "jp", "count": 3 }
]
}
/api/competitions?lang=en
Totales por estado para construir contadores o dashboards.
| Parametro | Tipo | Requerido | Default | Descripcion |
|---|---|---|---|---|
| lang | string | opcional | en | en o es |
| sport | string | opcional | - | Filtrar por deporte |
{
"total": 114,
"finished": 0,
"live": 10,
"upcoming": 104,
"competitions": 32,
"sports": 1,
"lang": "en",
"sport": "tennis"
}
/api/stats?lang=en&sport=tennis
Primera y ultima fecha con datos, util para limitar selectores de fecha en el cliente.
| Parametro | Tipo | Requerido | Default | Descripcion |
|---|---|---|---|---|
| lang | string | opcional | en | en o es |
| sport | string | opcional | - | Filtrar por deporte |
| competition | string | opcional | - | Filtrar por liga |
{ "start": "2026-06-04", "end": "2026-09-18", "lang": "en", "sport": null, "competition": null }
/api/date-range?lang=en
Dispara un scraping bajo demanda (requiere el JSON en el body). Util para forzar la actualizacion o cargar fechas pasadas. Si no se envia start, continua desde la ultima fecha almacenada.
| Campo | Tipo | Requerido | Default | Descripcion |
|---|---|---|---|---|
| start | string | opcional | ultima fecha + 1 | Fecha inicio YYYY-MM-DD |
| end | string | opcional | start | Fecha fin YYYY-MM-DD |
| lang | string | opcional | both | en, es o both |
| sports | array/string | opcional | all | Lista de deportes o "all" |
| update | boolean | opcional | false | true = actualiza eventos existentes; false = solo inserta nuevos |
curl -X POST http://TU_HOST:5000/api/scrape \
-H "Content-Type: application/json" \
-d '{"start": "2026-09-18", "lang": "both", "sports": ["football", "basketball"], "update": true}'
Respuesta 200
{
"message": "Scraping completado",
"sports": ["football", "basketball"],
"result": {
"en": {
"days_scraped": 2,
"new_events": 10,
"updated_events": 0,
"sports": { "football": { "days_scraped": 1, "new_events": 8, "updated_events": 0 } },
"errors": []
},
"es": { "...": "misma estructura" }
}
}
Errores
400 { "error": "Formato de fecha invalido. Use YYYY-MM-DD" }
400 { "error": "fecha fin es anterior a fecha inicio" }
Campos presentes en cada elemento de events, matches y days[].events.
| Campo | Tipo | Descripcion |
|---|---|---|
| id | integer | ID interno del evento. Usar en /api/events/{id} |
| sport | string | Clave del deporte (ej: football) |
| sport_name | string | Nombre del deporte en el idioma solicitado |
| date | string | Fecha del partido YYYY-MM-DD |
| date_display | string | Fecha legible segun idioma (ej: jue 24 sep / Thu Sep 24) |
| time | string | Hora local del partido en America/Los_Angeles (ej: 6:40pm) |
| status | string | UPCOMING, LIVE, FT o marcador de tiempo (45', Q3) |
| competition | string | Nombre de la liga en el idioma solicitado |
| competition_country | string | Pais de la liga (puede ser "" para torneos internacionales) |
| competition_flag | string | Codigo ISO del pais de la liga, o "" para torneos internacionales |
| home_team | string | Equipo o jugador local |
| away_team | string | Equipo o jugador visitante |
| home_flag | string | Codigo ISO del pais del local (seleccion o club), o "" |
| away_flag | string | Codigo ISO del pais del visitante (seleccion o club), o "" |
| home_logo | string | URL del escudo/logo del local servido por el CDN de 365scores, o "" |
| away_logo | string | URL del escudo/logo del visitante, o "" |
| score | string | Marcador "2 - 1" o "" si aun no hay resultado |
| channels | array | Canales de TV que transmiten el partido segun TV_COUNTRY_ID, ej. ["DAZN US - USA"], o [] |
| match | string | Cadena lista para mostrar: "Local vs Visitante" |
| has_formation | boolean | true si existe alineacion almacenada para este partido |
| formation_url | string | Solo si has_formation = true: ruta de /api/events/{id}/formation |
home_flag, away_flag y competition_flag contienen el codigo ISO 3166-1 alpha-2 (o subdivisiones como gb-eng). Aplica tanto a selecciones como a clubes: la fuente informa el pais de cada competidor y de cada liga. Para torneos internacionales (Europe, Asia, International) el valor es "".
Para clubes, home_logo/away_logo traen el escudo oficial directamente desde el CDN 365scores (no requiere proxy). Use flag como respaldo cuando no haya logo.
Para pintar la bandera use flagcdn:
<img src="https://flagcdn.com/16x12/{codigo}.png"
srcset="https://flagcdn.com/32x24/{codigo}.png 2x"
alt="equipo">
| Codigo | Equipo | URL |
|---|---|---|
| es | Spain | flagcdn.com/16x12/es.png |
| gb-eng | England | flagcdn.com/16x12/gb-eng.png |
| us | USA | flagcdn.com/16x12/us.png |
"", el equipo es un club sin bandera asignada; conviene mostrar un placeholder.