api de cuotas de pinnacle / node.js / fetch / websockets
API de cuotas de Pinnacle en Node.js
GET/kit/v1/markets?sport_id=2&since=141
solo eventos cambiados200 OK
Un script corto de Node.js para la API de cuotas de Pinnacle sin nada que instalar: un bucle de sondeo sobre el fetch global que pide solo lo que cambió desde la última llamada e imprime cada money line que se movió. Exporta tu clave y la URL base de la documentación, y luego ejecútalo sin cambios.
Crear una clave gratuitaSondea con un cursor
El bucle guarda last de cada respuesta y lo devuelve como since, así que tras la primera llamada solo llegan eventos cambiados. Un 429 lleva Retry-After, y el bucle espera exactamente ese tiempo en lugar de fallar.
Node 18 y posteriores incluyen fetch globalmente, así que el script no tiene dependencias. A una llamada cada tres segundos, las 100 llamadas diarias de la clave gratuita duran cinco minutos. Sondea cada 15 minutos para una prueba de todo el día, o pásate a poll para 10 llamadas por segundo.
// Poll the REST feed with a
// since cursor. Node 18+.
const HOST = process.env.ODDS_BASE_URL;
const PATH = "/kit/v1/markets";
const KEY = process.env.ODDS_API_KEY;
const HDRS = {
"x-portal-apikey": KEY,
};
const sleep = (ms) =>
new Promise((r) =>
setTimeout(r, ms));
function moneyLine(ev) {
const p = ev.periods || {};
return (p.num_0 || {}).money_line;
}
async function poll(sportId, ms) {
let since = null;
for (;;) {
const q = new URLSearchParams({
sport_id: String(sportId),
});
if (since !== null)
q.set("since", String(since));
const r = await fetch(
HOST + PATH + "?" + q,
{ headers: HDRS });
if (r.status === 429) {
const w =
r.headers.get("Retry-After");
await sleep(Number(w) * 1000);
continue;
}
if (!r.ok)
throw Error("HTTP " + r.status);
const data = await r.json();
since = data.last;
for (const ev of data.events) {
const ml = moneyLine(ev);
if (ml)
console.log(ev.home, "v",
ev.away, ml);
}
await sleep(ms);
}
}
poll(2, 3000); // 2 = tennis
Selecciona el código para copiarlo.
GET/odds-drop?min_drop=5
a medida que caen los preciosdata: [alerts]
Escucha las caídas desde Node
EventSource es solo del navegador, pero un stream SSE es una solicitud HTTP que permanece abierta. Envía una cabecera Accept: text/event-stream con fetch y luego lee res.body línea a línea: cada línea data: es un lote JSON de alertas. Un objeto suelto en lugar de una lista es un mensaje de control: el saludo connected, o plan_lacks_sse cuando el plan de la clave no tiene stream.
El stream no tiene filtro de deporte, así que comprueba sport a medida que llegan las alertas si solo quieres algunos deportes. min_drop baja hasta 1.
Necesita push, poll + push o bulk.
WSS/ws/feed?key=<your key>
subscribeen menos de 5 s
luego actualizacionessnapshot
Notas sobre WebSocket
El socket espera un mensaje de suscripción en los cinco segundos siguientes a la conexión. El primer frame de cada stream es un snapshot; cada frame posterior actualiza esa línea base. Responde a cada ping con un pong.
Node 22 y posteriores exponen un WebSocket global; en 18, el paquete ws habla el mismo protocolo. Los frames perdidos no se repiten, así que tras una desconexión, conecta de nuevo y empieza desde el snapshot nuevo. Puedes suscribirte por deporte o por hasta 200 IDs de evento por stream.
Necesita el complemento WebSocket en poll, poll + push o bulk.
SIGUIENTEnode node.mjs
Pega, exporta, ejecuta
La clave gratuita ejecuta hoy el script de sondeo. Cuando las caídas o el socket se ganen su sitio en tu código, la página de precios muestra qué plan los añade.