MarketMaster
Datos de solo lectura de los mercados de predicción de Kalshi y Polymarket: ventajas de valor esperado, arbitraje entre plataformas, instantáneas de mercado y operaciones de ballenas.
Documentación
Introducción
La API de MarketMaster te brinda acceso programático a nuestro motor de mercados de predicción multiplataforma: edges (mercados mal valorados clasificados por tamaño del edge), markets (instantáneas normalizadas entre plataformas), una consulta de un solo market, diferenciales de arbitraje entre plataformas, el feed de operaciones de ballenas (whale), y un stream WebSocket en tiempo real. Cada endpoint REST es un simple GET que devuelve JSON.
La API es de solo lectura. Nunca coloca operaciones, mueve fondos ni expone datos de ningún usuario individual — solo datos públicos de mercado.
REST · JSON WebSocket streaming Autenticación con API key CORS habilitado Servidor MCP v1
Inicio rápido
1. Genera una clave en tu panel de control (tarjeta de API para desarrolladores). Cópiala — solo se muestra una vez.
2. Envíala en el encabezado x-api-key.
3. Llama a un endpoint.
curl
curl "https://api.marketmaster.live/v1/edges?limit=5" \
-H "x-api-key: mmk_live_your_key_here" \
-H "User-Agent: my-app/1.0"
SDKs y MCP
Clientes oficiales con autenticación, reintentos, manejo de límites de tasa y un User-Agent adecuado integrado. O evita el código por completo y conecta los datos a Claude o Cursor mediante MCP.
JavaScript / TypeScript
npm install @marketmaster/sdk
import { MarketMaster } from "@marketmaster/sdk";
const mm = new MarketMaster({ apiKey: process.env.MM_API_KEY });
const { edges } = await mm.edges({ platform: "kalshi", min_edge: 5 });
Python
pip install marketmaster
from marketmaster import MarketMaster
mm = MarketMaster(api_key="mmk_live_your_key")
edges = mm.edges(platform="kalshi", min_edge=5)["edges"]
MCP — conexión en un clic
Conecta MarketMaster a tu asistente de IA en un solo paso. El servidor alojado te inicia sesión con tu cuenta de MarketMaster, así que no hay clave que copiar.
Claude: el botón copia la URL del servidor y abre la configuración de conectores de Claude. Elige Añadir conector personalizado y pégala.
MCP — Claude Desktop / Cursor
Seis herramientas de solo lectura (mm_edges, mm_markets, mm_market, mm_arbitrage, mm_whales, mm_status) vía npx — sin instalación. Añádelas a claude_desktop_config.json (o ~/.cursor/mcp.json):
{
"mcpServers": {
"marketmaster": {
"command": "npx",
"args": ["-y", "@marketmaster/mcp"],
"env": { "MARKETMASTER_API_KEY": "mmk_live_your_key" }
}
}
}
MCP — endpoint alojado (nada que instalar)
Las mismas seis herramientas también se sirven desde un endpoint MCP Streamable HTTP alojado, para clientes que se conectan a una URL en lugar de iniciar un proceso local. Los clientes que admiten OAuth (Claude, Cursor, VS Code) inician sesión con tu cuenta de MarketMaster; cualquier otro puede enviar la misma API key como token bearer.
https://api.marketmaster.live/mcp
{
"mcpServers": {
"marketmaster": {
"url": "https://api.marketmaster.live/mcp",
"headers": { "Authorization": "Bearer mmk_live_your_key" }
}
}
}
Usa npx de arriba si quieres el servidor ejecutándose localmente; usa el endpoint alojado si tu cliente solo acepta una URL, o prefieres no ejecutar un proceso. Ambos exponen herramientas idénticas y cuentan contra la misma cuota.
MarketMaster está listado en el Registro oficial de MCP como live.marketmaster/mcp y en Smithery. Una descripción legible por máquina del servidor se publica en https://api.marketmaster.live/.well-known/mcp/server-card.json.
Cada herramienta MCP está anotada como readOnlyHint: true. Un agente conectado a MarketMaster puede leer datos de mercado y nada más — no puede colocar una operación, mover fondos ni acceder a la cuenta de otro usuario.
Autenticación
Autentica cada solicitud con tu API key en el encabezado x-api-key. Las claves tienen el formato mmk_live_… y se gestionan desde tu panel de control. Una clave se muestra una sola vez al crearla; guárdala en una variable de entorno, nunca la confirmes en control de versiones, y rótala desde el panel si alguna vez se expone.
Trata tu clave como una contraseña. Las solicitudes sin una clave válida devuelven 401.
Envía siempre un encabezado User-Agent descriptivo. Las solicitudes de agentes de bibliotecas predeterminados (p. ej. python-urllib) pueden ser rechazadas por nuestra protección de bots perimetral. Nuestros SDKs oficiales establecen uno automáticamente.
Convenciones
URL base
https://api.marketmaster.live
| Formato | Todas las solicitudes y respuestas son JSON. |
|---|---|
| Precios | Probabilidades en 0.0–1.0 (p. ej. 0.43 = 43¢ / 43% de probabilidad implícita). |
| Marcas de tiempo | ISO 8601, UTC (p. ej. 2026-06-20T21:25:12Z). |
| Plataformas | kalshi, polymarket. |
| CORS | Habilitado para todos los orígenes — llama directamente desde una aplicación de navegador. |
| Paginación | Los endpoints de listas aceptan limit y offset; la respuesta incluye has_more. |
| Caché | Los endpoints de datos envían Cache-Control: public, max-age=30. |
Precios
Todos los endpoints — incluidos arbitraje, edges, feed de ballenas y streaming WebSocket — están disponibles en todos los niveles.
Gratis
$0/mes
60 req/min · 1,000 req/mes
- Los 6 endpoints REST
- Edges, arbitraje y feed de ballenas
- WebSocket: 1 conexión
- 1 API key
Más popular
API Starter
$9.99/mes
120 req/min · 50,000 req/mes
- Todo lo de Gratis
- Límite de tasa 2×
- WebSocket: 3 conexiones
- No requiere aplicación de consumidor
API Pro
$29.99/mes
300 req/min · 1,000,000 req/mes
- Todo lo de Starter
- Límite de tasa 5×
- WebSocket: 10 conexiones
- Para pipelines de alta frecuencia
MarketMaster Pro (suscripción de consumidor de $12.99/mes) también incluye acceso a la API a 240 req/min · 200k req/mes, WebSocket: 5 conexiones, además de escáner, alertas y superposición.
¿Por qué MarketMaster frente a alternativas?
| Característica | MarketMaster | Competidores |
|---|---|---|
| Feed de arbitraje | ✅ Todos los niveles | Solo Enterprise |
| Clasificación de EV / edges | ✅ Todos los niveles | Solo Enterprise |
| Feed de operaciones de ballenas | ✅ Todos los niveles | Solo Enterprise |
| Streaming WebSocket | ✅ Todos los niveles | Solo Enterprise |
| Precio de entrada | Gratis para siempre | $49+/mes para empezar |
| Kalshi + Polymarket + más | ✅ Unificado | Una sola plataforma |
Límites de tasa
Los límites se aplican por cuenta en dos ventanas: una tasa por minuto y una cuota mensual. Los límites sobreviven a la rotación de claves.
| Nivel | Tasa | Cuota mensual | Conexiones WS |
|---|---|---|---|
free | 60 req / min | 1,000 | 1 |
api_starter | 120 req / min | 50,000 | 3 |
pro (consumidor) | 240 req / min | 200,000 | 5 |
api_pro | 300 req / min | 1,000,000 | 10 |
Encabezados de respuesta de límite de tasa
X-RateLimit-Limit-Minute | Tu límite máximo por minuto. |
|---|---|
X-RateLimit-Remaining-Minute | Solicitudes restantes este minuto. |
X-RateLimit-Limit-Month | Tu cuota mensual. |
X-RateLimit-Remaining-Month | Solicitudes restantes este mes. |
Exceder la tasa por minuto devuelve 429 rate_limited; agotar la cuota mensual devuelve 429 quota_exceeded. Ambos incluyen un encabezado Retry-After en segundos.
Edges
GET/v1/edges
Los mercados más mal valorados en este momento — el valor justo de nuestro modelo frente al precio en vivo, clasificados por tamaño del edge. Devuelve una fila por mercado, deduplicada a la lectura más reciente.
Parámetros de consulta
| Parámetro | Tipo | Descripción |
|---|---|---|
platform | string | Filtrar por plataforma: kalshi, polymarket. |
category | string | Filtrar por categoría, p. ej. politics, sports, crypto. |
limit | integer | Máximo de filas. Predeterminado 50, máximo 200. |
offset | integer | Filas a omitir. Predeterminado 0. |
min_edge | number | Edge mínimo en puntos porcentuales. |
Respuesta: edges[]
| Campo | Tipo | Descripción |
|---|---|---|
platform | string | Plataforma. |
market_id | string | Identificador de mercado nativo de la plataforma. |
market_title | string | Pregunta del mercado. |
market_category | string | Categoría (p. ej. politics). |
outcome | string | YES o NO. |
price | number | Precio de mercado en vivo para el lado indicado por outcome (0–1). En una fila NO este es el precio NO, no el precio SÍ. |
fair_value | number | Probabilidad justa estimada por el modelo para el lado indicado por outcome (0–1). Cada campo de precio en una fila — price, fair_value, ask — se cotiza en ese mismo lado, así que fair_value − price es siempre el edge a tu favor. |
edge_pct | number | Edge en puntos porcentuales. Más grande = más mal valorado. |
confidence | number | Confianza del modelo (0–1). |
match_group_id | integer | ID de grupo de coincidencia entre plataformas. Los mercados que comparten este ID son el mismo evento del mundo real en diferentes plataformas. |
expires_at | string | Cuándo cierra el mercado (ISO 8601). |
computed_at | string | Cuándo se calculó este edge (ISO 8601). |
Ejemplo
curl
curl "https://api.marketmaster.live/v1/edges?platform=kalshi&limit=2" \
-H "x-api-key: mmk_live_your_key_here"
JavaScript
const res = await fetch(
"https://api.marketmaster.live/v1/edges?platform=kalshi&limit=2",
{ headers: { "x-api-key": process.env.MM_API_KEY } }
);
const { edges } = await res.json();
Python
import requests
r = requests.get(
"https://api.marketmaster.live/v1/edges",
params={"platform": "kalshi", "limit": 2},
headers={"x-api-key": MM_API_KEY},
)
edges = r.json()["edges"]
Respuesta
{
"count": 2,
"edges": [{
"platform": "kalshi", "market_id": "PRES-2028-DEM",
"market_title": "Will a Democrat win the 2028 election?",
"outcome": "YES", "price": 0.43, "fair_value": 0.51,
"edge_pct": 8.0, "confidence": 0.62,
"expires_at": "2028-11-07T05:00:00Z", "computed_at": "2026-06-20T21:25:12Z"
}],
"generated_at": "2026-06-20T21:25:34Z"
}
Markets
GET/v1/markets
La instantánea más reciente de todos los mercados rastreados en ambas plataformas — título, categoría, precio SÍ/NO, volumen de 24h y hora de cierre. Ordenados por volumen de 24h (los más activos primero).
Parámetros de consulta
| Parámetro | Tipo | Descripción |
|---|---|---|
source | string | Filtrar por plataforma (alias: platform). |
category | string | Filtrar por categoría. |
limit | integer | Máximo de filas. Predeterminado 100, máximo 500. |
offset | integer | Filas a omitir. Predeterminado 0. |
Respuesta: markets[]
| Campo | Tipo | Descripción |
|---|---|---|
source | string | Plataforma. |
source_market_id | string | ID de mercado nativo de la plataforma. |
title | string | Pregunta del mercado. |
category | string | Categoría. |
yes_price | number | Precio SÍ actual (0–1). |
no_price | number | Precio NO actual (0–1). |
volume_24h_usd | number | null | Volumen negociado en 24h en USD. |
close_time | string | null | Hora de cierre del mercado (ISO 8601). |
last_trade_at | string | null | Marca de tiempo de la última operación (ISO 8601). |
fetched_at | string | Cuándo capturamos la instantánea de este mercado por última vez (ISO 8601). |
curl
curl "https://api.marketmaster.live/v1/markets?category=politics&limit=50" \
-H "x-api-key: mmk_live_your_key_here"
Market
GET/v1/market
La instantánea más reciente de un solo mercado más cualquier edge en vivo calculado para él. Identifícalo por source + id.
Parámetros de consulta
| Parámetro | Tipo | Descripción |
|---|---|---|
source | string · obligatorio | Plataforma: kalshi, polymarket. |
id | string · obligatorio | ID de mercado nativo de la plataforma. |
Devuelve market (misma forma que markets[]) y edges[] (misma forma que edges[], más recientes primero). Un ID desconocido devuelve 404 not_found.
curl
curl "https://api.marketmaster.live/v1/market?source=kalshi&id=PRES-2028-DEM" \
-H "x-api-key: mmk_live_your_key_here"
Arbitraje
GET/v1/arbitrage
Diferenciales de precios entre plataformas para el mismo resultado en mercados emparejados, clasificados del más amplio al más estrecho.
Los diferenciales son indicativos y brutos de comisiones, deslizamiento y profundidad de oferta/demanda — no son arbitraje garantizado. Siempre confirma los precios ejecutables en la plataforma.
Parámetros de consulta
| Parámetro | Tipo | Descripción |
|---|---|---|
min_spread | number | Diferencial mínimo en puntos porcentuales. |
limit | integer | Máximo de filas. Predeterminado 50, máximo 200. |
offset | integer | Filas a omitir. Predeterminado 0. |
Respuesta: opportunities[]
| Campo | Tipo | Descripción |
|---|---|---|
match_group_id | integer | Grupo de coincidencia entre plataformas. |
title | string | Pregunta del mercado. |
outcome | string | Resultado que se compara (YES / NO). |
spread_pct | number | Precio más caro menos el más barato, en puntos porcentuales. |
buy_yes | object | Plataforma más barata: { platform, market_id, price }. |
sell_yes | object | Plataforma más cara: { platform, market_id, price }. |
computed_at | string | Cuándo se calcularon estos precios (ISO 8601). |
curl
curl "https://api.marketmaster.live/v1/arbitrage?min_spread=2&limit=10" \
-H "x-api-key: mmk_live_your_key_here"
Ballenas
GET/v1/whales
Operaciones recientes grandes con dinero real entre plataformas, de la más reciente a la más antigua.
Parámetros de consulta
| Parámetro | Tipo | Descripción |
|---|---|---|
source | string | Filtrar por plataforma. |
min | integer | Tamaño mínimo de operación en USD. |
limit | integer | Máximo de filas. Predeterminado 50, máximo 200. |
offset | integer | Filas a omitir. Predeterminado 0. |
Respuesta: trades[]
| Campo | Tipo | Descripción |
|---|---|---|
source | string | Recinto. |
source_market_id | string | Identificador de mercado nativo del recinto. |
trader_name | string | null | Identificador público del operador, cuando esté disponible. |
side | string | Lado de la operación (buy / sell). |
outcome | string | Resultado negociado. |
size_usd | number | Tamaño nocional en USD. |
price | number | Precio de la operación (0–1). |
title | string | Pregunta del mercado. |
trade_time | string | Cuándo se registró la operación (ISO 8601). |
tx_hash | string | null | Hash de transacción en cadena para recintos en cadena. |
curl
curl "https://api.marketmaster.live/v1/whales?min=10000&limit=20" \
-H "x-api-key: mmk_live_your_key_here"
Estado
Devuelve el nivel de tu clave, los límites y el uso actual. Úsalo para monitorear la cuota restante.
{
"ok": true,
"tier": "free",
"limits": { "minute": 60, "month": 1000 },
"usage": { "minute": 3, "month": 412 }
}
Transmisión por WebSocket
Conéctate una vez y recibe eventos enviados en el momento en que estén listos, sin sondeos. La transmisión envía lotes de bordes y notificaciones de operaciones de ballenas desde nuestra canalización de ingesta a medida que se produce cada lote.
WSS /v1/stream Tiempo real
URL de conexión
wss://api.marketmaster.live/v1/stream
Autenticación
Tu clave de API debe enviarse al momento de la conexión. Dos opciones según el entorno:
| Entorno | Cómo autenticar |
|---|---|
| Node.js / Python / servidor | Pasa x-api-key: mmk_live_... en los encabezados de la solicitud de actualización de WebSocket. |
| Navegador | Agrega ?api_key=mmk_live_... como parámetro de consulta: los navegadores no pueden establecer encabezados personalizados en conexiones WebSocket. |
Nunca expongas tu clave de API en código público del lado del cliente en el navegador. Usa un token de corta duración o un relé del lado del servidor para implementaciones en navegador.
Canales
edges
Enviado cada ~10 min
Nuevo lote de bordes calculado. Obtén /v1/edges al recibirlo para la lista actualizada.
whales
Enviado cada ~5 min
Nuevas operaciones de ballenas ingeridas. Obtén /v1/whales al recibirlo para las últimas ejecuciones.
prices/*
Reservado
Transmisión de precios por mercado: próximamente.
La transmisión envía una notificación ligera (recuento + marca de tiempo) en lugar de la carga útil completa. Extrae el endpoint REST correspondiente al recibirla para obtener los datos; esto mantiene pequeñas las cargas útiles de la transmisión y te permite filtrar antes de obtener.
Mensajes de cliente → servidor (enviar como JSON)
| Acción | Carga útil | Efecto |
|---|---|---|
subscribe | {"action":"subscribe","channel":"edges"} | Comienza a recibir eventos para este canal. |
unsubscribe | {"action":"unsubscribe","channel":"edges"} | Deja de recibir eventos para este canal. |
ping | {"action":"ping"} | El servidor responde con pong. Úsalo para mantener viva la conexión. |
Mensajes de servidor → cliente (recibir como JSON)
| Tipo | Ejemplo de carga útil | Cuándo |
|---|---|---|
welcome | {"type":"welcome","tier":"free","conn_id":"abc"} | Inmediatamente al conectar. |
subscribed | {"type":"subscribed","channel":"edges"} | Después de una suscripción exitosa. |
event | {"type":"event","channel":"edges","data":{"count":34,"ts":1751000000000}} | Nuevos datos disponibles para un canal suscrito. |
pong | {"type":"pong"} | Respuesta a tu ping. |
error | {"type":"error","code":"too_many_connections","message":"..."} | Fallo de autenticación, límite de conexiones superado o mensaje no válido. |
Límites de conexión por nivel
| Nivel | Máximo de conexiones concurrentes | Máximo de suscripciones a canales / conexión |
|---|---|---|
free | 1 | 5 |
api_starter | 3 | 20 |
pro (consumidor) | 5 | 50 |
api_pro | 10 | 100 |
Ejemplo: navegador
JavaScript (navegador)
// Pass key as query param; browsers can't set WebSocket headers
const ws = new WebSocket(
\`wss://api.marketmaster.live/v1/stream?api_key=${MM_API_KEY}\`
);
ws.onopen = () => {
ws.send(JSON.stringify({ action: "subscribe", channel: "edges" }));
ws.send(JSON.stringify({ action: "subscribe", channel: "whales" }));
};
ws.onmessage = async (e) => {
const msg = JSON.parse(e.data);
if (msg.type === "event" && msg.channel === "edges") {
// New edge batch — pull fresh data
const { edges } = await fetch("/v1/edges?limit=20", {
headers: { "x-api-key": MM_API_KEY }
}).then(r => r.json());
renderEdges(edges);
}
};
// Keep-alive ping every 30s
setInterval(() => ws.send(JSON.stringify({ action: "ping" })), 30_000);
Ejemplo: Node.js
JavaScript (Node.js / biblioteca ws)
import WebSocket from "ws";
const ws = new WebSocket("wss://api.marketmaster.live/v1/stream", {
headers: { "x-api-key": process.env.MM_API_KEY },
});
ws.on("open", () => {
ws.send(JSON.stringify({ action: "subscribe", channel: "edges" }));
ws.send(JSON.stringify({ action: "subscribe", channel: "whales" }));
});
ws.on("message", (raw) => {
const msg = JSON.parse(raw);
console.log(msg.type, msg.channel ?? "", msg.data ?? "");
});
Ejemplo: Python
Python (biblioteca websockets)
import asyncio, json, websockets
async def stream():
uri = "wss://api.marketmaster.live/v1/stream"
async with websockets.connect(uri, extra_headers={"x-api-key": MM_API_KEY}) as ws:
await ws.send(json.dumps({"action": "subscribe", "channel": "edges"}))
await ws.send(json.dumps({"action": "subscribe", "channel": "whales"}))
async for raw in ws:
msg = json.loads(raw)
print(msg["type"], msg.get("channel"), msg.get("data"))
asyncio.run(stream())
Errores
Los errores devuelven el estado HTTP apropiado con un envoltorio JSON:
{ "error": { "code": "rate_limited", "message": "Per-minute rate limit exceeded." } }
| Estado | Código | Significado |
|---|---|---|
401 | missing_api_key | No se envió el encabezado x-api-key. |
401 | invalid_api_key | La clave está mal formada, es desconocida o fue revocada. |
400 | invalid_parameter | Parámetro de consulta no válido o falta un parámetro obligatorio. |
404 | not_found | No se encontró ningún recurso (p. ej., identificador de mercado desconocido). |
426 | websocket_required | /v1/stream debe estar conectado mediante WebSocket. |
429 | rate_limited | Se superó la tasa por minuto: consulta el encabezado Retry-After. |
429 | quota_exceeded | Cuota mensual agotada: se restablece al inicio del mes. |
500 | auth_error | Problema temporal al validar la clave: reintenta. |
502 | upstream_error | Problema transitorio de carga de datos: reintenta. |
503 | streaming_unavailable | La transmisión por WebSocket no está disponible temporalmente. |
Los marcos de error de WebSocket usan la misma forma code / message, entregada como mensaje JSON antes de que el servidor cierre la conexión.
Versionado y cambios
La API tiene versión en la ruta (/v1/). Podemos agregar nuevos campos a las respuestas y nuevos canales a la transmisión en cualquier momento: escribe clientes que ignoren campos desconocidos y tipos de mensajes. Los cambios disruptivos se publicarían bajo una nueva ruta de versión. Esta es una versión temprana; los endpoints, límites y canales de transmisión pueden evolucionar.
Aviso legal
Las cifras de bordes y valor justo son estimaciones de modelo solo con fines informativos. No son asesoramiento de inversión ni garantía de ganancias. Los datos se proporcionan tal cual, sin garantía. Eres responsable de cumplir con los términos y las leyes aplicables de cualquier recinto en el que operes.