REST + Streaming Model
Most Conyr primitives come in two shapes: a REST query for current state and point lookups, and a WebSocket stream that pushes every update live. They serve the same data — pick REST to backfill, the stream to stay current.
| Data | REST query | WebSocket channel |
|---|---|---|
| Trades / tape | GET /v1/token/{mint}/trades | token:{mint}:trades |
| Chart ticks | — | token:{mint}:ticks |
| OHLCV candles | GET /v1/token/{mint}/ohlcv | token:{mint}:ohlcv:{view}:{tf} |
| Wallet PnL | GET /v1/wallet/{addr}/pnl | wallet:{addr}:pnl |
| Positions | GET /v1/wallet/{addr}/positions | wallet:{addr}:positions |
| Wallet labels | GET /v1/wallet/{addr}/labels | wallet:{addr}:labels |
| Token security | GET /v1/token/{mint}/suspicious-activity | token:{mint}:security |
The zero-gap pattern
Fetch the snapshot
Call the REST endpoint to load current state (open positions, the last candles, recent trades).
Subscribe to the stream
Open wss://api.conyr.ai/ws and subscribe to the matching channel for the same mint or address.
Apply events on top
Merge incoming stream events into your snapshot. Because the stream picks up from the moment you connect, there’s no gap between the backfill and the live feed.
Connecting
wss://api.conyr.ai/wsconst ws = new WebSocket("wss://api.conyr.ai/ws");
ws.onopen = () => {
ws.send(JSON.stringify({
op: "subscribe",
channels: ["token:EPjFWd...:trades"],
}));
};
ws.onmessage = (event) => {
const msg = JSON.parse(event.data);
if (msg.channel) console.log(`[${msg.channel}]`, msg.data);
};Data events arrive as {"channel": "...", "data": { ... }}. The full message lifecycle, every channel pattern, and per-tier limits live in the WebSocket Protocol and Channel Catalog.
WebSocket access starts at Layer 1. See Tiers & Rate Limits for connection and subscription caps.