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 solo de 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 (tarjeta Developer API). 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 — 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ñade 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 alojado de Streamable HTTP, para clientes que se conectan a una URL en lugar de iniciar un proceso local. Autentica con la misma clave como token de portador.
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 con 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 clave API en el encabezado x-api-key. Las claves tienen el formato mmk_live_… y se gestionan desde tu panel. Una clave se muestra una vez al crearla; guárdala en una variable de entorno, nunca la confirmes en el 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 biblioteca 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 clave API
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 |
| Clasificaciones de EV / edge | ✅ 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 (0–1). |
fair_value | number | Probabilidad justa estimada por el modelo (0–1). |
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 última instantánea de este mercado (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. Identifica 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 coincidentes, 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 grandes recientes 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 | Plataforma. |
source_market_id | string | ID de mercado nativo de la plataforma. |
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 plataformas on-chain. |
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, límites y uso actual. Úsalo para monitorear la cuota restante.
{
"ok": true,
"tier": "free",
"limits": { "minute": 60, "month": 1000 },
"usage": { "minute": 3, "month": 412 }
}
Streaming WebSocket
Conéctate una vez y recibe eventos enviados en el momento en que están listos — sin sondeo. El stream envía lotes de edges y notificaciones de operaciones de ballenas desde nuestro pipeline de ingesta a medida que se produce cada lote.
WSS /api/v1/stream Tiempo real
URL de conexión
wss://api.marketmaster.live/api/v1/stream
Autenticación
Tu clave API debe enviarse en el momento de la conexión. Dos opciones según el entorno:
| Entorno | Cómo autenticarse |
|---|---|
| Node.js / Python / servidor | Pasa x-api-key: mmk_live_... en los encabezados de la solicitud de actualización de WebSocket. |
| Navegador | Añade ?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 de navegador público del lado del cliente. 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 edges 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 los últimos llenados.
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 relevante al recibirla para obtener los datos; esto mantiene las cargas útiles de la transmisión pequeñas 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 la conexión activa. |
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 excedido o mensaje invá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/api/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/api/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/api/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á malformada, es desconocida o fue revocada. |
400 | invalid_parameter | Parámetro de consulta inválido o falta un parámetro requerido. |
404 | not_found | No se encontró ningún recurso (p. ej., id de mercado desconocido). |
426 | websocket_required | /api/v1/stream debe estar conectado vía WebSocket. |
429 | rate_limited | Se excedió la tasa por minuto: verifica 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 WebSocket no está disponible temporalmente. |
Los marcos de error de WebSocket usan la misma forma code / message, entregados como un mensaje JSON antes de que el servidor cierre la conexión.
Versionado y cambios
La API está versionada 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 y tipos de mensaje desconocidos. 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 edge 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 plataforma en la que operes.