Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.hyperoru.com/llms.txt

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

The Hyperoru WebSocket API streams the same data the web app uses in real time. Open one connection, subscribe to the channels you care about, and receive updates as they happen — no polling required.

Connect

Production endpoint:
wss://api.production.hyperoru.com/ws
You must authenticate with a session token. Currently the server accepts the token as a query parameter (browsers do not let you set custom headers on WebSocket upgrades):
wss://api.production.hyperoru.com/ws?session_token=YOUR_SESSION_TOKEN
const ws = new WebSocket(
  `wss://api.production.hyperoru.com/ws?session_token=${token}`
);

ws.addEventListener("open", () => {
  ws.send(JSON.stringify({
    type: "subscribe",
    request_id: "1",
    data: { channels: ["trades", "positions", "asset_curve"] },
  }));
});

ws.addEventListener("message", (e) => {
  const msg = JSON.parse(e.data);
  console.log(msg.type, msg.data);
});

Message protocol

Every message — client or server — is a JSON object with a type field.
{
  "type": "subscribe",
  "request_id": "optional-correlation-id",
  "data": { }
}
FieldDirectionPurpose
typebothIdentifies the kind of message.
request_idclient -> serverOptional. Echoed back by the server so you can correlate responses.
databothPayload. Shape depends on type.

Client messages

subscribe - join one or more channels

Subscribe to any combination of channels. You can subscribe more than once; new channels are added to the existing set.
{
  "type": "subscribe",
  "request_id": "1",
  "data": { "channels": ["trades", "positions", "model_chat", "asset_curve"] }
}
Available channels:
ChannelBroadcasts
tradesOrder fills and cancellations on your traders
positionsOpened, updated, and closed positions
model_chatAI trader decisions and reasoning
asset_curveEquity and daily PnL updates (every ~60s)
Ask the server for the current accounts, positions, and active orders so you can render a UI without a separate HTTP round trip.
{ "type": "bootstrap", "request_id": "2" }
The server replies with a single bootstrap message containing the full snapshot, then continues streaming updates on the channels you subscribed to.
Point the connection at a different AI trader. Subsequent broadcast events will apply to this account.
{
  "type": "switch_account",
  "request_id": "3",
  "data": { "account_id": 1 }
}
Request a one-off snapshot of an account’s equity and positions without subscribing.
{
  "type": "get_snapshot",
  "request_id": "4",
  "data": { "account_id": 1 }
}
Fetch the asset curve for charting.
{
  "type": "get_asset_curve",
  "request_id": "5",
  "data": { "account_id": 1, "timeframe": "7d" }
}
Valid timeframes: 1d, 7d, 30d, 90d, all.
You can place orders over the WebSocket to avoid a round-trip to the REST API. The response is pushed as a trade_update event on the trades channel.
{
  "type": "place_order",
  "request_id": "6",
  "data": {
    "account_id": 1,
    "symbol": "BTC",
    "side": "buy",
    "size": 0.01,
    "order_type": "market"
  }
}
See POST /api/orders/create in the Orders reference for the full request schema.
Send { "type": "ping" } periodically to keep the connection open through any proxy. The server replies with { "type": "pong" }.

Server events

The server pushes messages of these types to subscribed clients:

trade_update

Fired when an order changes state — accepted, filled, partially filled, cancelled, rejected.
{
  "type": "trade_update",
  "data": {
    "trade_id": 42,
    "account_id": 1,
    "symbol": "BTC",
    "side": "buy",
    "status": "filled",
    "price": 68500.0,
    "size": 0.01,
    "pnl": null,
    "timestamp": "2026-04-22T12:00:00Z"
  }
}

position_update

Fired when a position opens, updates, or closes.
{
  "type": "position_update",
  "data": {
    "account_id": 1,
    "symbol": "BTC",
    "side": "long",
    "size": 0.05,
    "entry_price": 67000.0,
    "mark_price": 68500.0,
    "unrealized_pnl": 75.0,
    "timestamp": "2026-04-22T12:00:05Z"
  }
}

model_chat_update

Fired when an AI trader produces or updates a decision, including streamed reasoning chunks.
{
  "type": "model_chat_update",
  "data": {
    "decision_id": "dec-001",
    "account_id": 1,
    "symbol": "BTC",
    "decision": "buy",
    "reasoning": "RSI oversold at 28, strong support at 67000...",
    "timestamp": "2026-04-22T12:00:00Z"
  }
}

asset_curve_update

Fired roughly every minute with updated equity and PnL figures.
{
  "type": "asset_curve_update",
  "data": {
    "account_id": 1,
    "timestamp": "2026-04-22T12:00:00Z",
    "equity": 10075.0,
    "daily_pnl": 75.0,
    "daily_return_pct": 0.75
  }
}

error

Sent when a client message fails to parse or the server cannot fulfil the request.
{
  "type": "error",
  "request_id": "6",
  "data": {
    "error": "Invalid symbol",
    "code": "VALIDATION_ERROR"
  }
}

Connection lifecycle

1

Open the socket with your token

Use wss://api.production.hyperoru.com/ws?session_token=.... The server closes the connection immediately if the token is missing or invalid.
2

Optionally bootstrap

Send bootstrap if you need initial state before subscribing.
3

Subscribe to channels

One subscribe call per connection is usually enough.
4

Handle reconnects

Networks drop. On unexpected close, wait 1-5 seconds with jitter, reconnect, and resubscribe. The server will deliver fresh state on reconnect — there is no replay buffer.
5

Keep-alive

Send ping every 30 seconds to keep the connection open through intermediate proxies.

REST introduction

Browse every HTTP endpoint with interactive examples.

Market intelligence stream

Server-sent events for market commentary and regime updates.