Developers

Market data

List markets, fetch current prices and history, preview order sizing, and stream the live orderbook over WebSocket.

List markets

GET /polymarket/markets[?category=sports]

Returns an array of currently-tradeable markets (the catalogue is filtered to remove resolved or one-sided markets unless the caller has an open position on them):

[
  {
    "id": "will-btc-hit-150k-2026", // slug (also "slug" field)
    "slug": "will-btc-hit-150k-2026",
    "name": "Will BTC hit $150k in 2026?",
    "tokenId": "7239…", // YES token (uint256 decimal)
    "complementTokenId": "8104…", // NO token
    "conditionId": "0xabcd…", // bytes32, needed to open
    "outcome": "Yes",
    "complementOutcome": "No",
    "maxLeverage": 5, // YES-side cap right now
    "noMaxLeverage": 3, // NO-side cap right now
    "maxNotionalPerUser": 25000, // null if uncapped
    "price": 0.62, // YES display price: last trade, with fallbacks when unavailable
    "noPrice": 0.38, // 1 - price
    "groupSlug": "btc-price-2026",
    "groupLabel": "BTC price 2026",
    "conditionLabel": "BTC ≥ $150k by Dec 31",
    "category": "crypto",
    "volume24h": 1234567,
    "endDate": "2026-12-31T23:59:59Z",
    "underlyingAsset": "BTC",
    "volume": 5000000,
    "source": "polymarket",
    "imageUrl": null,
    "description": null,
  },
]

Response is cached server-side for 10s.

The displayed last-trade price can sit outside the current bid/ask spread when no new trade has occurred. It is not an executable quote. Order previews use current execution inputs, and liquidation checks use best bid. Yes and No leverage caps can differ and can change independently of the displayed last trade.

Spot price

GET /polymarket/price/{tokenId}

Returns the most-recent price the backend has seen (WS book mid → cached tick fallback). Always available even when there is no market data subscription.

Price history

GET /polymarket/history/{tokenId}?interval=1h|1d|max[&before=<unix ms>]

Returns { tokenId, history: [{ time, price }, …] }. Server-side caches: 1h → 15s, 1d → 30s, max → 120s.

Order preview

For sizing positions before signing:

GET /polymarket/order-preview?tokenId=…&amount=<usdc>&leverage=<x>&side=yes|no[&priceOverride=<0..1>]

Returns shares, estimated entry, liquidation price, and the binding leverage cap with the reason it bound (price-tier vs. depth vs. spread vs. admin). Use this to discover the exact maxLeverage the open endpoint will accept right now — it can be lower than the market's nominal cap when book depth is thin.

Lending pools

GET /polymarket/lending-pool[?category=sports]   # one pool
GET /polymarket/lending-pools                    # all pools (default + overrides)

Tells the integrator the borrow APR, utilization, and free liquidity. Category-overriding works exactly the same as opening a position — pass the same category value the market reports.

Real-time orderbook

GET /ws/orderbook/{tokenId}   (WebSocket upgrade)

Server pushes:

{ "type": "orderbook",  "data": { "tokenId": "…", "bids": [{ "price": "0.64", "amount": "100" }, …], "asks": [ … ] } }
{ "type": "price_tick", "data": { "time": 1700000000000, "price": 0.65, "bestBid": 0.64, "bestAsk": 0.66 } }

One subscription per connection. To watch multiple tokens, open multiple sockets.

For backfill, REST endpoints expose recent state:

GET /api/orderbook-snapshots?tokenId=…&minutes=30
GET /api/market-trades?tokenId=…&minutes=30