Webhook de eventos de partidos de fútbol
Recibe cada gol, tarjeta y cambio, además del inicio, el descanso y el final de las ligas, equipos, jugadores o partidos que elijas, como una petición POST en JSON a tu propia URL. No hay que consultar nada ni gestionar claves de API: llamamos a tu endpoint en cuanto registramos el evento.
Úsalo para alimentar tu propio bot, un overlay para tus directos, una hoja de cálculo o tu domótica. En la app, este destino se llama «Servidor HTTP».
Qué recibes
Una petición HTTP POST por evento, para los eventos que elijas:
- Pitido inicial
- Goles, con el goleador y el asistente cuando nuestros datos los incluyen
- Tarjetas amarillas y rojas
- Cambios
- Resultado al descanso
- Resultado final
- Para una liga o un equipo: los nuevos vídeos y Shorts de YouTube de los canales que seguimos para ellos
Sigue una liga entera, un equipo, un jugador o un solo partido. Una liga cubre todos sus partidos. Un jugador solo recibe los eventos en los que aparece: goles, asistencias, tarjetas y cambios. Un partido suelto se detiene solo con el pitido final.
El cuerpo es el propio evento, con los mismos campos para todos los tipos: un solo manejador sirve para todo.
Ejemplo de petición
Un gol, tal como lo recibe tu endpoint (valores de ejemplo; el orden de los campos puede variar):
POST /hooks/9f2c51e7a4 HTTP/1.1
Content-Type: application/json
{
"eventId": "6f1d2c3e-8a4b-4c5d-9e6f-7a8b9c0d1e2f",
"matchId": "1234567",
"type": "goal",
"country": "England",
"countryId": "44",
"countryLogo": "https://example.com/flags/england.png",
"league": "Coastal League",
"leagueId": "300",
"leagueLogo": "https://example.com/logos/coastal-league.png",
"matchStadium": "Riverside Park",
"matchReferee": "M. Keller",
"teamHome": "Riverside FC",
"teamHomeId": "5001",
"teamHomeBadge": "https://example.com/badges/riverside-fc.png",
"teamHomeScore": "1",
"teamAway": "Northbridge Athletic",
"teamAwayId": "5002",
"teamAwayBadge": "https://example.com/badges/northbridge-athletic.png",
"teamAwayScore": "0",
"time": "31",
"score": "1 - 0",
"side": "home",
"player1": "J. Moreno",
"player1Id": "70001",
"player2": "L. Okafor",
"player2Id": "70002",
"card": "",
"timestamp": { "_seconds": 1792855872, "_nanoseconds": 512000000 }
}Configuración
1. Crea un endpoint
Tu endpoint tiene que aceptar una petición POST con cuerpo JSON y responder con un estado 2xx. Esta es una versión mínima en Node.js, con una ruta difícil de adivinar que hace de secreto:
import http from "node:http";
http.createServer((req, res) => {
if (req.method !== "POST" || req.url !== "/hooks/9f2c51e7a4") return res.writeHead(404).end();
let body = "";
req.on("data", (chunk) => (body += chunk));
req.on("end", () => {
const event = JSON.parse(body);
if (event.type === "goal") console.log(`${event.player1} scores: ${event.teamHome} ${event.score} ${event.teamAway}`);
res.writeHead(204).end();
});
}).listen(8080);Despliégalo en una dirección HTTPS pública.
2. Crea la integración
- Inicia sesión en Football Live Score y abre la página de la liga, el equipo, el jugador o el partido que quieres seguir.
- Elige Crear integración, ponle un nombre y selecciona Webhook HTTP como destino.
- Pega la dirección de tu endpoint en URL del webhook y elige Enviar mensaje de prueba. Tu endpoint recibe una petición cuyo cuerpo es solo {"type": "✅ Football Live Score: tu integración funciona."}. Responde con un estado 2xx y la prueba se da por buena.
- Elige los eventos. Gol ya está marcado.
- Elige Crear integración.
En la app, toca el botón de retransmisión en la pantalla de un partido, un equipo, una liga o un jugador, añade un destino Servidor HTTP con la misma URL, elige los eventos e inicia la retransmisión.

Campos de la petición
Todas las peticiones tienen los mismos campos. Todos los valores son cadenas, salvo timestamp y, en los eventos de YouTube, post. Un campo que no corresponde al evento es una cadena vacía.
- eventId: ID único del evento. Si dos de tus integraciones cubren el mismo evento, las dos peticiones llevan el mismo eventId, así que puedes descartar los duplicados.
- type: match_started, match_half_time, match_ended, goal, card, substitution, youtube o youtube-short.
- matchId: el ID del partido (vacío en los eventos de YouTube).
- country, countryId, countryLogo: el país de la competición, su ID y la URL de su bandera.
- league, leagueId, leagueLogo: el nombre, el ID y la URL del logo de la competición.
- matchStadium, matchReferee: estadio y árbitro, cuando se conocen.
- teamHome, teamHomeId, teamHomeBadge, teamHomeScore: nombre, ID, URL del escudo y marcador actual del equipo local.
- teamAway, teamAwayId, teamAwayBadge, teamAwayScore: lo mismo para el equipo visitante.
- time: el minuto de un gol, una tarjeta o un cambio, tal como lo escribe nuestra fuente de datos.
- score: el marcador como «local - visitante», por ejemplo "1 - 0". En un gol, el marcador después de ese gol.
- side: home o away, es decir, el equipo que marcó, recibió la tarjeta o hizo el cambio.
- player1, player1Id: el goleador, el jugador amonestado o expulsado, o el jugador que entra.
- player2, player2Id: el asistente (vacío si no hay), o el jugador que sale.
- card: la tarjeta tal como la nombra nuestra fuente de datos, por ejemplo "yellow card" o "red card".
- timestamp: cuándo registramos el evento, como un objeto con _seconds (tiempo Unix) y _nanoseconds.
- post: solo en los eventos de YouTube, el vídeo, con post.youtubeData.title, post.youtubeData.url y post.channelDisplayName, entre otros.
Entrega
- Formato: una petición POST con Content-Type: application/json y el evento como cuerpo. Una petición por evento e integración, nunca agrupadas.
- Éxito: cualquier estado 2xx. Un estado 4xx o 5xx, o un error de conexión, cuenta como fallo.
- Sin reintentos: una entrega fallida no se vuelve a enviar. Aparece como error en el registro de la integración.
- Fallos repetidos: tras varios fallos seguidos, la integración pasa a Error y deja de enviar. Una entrega correcta pone el contador a cero.
- Orden: las peticiones salen de forma independiente, así que dos eventos del mismo minuto pueden llegar en cualquier orden.
- Seguridad: las peticiones no van firmadas ni llevan token. Usa una dirección HTTPS con una parte aleatoria larga, como en el ejemplo, e ignora las peticiones a cualquier otra ruta.
- Petición de prueba: el botón de prueba solo envía el campo type, así que asegúrate de que tu código acepta un cuerpo sin los demás campos.
Preguntas
¿Necesito una clave de API?
No. Nos das una URL. No hay ninguna clave que pedir, renovar ni enviar.
¿Puedo recibir solo los goles?
Sí. Marca solo Gol al crear la integración. Puedes cambiar los eventos más tarde con Editar.
¿Por qué he recibido el mismo gol dos veces?
Seguramente porque dos de tus integraciones lo cubren, por ejemplo una para la liga y otra para el equipo. Cada una envía el evento, con el mismo eventId. Descartar los eventId repetidos resuelve esto y también la rara entrega duplicada.
¿Es lo mismo que el destino «Servidor HTTP» de la app?
Sí. La app lo llama «Servidor HTTP» y la web «Webhook HTTP». Los dos envían la misma petición.
¿Con qué rapidez llegan los mensajes?
En cuanto el evento llega a nuestros datos en directo: el mensaje sale en pocos minutos.
¿Cómo pauso o elimino una integración?
En la web, abre tu cuenta y luego Integraciones. Cada integración muestra su estado, cuántos mensajes se han enviado o han fallado, un registro de los últimos envíos y botones para pausarla, editarla o eliminarla. En la app, tus retransmisiones están en la pestaña de la cuenta.
¿Qué pasa tras el pitido final?
Una integración que sigue un solo partido se detiene sola cuando este termina. Las que siguen una liga, un equipo o un jugador continúan, partido tras partido, hasta que las pauses o las elimines.
¿Qué competiciones puedo seguir?
Todas las ligas y copas de nuestra página de cobertura.
¿Cuesta algo?
Las integraciones son gratuitas por ahora. Más adelante podría llegar una suscripción.