Skip to main content

Documentation Index

Fetch the complete documentation index at: https://stabyl.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

The Stabyl WebSocket API streams real time exchange data and account specific trading updates. Use REST to discover markets and fetch durable baseline state, then use WebSocket subscriptions for low latency updates.

Endpoints

EnvironmentURL
Productionwss://api.stabyl.com/v1/ws
Stagingwss://api-staging.stabyl.com/v1/ws

Authentication

Market data topics can be used without account authentication. Private topics and order commands require an API key:
wss://api-staging.stabyl.com/v1/ws?token=<api_key>
Because the API key is carried in the WebSocket URL, connect from server side automation only. Do not open API-key WebSocket connections from browser, mobile, desktop, or user controlled code, and do not log full WebSocket URLs.

Pair and Topic Naming

REST endpoints use the pair identifier returned by GET /partner/exchange/markets, such as USD/NGN. WebSocket topic names use a topic-safe pair key where / becomes _:
REST pair IDWebSocket pair keyExample topic
USD/NGNUSD_NGNorderbook.USD_NGN
Today, USD/NGN is the supported exchange pair. When more pairs are added, discover them from GET /partner/exchange/markets and derive the topic key by replacing / with _. Use the REST pair ID in command payloads, such as "pair_id": "USD/NGN". Use the topic key only inside topic names, such as trades.USD_NGN.

Message Model

All client and server messages are JSON objects with a type field. Client messages:
TypePurpose
subscribeSubscribe to one or more topics
unsubscribeStop receiving one or more topics
pingOptional application-level heartbeat
commandSubmit an authenticated order command
Server messages:
TypePurpose
subscribedConfirms active topics and returns optional snapshots
unsubscribedConfirms topics were removed
dataCarries a topic update
pongResponds to application-level ping
errorReports a subscription, auth, rate, or format error
command_ackConfirms an order command was accepted for processing
command_errorReports an order command rejection

Basic Session

Connect From A Server

import WebSocket from "ws";

const baseUrl =
  process.env.STABYL_WS_URL ?? "wss://api-staging.stabyl.com/v1/ws";
const apiKey = process.env.STABYL_API_KEY;
const ws = new WebSocket(`${baseUrl}?token=${encodeURIComponent(apiKey)}`);

ws.on("open", () => {
  ws.send(
    JSON.stringify({
      type: "subscribe",
      topics: ["orderbook.USD_NGN", "trades.USD_NGN", "user.orders"],
      snapshot: true,
    }),
  );
});

ws.on("message", (raw) => {
  const message = JSON.parse(raw.toString());
  if (message.type === "data") {
    console.log(message.topic, message.seq, message.data);
  }
});

Reliability Model

Every data message includes:
FieldMeaning
topicTopic that produced the update
seqMonotonic sequence for that topic within the current epoch
epochStream epoch; changes after some server restarts
tsServer event timestamp
dataTopic-specific payload
Store the latest {epoch, seq} per exact topic. On reconnect, send those values in resume. Resume is best-effort; if the server cannot replay from your sequence, rebuild state from REST and continue with fresh WebSocket updates. Use exact topics when you need reliable resume. Wildcard topics are useful for broad monitoring, but exact topics give cleaner recovery behavior.

Operational Limits

Keep each connection focused on the streams it needs:
LimitGuidance
SubscriptionsUp to 50 active topics per connection
Message sizeKeep command and subscription frames compact JSON objects
ReconnectsUse exponential backoff with jitter after disconnects or rate_limited errors
State rebuildsPrefer REST reads for durable state, then use WebSocket for live changes
If a connection receives rate_limited, slow down, reduce the subscription set if needed, and reconnect only after a backoff delay.