API Overview
The mackinac API exposes real-time and historical market data for 13 venues across DEX, perpetual, and yield markets through two transports: a WebSocket feed (/feed) for live streaming and a REST API (/v1/history/) for historical queries. Both use the same normalized message shapes — a client that parses a live print frame can reuse its parser against the historical trades endpoint unchanged.
All endpoints are served from wss://api.mackinac.io (WebSocket) and https://api.mackinac.io (REST).
Quick start
import asyncio, json, websockets
async def main(): async with websockets.connect("wss://api.mackinac.io/feed") as ws: # Authenticate (required for paid tier; optional for free) await ws.send(json.dumps({"action": "auth", "key": "mk_live_..."})) authed = json.loads(await ws.recv()) print(authed) # {"type":"authed","tier":"api","symbolLimit":100}
# Subscribe to a perp and an AMM pair await ws.send(json.dumps({"action": "subscribe", "exchange": "hl", "symbol": "ETH"})) await ws.send(json.dumps({"action": "subscribe", "exchange": "uni", "symbol": "WETH/USDC"}))
async for raw in ws: msg = json.loads(raw) print(msg["type"], msg.get("exchange"), msg.get("symbol"))
asyncio.run(main())What’s in the API
| Surface | Path | Description |
|---|---|---|
| Live feed | wss://.../feed | Subscribe to quotes, trades, funding, depth, LP events, yield snapshots |
| Historical queries | GET /v1/history/{exchange}/{symbol}/{kind} | Same message shapes, paginated, from inception |
| Yield-market history | GET /v1/history/rates/{address} | Rate-market snapshots keyed by PT contract address |
| Venue catalog | GET /v1/markets, /v1/symbols, /v1/instruments | Runtime discovery — what venues and symbols are live |
| Auth | POST /api/auth/*, GET /api/auth/me | JWT, wallet, API-key management |
Venue coverage
13 live venues across 5 venue classes:
| Class | Venues | Message types |
|---|---|---|
| CLOB perp | hl, dydx | quote, print (+ microstructure), funding |
| Oracle perp | gmx, vertex, ostium | quote, funding; Ostium also print |
| AMM spot | uni, univ4, univ4chain, sushi, pancake, balancer | quote, print, depth, liquidity |
| Yield rate | pendle, spectra | rate_market, print; Pendle also rate_depth |
| Virtual | ammbook, ammliquidity, rates | Consolidated cross-venue streams |
See Venues & Symbols for the full matrix.
Two tiers
Free (none) | Paid (api) | |
|---|---|---|
| Live streaming | ✓ | ✓ |
| Concurrent symbols | 3 | 100 |
| Historical lookback | 1 day | Full retention |
| API keys | — | ✓ (up to 3) |
Authenticate anonymously (free) or with an API key (paid). See Authentication and Tiers & Limits.
Machine-readable specs
The REST endpoints are described in an OpenAPI 3.1 spec; every WebSocket message type has a JSON Schema. Use these to generate typed clients rather than hand-transcribing the docs:
# Python (Pydantic v2)datamodel-codegen --input ./schemas/ --input-file-type jsonschema \ --output messages.py --output-model-type pydantic_v2.BaseModel
datamodel-codegen --input ./openapi.yaml --input-file-type openapi \ --output rest.py --output-model-type pydantic_v2.BaseModel
# TypeScriptnpx openapi-typescript ./openapi.yaml --output ./rest.d.tsnpx json-schema-to-typescript -i './schemas/*.schema.json' -o ./messages.d.tsWhere to go next
- Authentication — get a JWT, a wallet sign-in, or an API key
- Venues & Symbols — venue matrix and symbol naming rules
- WebSocket — connect, subscribe, heartbeat, reconnect
- Message Types — every frame the server can emit
- Historical REST — pull paginated time-series data
- Discovery REST — enumerate live venues and symbols at runtime
- Errors — error codes and retry guidance
- Tiers & Limits — symbol caps, lookback limits, tier determination