Event Reference
Every event name lives in src/core/websocket/event-constants.ts on the server. The client emits
a "request" event and receives one or more "response", "progress", and "error" events in return.
System
| Event | Direction | Payload |
|---|---|---|
connected | server → you | { userId, sid, timestamp } |
ping | you → server | () |
pong | server → you | { timestamp } |
subscribe | you → server | { room: string } |
unsubscribe | you → server | { room: string } |
subscribed | server → you | { room, subscriberCount } |
unsubscribed | server → you | { room } |
user_joined_room | server → room | { userId, room, joinedAt } |
user_left_room | server → room | { userId, room, leftAt } |
Query Engine
The unified query engine streams results over WebSocket for queries that take longer than ~200ms.
| Event | Direction | Payload |
|---|---|---|
query | you → server | { sql, params?, applicationId } |
query_started | server → you | { queryId, estimatedMs } |
query_progress | server → you | { queryId, rowsProcessed, pct } |
query_response | server → you | { queryId, rows, schema } |
query_completed | server → you | { queryId, durationMs, totalRows } |
query_error | server → you | { queryId, code, message } |
Market Data
Sub-second candles, trades, and chart updates.
| Event | Direction | Payload |
|---|---|---|
request_market_data | you → server | { symbol, resolution, venues?, window? } |
market_data_response | server → you | { symbol, candles } |
market_chart_initial_data | server → you | { symbol, series: Candle[] } |
market_chart_live_update | server → you | { symbol, open, high, low, close, volume, timestamp } |
market_data_error | server → you | { code, message } |
Compliance (LedgerBrain)
Long-running address and transaction analysis with progress updates.
| Event | Direction | Payload |
|---|---|---|
address_analysis | you → server | { chain, address, hops? } |
address_analysis_started | server → you | { jobId } |
address_analysis_progress | server → you | { jobId, stage, pct } |
address_analysis_response | server → you | { jobId, riskScore, riskLevel, clusters, signals } |
address_analysis_completed | server → you | { jobId, durationMs } |
address_analysis_error | server → you | { jobId, code, message } |
address_transactions | you → server | { chain, address, limit?, cursor? } |
address_transactions_response | server → you | { chain, address, transactions, nextCursor } |
cross_border_flows | you → server | { corridor, window } |
cross_border_flows_response | server → you | { corridor, flows, totalsUSD } |
Credits
Every credit movement is pushed to your personal room (user:<clerkUserId>) automatically —
no subscription required.
| Event | Direction | Payload |
|---|---|---|
credit_balance_updated | server → you | { newBalance, lifetimeEarned, lifetimeSpent, applicationId } |
credits_deducted | server → you | { amount, newBalance, action, transactionId, timestamp } |
credits_granted | server → you | { amount, newBalance, reason, transactionId, timestamp } |
insufficient_credits | server → you | { required, available, action } |
Chat / AI (LedgerBrain AI)
Streaming natural-language query responses.
| Event | Direction | Payload |
|---|---|---|
chat | you → server | { conversationId, message, context? } |
chat_typing | server → you | { conversationId } |
chat_stop_typing | server → you | { conversationId } |
chat_message | server → you | { conversationId, role, delta, isFinal } |
chat_response | server → you | { conversationId, messageId, tokens, sql? } |
chat_error | server → you | { conversationId, code, message } |
Errors
Standard error envelope across every category:
{
"code": "RATE_LIMITED | UNAUTHORIZED | NOT_FOUND | INTERNAL",
"message": "Human-readable description",
"retryAfter": 30
}
| Event | When |
|---|---|
rate_limit_error | You exceeded per-socket or per-user request throttles. |
validation_error | Your request payload failed schema validation. |