> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polynode.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Crypto Prices

> Real-time crypto price streaming over WebSocket. 7 assets, ~1 update per second per feed.

Stream real-time crypto prices over WebSocket. 7 feeds, \~1 update per second each.

## Connection

```
wss://ws.polynode.dev/ws?key=YOUR_API_KEY
```

This is the same WebSocket endpoint used for settlements and orderbook. If you already have a connection open, you don't need a new one.

## Available feeds

| Feed       | Pair                    | Update rate |
| ---------- | ----------------------- | ----------- |
| `BTC/USD`  | Bitcoin / US Dollar     | \~1/second  |
| `ETH/USD`  | Ethereum / US Dollar    | \~1/second  |
| `SOL/USD`  | Solana / US Dollar      | \~1/second  |
| `BNB/USD`  | BNB / US Dollar         | \~1/second  |
| `XRP/USD`  | XRP / US Dollar         | \~1/second  |
| `DOGE/USD` | Dogecoin / US Dollar    | \~1/second  |
| `HYPE/USD` | Hyperliquid / US Dollar | \~1/second  |

## Quick start

Connect and subscribe to all 7 feeds:

<CodeGroup>
  ```javascript JavaScript theme={null}
  const WebSocket = require("ws");

  const ws = new WebSocket(
    "wss://ws.polynode.dev/ws?key=YOUR_API_KEY"
  );

  ws.on("open", () => {
    ws.send(JSON.stringify({
      action: "subscribe",
      type: "chainlink"
    }));
  });

  ws.on("message", (data) => {
    const msg = JSON.parse(data);
    if (msg.type === "price_feed") {
      console.log(`${msg.data.feed}: $${msg.data.price}`);
    }
  });
  ```

  ```python Python theme={null}
  import asyncio
  import json
  import websockets

  async def main():
      uri = "wss://ws.polynode.dev/ws?key=YOUR_API_KEY"
      async with websockets.connect(uri) as ws:
          await ws.send(json.dumps({
              "action": "subscribe",
              "type": "chainlink"
          }))
          async for message in ws:
              msg = json.loads(message)
              if msg.get("type") == "price_feed":
                  d = msg["data"]
                  print(f"{d['feed']}: ${d['price']}")

  asyncio.run(main())
  ```

  ```rust Rust theme={null}
  use polynode::PolyNodeWS;

  #[tokio::main]
  async fn main() {
      let mut ws = PolyNodeWS::connect("YOUR_API_KEY").await.unwrap();
      ws.subscribe_price_feeds(None).await.unwrap(); // None = all feeds

      while let Some(event) = ws.next_event().await {
          println!("{}: ${}", event.feed, event.price);
      }
  }
  ```

  ```bash wscat theme={null}
  wscat -c "wss://ws.polynode.dev/ws?key=YOUR_API_KEY"

  # Then send:
  {"action": "subscribe", "type": "chainlink"}
  ```
</CodeGroup>

### Filter to specific feeds

Only receive the feeds you care about:

```json theme={null}
{
  "action": "subscribe",
  "type": "chainlink",
  "filters": {
    "feeds": ["BTC/USD", "ETH/USD"]
  }
}
```

Omit `feeds` to get all 7.

## Event format

Every price update arrives as a `price_feed` event:

```json theme={null}
{
  "type": "price_feed",
  "feed": "BTC/USD",
  "timestamp": 1774672588,
  "data": {
    "feed": "BTC/USD",
    "price": 66225.49,
    "bid": 66221.69,
    "ask": 66229.46,
    "timestamp": 1774672588
  }
}
```

See [Event Format](/crypto/event-format) for the full field reference.

## Combining with other streams

Crypto prices run on the same WebSocket connection as settlements, orderbook, and oracle streams. Send multiple subscribe messages:

<CodeGroup>
  ```javascript JavaScript theme={null}
  // Settlements + crypto prices on the same connection
  ws.on("open", () => {
    ws.send(JSON.stringify({ action: "subscribe", type: "settlements" }));
    ws.send(JSON.stringify({ action: "subscribe", type: "chainlink" }));
  });

  ws.on("message", (data) => {
    const msg = JSON.parse(data);
    if (msg.type === "price_feed") {
      // crypto price tick
      console.log(`${msg.data.feed}: $${msg.data.price}`);
    } else if (msg.type === "settlement") {
      // polymarket settlement
      console.log(`${msg.data.market_title}: ${msg.data.outcome}`);
    }
  });
  ```

  ```python Python theme={null}
  await ws.send(json.dumps({"action": "subscribe", "type": "settlements"}))
  await ws.send(json.dumps({"action": "subscribe", "type": "chainlink"}))

  async for message in ws:
      msg = json.loads(message)
      if msg.get("type") == "price_feed":
          d = msg["data"]
          print(f"Price: {d['feed']} ${d['price']}")
      elif msg.get("type") == "settlement":
          d = msg["data"]
          print(f"Settlement: {d['market_title']}: {d['outcome']}")
  ```
</CodeGroup>

Use the `type` field (`"price_feed"` vs `"settlement"`) to route events.

## REST Endpoints

In addition to the WebSocket stream, crypto data is available via REST. See the [REST API reference](/crypto/rest-api) for full details.

| Endpoint                                                      | Description                                        |
| ------------------------------------------------------------- | -------------------------------------------------- |
| `GET /v1/crypto/markets`                                      | All crypto prediction markets                      |
| `GET /v1/crypto/candles?symbol=BTC`                           | 5-min OHLC candles from Chainlink oracle           |
| `GET /v1/crypto/ticks?symbol=BTC&from={unix_ms}&to={unix_ms}` | 1-second historical price ticks for chart backfill |
| `GET /v1/crypto/price?symbol=BTC&window={epoch}`              | Open/close price for a market window               |
| `GET /v1/crypto/active`                                       | Currently active 5-minute markets for all 7 coins  |
| `GET /v1/crypto/series`                                       | Recurring crypto market series                     |

All endpoints require an API key via `?key=` or `x-api-key` header.

## Short-Form Crypto Markets

<Info>
  **These prices power prediction markets.** All 7 coins have active 5-minute, 15-minute, and 1-hour "Up or Down" prediction markets on Polymarket. The Chainlink price feed determines the opening price (price-to-beat), and the closing price at window end decides the outcome. Hundreds of trades happen every minute on these markets.
</Info>

Here's how it works: a BTC 5-minute market opens at 10:00 with BTC at $66,800. If BTC is above $66,800 at 10:05, "Up" wins. If it's below, "Down" wins. A new market opens at 10:05 with the new price as the target. This repeats every 5 minutes, 15 minutes, and every hour, across all 7 coins.

### What you can do with this

| Stream                     | What it gives you                                  | How to get it                                       |
| -------------------------- | -------------------------------------------------- | --------------------------------------------------- |
| **Chainlink prices**       | Underlying asset price at \~1/sec                  | `subscribe('chainlink')` on the main WS             |
| **Historical price ticks** | 1-second chart backfill for an already-open window | `GET /v1/crypto/ticks`                              |
| **Short-form settlements** | Every trade on 5m/15m/1h markets                   | SDK `shortForm('15m')` auto-rotates between windows |
| **Short-form orderbook**   | Bid/ask depth on crypto markets                    | `OrderbookEngine` with `clobTokenIds` from rotation |
| **Price-to-beat**          | Chainlink opening price per window                 | Included in SDK rotation events                     |
| **Odds & liquidity**       | Market-implied probabilities                       | Included in SDK rotation events                     |

### Quick example

Track BTC price alongside 15-minute market odds:

```javascript theme={null}
import { PolyNodeWS } from 'polynode-sdk';

const ws = new PolyNodeWS('pn_live_...', 'wss://ws.polynode.dev/ws');

// Live BTC price from Chainlink
const prices = await ws.subscribe('chainlink')
  .feeds(['BTC/USD'])
  .send();

prices.on('price_feed', (msg) => {
  console.log(`BTC: $${msg.price}`);
});

// 15-minute market rotation + settlements
const stream = ws.shortForm('15m', { coins: ['btc'] });

stream.on('rotation', (r) => {
  const m = r.markets[0];
  console.log(`Window: beat $${m.priceToBeat} | ${(m.upOdds * 100).toFixed(0)}% up | ${r.timeRemaining}s left`);
});

stream.on('settlement', (e) => {
  console.log(`Trade: ${e.outcome} $${e.taker_size}`);
});
```

<Tip>
  The SDK handles market discovery, slug computation, token resolution, and automatic rotation between windows. See [Short-Form Markets](/sdks/short-form) for the full reference including the interactive slug calculator, all 14 market fields, and how to connect the orderbook.
</Tip>

### Market slug patterns

Slugs are deterministic, based on the window's Unix epoch timestamp:

| Interval | Pattern                     | Example                                   |
| -------- | --------------------------- | ----------------------------------------- |
| 5 min    | `{coin}-updown-5m-{epoch}`  | `btc-updown-5m-1775399100`                |
| 15 min   | `{coin}-updown-15m-{epoch}` | `eth-updown-15m-1775397600`               |
| 1 hour   | Human-readable              | `bitcoin-up-or-down-april-5-2026-10am-et` |

The epoch timestamp is always aligned to the interval boundary: `Math.floor(now / intervalSeconds) * intervalSeconds`.

## Use cases

* **Short-form market trading** -- track the underlying asset price alongside 5m/15m/1h crypto markets
* **Portfolio valuation** -- combine real-time crypto prices with Polymarket positions for live PnL
* **Hedging signals** -- correlate crypto price moves with prediction market settlements
* **Dashboards** -- display live crypto prices alongside prediction market data
* **Trading bots** -- trigger Polymarket trades based on crypto price thresholds
