WebSocket Messages
The Trading API uses WebSocket connections for real-time event streaming. This reference documents all message types exchanged between your strategy and the Trading API.
Message Format
All messages use JSON with an internally-tagged format. The type field identifies the message type:
{"type": "ping", "timestamp": "2025-01-15T10:30:00Z"}
{"type": "order", "event": "ORDER_FILLED", "order": {...}}
Client to Server Messages
Your strategy sends these messages to the Trading API.
Pong
Response to a server ping heartbeat. Send this to keep the connection alive.
{
"type": "pong"
}
EventAck
Acknowledge processed events. Required for backtest mode (Tektii Engine — controls time simulation), optional when using the Trading Gateway (paper or live).
| Field | Type | Description |
|---|---|---|
type | string | Always "event_ack" |
correlation_id | string | Unique ID for tracking this acknowledgment |
events_processed | string[] | List of event IDs that were processed |
timestamp | integer | Unix timestamp (milliseconds) when events were processed |
{
"type": "event_ack",
"correlation_id": "550e8400-e29b-41d4-a716-446655440000",
"events_processed": ["evt_123", "evt_124"],
"timestamp": 1700000000000
}
Server to Client Messages
The Trading API sends these messages to your strategy.
Ping
Server heartbeat. Respond with a pong message to keep the connection alive.
{
"type": "ping",
"timestamp": "2025-01-15T10:30:00Z"
}
Order Events
Order state changes. Sent when orders are created, modified, filled, cancelled, or rejected.
| Field | Type | Description |
|---|---|---|
type | string | Always "order" |
event | OrderEventType | Type of order event |
order | Order | Current state of the order |
timestamp | datetime | Event timestamp |
parent_order_id | string? | Parent order ID for bracket/OCO child orders |
OrderEventType values:
| Value | Description |
|---|---|
ORDER_CREATED | New order submitted |
ORDER_MODIFIED | Order parameters changed |
ORDER_CANCELLED | Order cancelled by user or system |
ORDER_REJECTED | Order rejected by provider |
ORDER_FILLED | Order completely filled |
ORDER_PARTIALLY_FILLED | Some quantity filled |
ORDER_EXPIRED | Order expired based on time_in_force |
BRACKET_ORDER_CREATED | Bracket order (with SL/TP) created |
BRACKET_ORDER_MODIFIED | Bracket order modified |
{
"type": "order",
"event": "ORDER_FILLED",
"order": {
"id": "ord_abc123",
"symbol": "AAPL",
"side": "BUY",
"order_type": "MARKET",
"quantity": "100",
"filled_quantity": "100",
"remaining_quantity": "0",
"average_fill_price": "150.25",
"status": "FILLED",
"time_in_force": "GTC",
"created_at": "2025-01-15T10:30:00Z",
"updated_at": "2025-01-15T10:30:01Z"
},
"timestamp": "2025-01-15T10:30:01Z"
}
Position Events
Position state changes. Sent when positions are opened, modified, or closed.
| Field | Type | Description |
|---|---|---|
type | string | Always "position" |
event | PositionEventType | Type of position event |
position | Position | Current state of the position |
timestamp | datetime | Event timestamp |
PositionEventType values:
| Value | Description |
|---|---|
POSITION_OPENED | New position opened |
POSITION_MODIFIED | Position quantity or P&L changed |
POSITION_CLOSED | Position fully closed |
{
"type": "position",
"event": "POSITION_OPENED",
"position": {
"id": "pos_xyz789",
"symbol": "AAPL",
"side": "LONG",
"quantity": "100",
"average_entry_price": "150.25",
"current_price": "150.50",
"unrealized_pnl": "25.00",
"realized_pnl": "0",
"opened_at": "2025-01-15T10:30:01Z",
"updated_at": "2025-01-15T10:30:01Z"
},
"timestamp": "2025-01-15T10:30:01Z"
}
Account Events
Account balance and margin changes.
| Field | Type | Description |
|---|---|---|
type | string | Always "account" |
event | AccountEventType | Type of account event |
account | Account | Current account state |
timestamp | datetime | Event timestamp |
AccountEventType values:
| Value | Description |
|---|---|
BALANCE_UPDATED | Cash balance changed (deposit, withdrawal, trade) |
MARGIN_WARNING | Approaching margin limit |
MARGIN_CALL | Margin limit exceeded, liquidation may occur |
{
"type": "account",
"event": "BALANCE_UPDATED",
"account": {
"balance": "10000.00",
"equity": "10500.00",
"margin_used": "2000.00",
"margin_available": "8500.00",
"unrealized_pnl": "500.00",
"currency": "USD"
},
"timestamp": "2025-01-15T10:30:01Z"
}
Candle Events
OHLCV bar/candlestick data for market analysis.
| Field | Type | Description |
|---|---|---|
type | string | Always "candle" |
bar | Bar | The bar data (includes symbol, provider, timeframe, OHLCV) |
timestamp | datetime | Event timestamp (when event was emitted) |
{
"type": "candle",
"bar": {
"symbol": "AAPL",
"provider": "alpaca",
"timeframe": "1h",
"timestamp": "2025-01-15T10:00:00Z",
"open": "150.00",
"high": "151.50",
"low": "149.75",
"close": "151.25",
"volume": "1234567"
},
"timestamp": "2025-01-15T11:00:00Z"
}
Quote Events
Real-time bid/ask price updates.
| Field | Type | Description |
|---|---|---|
type | string | Always "quote" |
quote | Quote | The quote data (includes symbol, provider, bid/ask/last) |
timestamp | datetime | Event timestamp (when event was emitted) |
{
"type": "quote",
"quote": {
"symbol": "AAPL",
"provider": "alpaca",
"bid": "150.20",
"bid_size": "100",
"ask": "150.25",
"ask_size": "200",
"last": "150.22",
"timestamp": "2025-01-15T10:30:00.123Z"
},
"timestamp": "2025-01-15T10:30:00.123Z"
}
Trade Events
Individual trade/fill execution notifications.
| Field | Type | Description |
|---|---|---|
type | string | Always "trade" |
event | TradeEventType | Type of trade event |
trade | Trade | The executed trade |
timestamp | datetime | Event timestamp |
TradeEventType values:
| Value | Description |
|---|---|
TRADE_FILLED | Trade execution completed |
{
"type": "trade",
"event": "TRADE_FILLED",
"trade": {
"id": "trd_def456",
"order_id": "ord_abc123",
"symbol": "AAPL",
"side": "BUY",
"quantity": "100",
"price": "150.25",
"commission": "0.50",
"commission_currency": "USD",
"is_maker": false,
"timestamp": "2025-01-15T10:30:01Z"
},
"timestamp": "2025-01-15T10:30:01Z"
}
Connection Events
Connection state changes with the Gateway or its upstream broker.
| Field | Type | Description |
|---|---|---|
type | string | Always "connection" |
event | ConnectionEventType | Type of connection event |
broker | string? | Upstream broker/provider identifier (e.g. "alpaca-paper"). Present on BROKER_* variants. |
error | string? | Error message when the event indicates a failure or unexpected disconnect |
gap_duration_ms | integer? | Outage duration in milliseconds. Present on BROKER_RECONNECTED. |
timestamp | datetime | Event timestamp (ISO 8601 UTC) |
ConnectionEventType values:
| Value | Description |
|---|---|
CONNECTED | Strategy successfully connected to the Gateway |
DISCONNECTING | Gateway connection is being closed |
RECONNECTING | Attempting to reconnect after connection loss |
BROKER_DISCONNECTED | Upstream broker link dropped |
BROKER_RECONNECTED | Upstream broker link restored after an outage; gap_duration_ms reports the gap |
BROKER_CONNECTION_FAILED | Initial broker connect failed, or a reconnect attempt failed terminally |
{
"type": "connection",
"event": "CONNECTED",
"timestamp": "2025-01-15T10:30:00Z"
}
{
"type": "connection",
"event": "BROKER_RECONNECTED",
"broker": "alpaca-paper",
"gap_duration_ms": 4200,
"timestamp": "2025-01-15T10:31:04Z"
}
Rate Limit Events
Notifications about API rate limits.
| Field | Type | Description |
|---|---|---|
type | string | Always "rate_limit" |
event | RateLimitEventType | Type of rate limit event |
requests_remaining | integer | Requests remaining in current window |
reset_at | datetime | When the rate limit window resets |
timestamp | datetime | Event timestamp |
RateLimitEventType values:
| Value | Description |
|---|---|
RATE_LIMIT_WARNING | Approaching rate limit |
RATE_LIMIT_HIT | Rate limit exceeded, requests will be rejected |
{
"type": "rate_limit",
"event": "RATE_LIMIT_WARNING",
"requests_remaining": 10,
"reset_at": "2025-01-15T10:31:00Z",
"timestamp": "2025-01-15T10:30:55Z"
}
Data Staleness Events
Emitted when the Gateway detects that upstream market-data freshness for one or more symbols has crossed a threshold. Useful for pausing or resuming trading logic that depends on live quotes.
| Field | Type | Description |
|---|---|---|
type | string | Always "data_staleness" |
event | DataStalenessEventType | STALE when data goes stale, FRESH when it recovers |
symbols | string[] | Affected symbols |
stale_since | datetime? | Timestamp (ISO 8601 UTC) when data first went stale. Present on STALE. |
broker | string? | Upstream broker/provider identifier, when the staleness is scoped to a specific provider |
timestamp | datetime | Event timestamp (ISO 8601 UTC) |
DataStalenessEventType values:
| Value | Description |
|---|---|
STALE | Upstream data freshness fell below the configured threshold |
FRESH | Upstream data freshness has recovered |
{
"type": "data_staleness",
"event": "STALE",
"symbols": ["AAPL", "MSFT"],
"stale_since": "2025-01-15T10:30:00Z",
"broker": "alpaca-paper",
"timestamp": "2025-01-15T10:30:05Z"
}
{
"type": "data_staleness",
"event": "FRESH",
"symbols": ["AAPL", "MSFT"],
"broker": "alpaca-paper",
"timestamp": "2025-01-15T10:31:12Z"
}
Error Events
Error notifications from the server.
| Field | Type | Description |
|---|---|---|
type | string | Always "error" |
code | WsErrorCode | Error code |
message | string | Human-readable error message |
details | any? | Additional error details |
timestamp | datetime | Event timestamp |
WsErrorCode values:
| Value | Description |
|---|---|
INVALID_MESSAGE | Malformed message received |
INTERNAL_ERROR | Internal server error |
POSITION_UNPROTECTED | A position is open without its configured bracket protection (stop-loss or take-profit) attached |
LIQUIDATION | Position was forcibly liquidated by the broker or risk engine |
OCO_DOUBLE_EXIT | Both legs of an OCO group fired before the cancel for the second leg reached the broker |
{
"type": "error",
"code": "INVALID_MESSAGE",
"message": "Failed to parse message: unexpected token at position 15",
"timestamp": "2025-01-15T10:30:00Z"
}
Event Subscription
Event subscriptions are configured at startup via environment variables, not through WebSocket messages. Configure the SUBSCRIPTIONS environment variable to specify which events your strategy receives.
Related Documentation
- Connection Guide - How to connect to the Trading API
- Order Types - Full order schema reference
- Position Types - Full position schema reference
- Event Types - Event type enumerations