Skip to main content

Endpoint

wss://api.vatic.trading/ws
No authentication required. Connect and subscribe to any asset + interval combination.

Why use WebSocket over polling?

The REST target endpoints have a ~1–5s publish lag at window boundaries while Chainlink/Binance finalise the price. If you poll right as a new window opens you get a 502. The WebSocket absorbs that wait server-side and pushes the price to you the instant it resolves — with no rate limits.

Connection flow

1. Connect

On connect the server immediately sends a connected event:
{
  "event": "connected",
  "supportedAssets": ["btc", "eth", "sol", "xrp", "hype", "doge", "bnb"],
  "supportedMarketTypes": ["5min", "15min", "1hour", "4hour", "daily"],
  "usage": "Send {\"type\":\"subscribe\",\"asset\":\"btc\",\"marketTypes\":[\"5min\",\"15min\"]}"
}

2. Subscribe

Send a JSON message to subscribe to one asset across one or more intervals:
{
  "type": "subscribe",
  "asset": "btc",
  "marketTypes": ["5min", "15min"]
}
FieldTypeDescription
type"subscribe"Required.
assetstringOne of the supported asset symbols.
marketTypesstring[]One or more interval types. Omit to subscribe to all five.
The server confirms with a subscribed event and immediately sends a window_open snapshot for the current window of each subscribed interval — so you’re never blind while waiting for the next boundary.
{ "event": "subscribed", "asset": "btc", "marketTypes": ["5min", "15min"] }

3. Receive price events

At every window boundary the server pushes a window_open event for each subscribed asset + interval:
{
  "event": "window_open",
  "asset": "btc",
  "marketType": "5min",
  "windowStart": 1744027500,
  "windowStartIso": "2025-04-07T12:05:00.000Z",
  "price": 82450.75,
  "source": "chainlink"
}
The initial snapshot after subscribe includes "snapshot": true. If the upstream fetch fails after 6 retries, you receive window_open_error instead:
{
  "event": "window_open_error",
  "asset": "btc",
  "marketType": "5min",
  "windowStart": 1744027500,
  "windowStartIso": "2025-04-07T12:05:00.000Z",
  "error": "Price unavailable — upstream fetch failed after retries"
}

4. Unsubscribe

{ "type": "unsubscribe" }
This removes all subscriptions for the current connection.

Heartbeat

The server sends a WebSocket ping every 30 seconds. If your client does not respond with a pong the connection is terminated. Most WebSocket client libraries handle this automatically.

Example — Node.js

import WebSocket from 'ws';

const ws = new WebSocket('wss://api.vatic.trading/ws');

ws.on('message', (raw) => {
  const msg = JSON.parse(raw);

  if (msg.event === 'connected') {
    ws.send(JSON.stringify({
      type: 'subscribe',
      asset: 'btc',
      marketTypes: ['5min', '15min'],
    }));
  }

  if (msg.event === 'window_open') {
    console.log(`[${msg.marketType}] ${msg.asset} opened at ${msg.price} (${msg.windowStartIso})`);
  }
});

Example — Browser

const ws = new WebSocket('wss://api.vatic.trading/ws');

ws.onmessage = ({ data }) => {
  const msg = JSON.parse(data);
  if (msg.event === 'connected') {
    ws.send(JSON.stringify({ type: 'subscribe', asset: 'eth', marketTypes: ['1hour'] }));
  }
  if (msg.event === 'window_open') {
    console.log(msg);
  }
};

Event reference

EventDirectionDescription
connectedServer → ClientSent immediately on connect.
subscribedServer → ClientConfirms a successful subscribe.
unsubscribedServer → ClientConfirms unsubscribe.
window_openServer → ClientPrice pushed at every window boundary. Also sent as a snapshot on subscribe.
window_open_errorServer → ClientSent when the upstream price fetch fails after all retries.
errorServer → ClientInvalid JSON, unknown asset, or unknown message type.
subscribeClient → ServerSubscribe to asset + intervals.
unsubscribeClient → ServerRemove all subscriptions.