Los mercados de predicción se encuentran entre los dominios más exigentes para construir APIs: instrumentos financieros con caducidad, probabilidades cotizadas en tiempo real, eventos con múltiples resultados, relaciones complejas de capital y usuarios humanos junto a bots de trading automatizados. Cada decisión de diseño se pone a prueba de inmediato.
Polymarket, actualmente la plataforma de mercados de predicción más grande del mundo por volumen, ofrece un ecosistema de APIs útil para estudiar este tipo de arquitectura. No es una API CRUD sobre una base de datos: debe equilibrar apertura y seguridad, datos históricos y en tiempo real, además de patrones financieros tradicionales y primitivas cripto-nativas.
Estos son ocho patrones que puedes aplicar al diseñar APIs financieras, de trading o con estado en tiempo real.
Patrón 1: separa las APIs por dominio
Polymarket expone tres APIs, cada una con una responsabilidad clara:
-
Gamma API (
gamma-api.polymarket.com): descubrimiento de mercados, eventos, etiquetas y búsqueda. -
CLOB API (
clob.polymarket.com): libro de órdenes, precios y colocación de órdenes. -
Data API (
data-api.polymarket.com): posiciones de usuario, trades, análisis y tablas de clasificación.
No es solo una convención de nombres. Cada API tiene requisitos distintos:
| API | Consumidor principal | Autenticación | Cadencia |
|---|---|---|---|
| Gamma | Interfaces, buscadores, integraciones | Pública | Navegación y descubrimiento |
| CLOB | Traders y bots | Pública para lectura; autenticada para trading | Baja latencia |
| Data | Dashboards y análisis | Pública, consultada por wallet | Histórico y analítico |
La lección es separar por dominio de uso, no solo por entidad.
Un diseño ingenuo podría concentrar todo bajo una única base:
/markets
/orders
/users
En cambio, conviene preguntar: ¿para qué sirve esta API?
- El descubrimiento necesita filtros, búsqueda y caché.
- El trading necesita baja latencia, firma y validación.
- El análisis necesita consultas agregadas e históricas.
Dar a cada dominio su propia URL base permite escalar, autenticar y evolucionar cada capa de forma independiente.
Patrón 2: prioriza el acceso público para datos de lectura
Los datos de mercado —precios, libros de órdenes, metadatos de eventos y trades históricos— son públicos:
curl "https://gamma-api.polymarket.com/events?limit=5"
No requiere clave API ni OAuth. El consumidor puede consultar datos directamente.
Este enfoque reduce la fricción para la mayor parte de la audiencia: desarrolladores que crean dashboards, alertas, visualizaciones, modelos o bots de análisis. La autenticación aparece solo cuando el usuario intenta realizar una operación con impacto financiero.
Al diseñar una API, separa explícitamente los flujos de lectura y escritura:
GET /events → público
GET /markets/{id} → público
GET /book → público
POST /order → autenticado
DELETE /order/{id} → autenticado
Este patrón funciona especialmente bien cuando el consumo de datos supera ampliamente la producción de datos.
Patrón 3: usa autenticación por niveles según el riesgo
Los endpoints de trading requieren autenticación, pero Polymarket separa dos niveles con propósitos diferentes.
L1: demostrar propiedad de la wallet
La autenticación L1 utiliza una firma EIP-712 de la clave privada del usuario. Su objetivo es probar el control de la wallet y derivar credenciales API.
// L1: usa la clave privada para derivar credenciales API
const credentials = await client.createOrDeriveApiKey();
// { key: "...", secret: "...", passphrase: "..." }
Esta operación ocurre una vez o con poca frecuencia.
L2: firmar solicitudes rutinarias
La autenticación L2 utiliza HMAC-SHA256 con las credenciales derivadas. Se adjunta a cada solicitud de trading:
{
"POLY_ADDRESS": "0x...",
"POLY_SIGNATURE": "<hmac-sha256>",
"POLY_TIMESTAMP": "1716000000",
"POLY_API_KEY": "550e8400-...",
"POLY_PASSPHRASE": "..."
}
La idea es asignar una ceremonia de seguridad proporcional al riesgo:
- L1: “demuestra que controlas esta identidad”.
- L2: “demuestra que esta solicitud proviene de una sesión autorizada”.
No obligues a un cliente de alta frecuencia a firmar con una clave privada en cada petición si ya existe una relación de confianza derivada y limitada.
Este patrón no es exclusivo de cripto. También se puede interpretar como:
- una credencial fuerte y poco frecuente para establecer identidad;
- una credencial de sesión, más ligera, para autorizar solicitudes repetidas.
Patrón 4: modela las órdenes como mensajes firmados
En Polymarket, colocar una orden no equivale simplemente a enviar datos a un servidor. La orden es un mensaje criptográficamente firmado que representa un compromiso financiero exigible.
const response = await client.createAndPostOrder(
{
tokenID: "71321045679...",
price: 0.65,
size: 100,
side: Side.BUY,
},
{
tickSize: "0.01",
negRisk: false,
},
OrderType.GTC
);
El SDK construye una estructura EIP-712 tipada, la firma con la clave privada y envía la firma junto a la orden.
El motor de emparejamiento opera fuera de la cadena, pero las operaciones emparejadas se liquidan en Polygon utilizando esas firmas. El operador no necesita custodiar fondos ni fabricar operaciones: el mensaje firmado ya contiene la autorización.
La diferencia semántica es importante:
API convencional:
"Por favor, ejecuta esta acción en mi nombre."
Orden firmada:
"Aquí tienes un instrumento firmado que autoriza esta operación."
Cuando la carga útil contiene su propia autorización, puedes obtener propiedades útiles como:
- no repudio;
- verificabilidad;
- trazabilidad de la autorización;
- menor dependencia de la confianza en la capa de transporte.
Este enfoque es aplicable a operaciones financieras, documentos legales y acciones de alto riesgo.
Patrón 5: expresa la ontología del dominio en el modelo de datos
Polymarket organiza sus datos alrededor de dos objetos distintos: Eventos y Mercados.
- Un Evento representa una pregunta general.
- Un Mercado representa un resultado binario negociable dentro de ese evento.
Por ejemplo:
- Evento: “¿Quién ganará la carrera por el Senado de EE. UU. de 2026 en Pensilvania?”
- Mercado: “¿Ganará Bob Casey?”
Un evento puede incluir varios mercados:
{
"id": "501",
"title": "2026 Pennsylvania Senate Race",
"negRisk": true,
"markets": [
{
"id": "2301",
"question": "Will Bob Casey win?",
"outcomePrices": "[\"0.42\", \"0.58\"]"
},
{
"id": "2302",
"question": "Will Dave McCormick win?",
"outcomePrices": "[\"0.35\", \"0.65\"]"
},
{
"id": "2303",
"question": "Will a third candidate win?",
"outcomePrices": "[\"0.23\", \"0.77\"]"
}
]
}
La API no solo almacena registros: representa relaciones conceptuales del dominio.
Por ejemplo, los precios se exponen como arrays paralelos. La posición del índice define la relación:
outcomes[0] === outcomePrices[0];
También aparece la bandera negRisk, que señala una relación de capital específica entre mercados del mismo evento.
No aplanes relaciones que sean importantes para ejecutar correctamente una operación. Si un bot ignora negRisk: true, puede calcular mal sus posiciones y asumir un riesgo incorrecto.
Patrón 6: convierte las invariantes financieras en campos tipados
La bandera negRisk representa uno de los patrones más interesantes: convertir equivalencias financieras del dominio en datos programables.
En un evento estándar con múltiples resultados, cada mercado es independiente. En un evento NegRisk, donde exactamente un resultado puede ganar, existe una equivalencia matemática:
1 token “No” en el resultado A ≡ 1 token “Sí” en todos los demás resultados
Por ejemplo:
| Antes | Después |
|---|---|
| 1× No (Otro) | 1× Sí (Casey) + 1× Sí (McCormick) |
Esta relación no queda solo documentada: está implementada en contratos inteligentes y expuesta por la API.
Al operar, la configuración de la orden debe reflejarla:
{
tickSize: "0.01",
negRisk: true
}
La regla práctica es simple: si omitir una restricción del dominio produce un comportamiento incorrecto, esa restricción debe aparecer en la superficie de la API.
No la dejes únicamente como una nota en la documentación.
Ejemplos de invariantes que suelen merecer campos explícitos:
- solo un resultado puede ganar;
- una operación requiere una conversión de posición;
- una orden depende de una modalidad de liquidación;
- un recurso cambia de estado de forma irreversible.
Patrón 7: trata los parámetros dinámicos como estado del mercado
Muchas APIs financieras tratan el tamaño de tick como una configuración estática. Polymarket lo trata como estado dinámico del mercado.
Cuando el precio se acerca a extremos —por encima de 0.96 o por debajo de 0.04— el tamaño de tick mínimo pasa de 0.01 a 0.001:
{
"event_type": "tick_size_change",
"asset_id": "65818619657...",
"old_tick_size": "0.01",
"new_tick_size": "0.001",
"timestamp": "100000000"
}
Tiene sentido: cerca de probabilidades extremas, un tick de 0.01 representa un salto relativo grande.
0.04 → 0.03 = movimiento relativo del 25%
Un tick más pequeño permite expresar probabilidades como 97.3% en lugar de redondear a 97%.
La consecuencia de implementación es importante: no consultes el tick una vez y lo codifiques de forma fija. Suscríbete a los eventos de cambio y actualiza la lógica de construcción de órdenes.
socket.on("tick_size_change", (event) => {
tickSizes.set(event.asset_id, event.new_tick_size);
});
Antes de enviar una orden, usa el valor actual:
const tickSize = tickSizes.get(assetId);
await client.createAndPostOrder(
{
tokenID: assetId,
price: 0.973,
size: 100,
side: Side.BUY,
},
{
tickSize,
negRisk: true,
},
OrderType.GTC
);
El principio general es que, en sistemas financieros, las reglas y parámetros del mercado pueden cambiar. La API debe publicar esas transiciones de estado explícitamente.
Patrón 8: separa los WebSockets según el perfil de consumo
Polymarket utiliza dos sistemas WebSocket distintos.
Canal de Mercado
El Canal de Mercado:
wss://ws-subscriptions-clob.polymarket.com/ws/market
Está orientado a consumidores de trading. Se suscribe por ID de token y entrega:
- instantáneas del libro de órdenes;
- cambios de precio;
- ejecuciones de operaciones;
- cambios de tamaño de tick.
{
"assets_ids": [
"65818619657568813474341868652308942079804919287380422192892211131408793125422"
],
"type": "market"
}
Socket de Datos en Tiempo Real
El Socket de Datos en Tiempo Real:
wss://ws-live-data.polymarket.com
Atiende a otro perfil de consumidor. Transmite comentarios, precios de criptomonedas de Binance y Chainlink, precios de acciones y eventos de interacción social.
{
"action": "subscribe",
"subscriptions": [
{
"topic": "crypto_prices",
"type": "update",
"filters": "btcusdt,ethusd"
}
]
}
La separación evita mezclar necesidades incompatibles:
| Consumidor | Necesidad principal |
|---|---|
| Creador de mercado | Deltas del libro de órdenes con baja latencia |
| Bot de trading | Precios, fills y cambios de tick |
| Dashboard | Comentarios, actividad y feeds generales |
| Interfaz social | Eventos de interacción y contexto en tiempo real |
No intentes resolver todos estos casos con un único WebSocket genérico. Si las audiencias tienen tolerancias de latencia, volúmenes de datos y modos de fallo distintos, ofrece infraestructuras separadas.
Qué tienen en común estos patrones
La API de Polymarket sigue una idea central: hacer visible la estructura real del dominio en lugar de abstraerla en exceso.
- Las tres APIs reflejan límites de dominio reales.
- El acceso público prioriza el descubrimiento y el consumo de datos.
- La autenticación en dos niveles diferencia identidad y autorización rutinaria.
- Las órdenes firmadas representan compromisos verificables.
- La jerarquía Evento/Mercado expone relaciones conceptuales.
-
negRiskconvierte invariantes financieras en datos explícitos. - Los cambios de tick se publican como transiciones de estado.
- Los WebSockets se segmentan por necesidades operativas.
La ergonomía sigue siendo importante: nombres consistentes, errores predecibles y SDKs útiles. Pero en APIs para sistemas complejos, la fidelidad al dominio importa aún más.
Cuando el dominio tiene una distinción relevante, muéstrala. Cuando tiene una restricción, aplícala. Cuando tiene estado cambiante, publícalo.
Top comments (0)