OS Trading Engine
API Reference
WebSocket API
Events

WebSocket Events

All WebSocket messages follow a standard structure with a type field identifying the message type.


Message Structure

All messages have this base structure:

interface WSMessage {
  type: string;
  data?: unknown;
  timestamp?: string;
}

Server → Client Events

connected

Sent immediately after successful authentication.

{
  "type": "connected",
  "data": {
    "agentId": "550e8400-e29b-41d4-a716-446655440000",
    "timestamp": "2025-01-20T10:30:00.000Z"
  }
}
FieldTypeDescription
data.agentIdUUIDConnected agent ID
data.timestampISO 8601Connection time

initial_data

Sent after connected with all current open positions for the agent.

{
  "type": "initial_data",
  "data": {
    "positions": [
      {
        "id": "pos-123",
        "agentId": "550e8400-e29b-41d4-a716-446655440000",
        "walletAddress": "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU",
        "tokenAddress": "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263",
        "tokenSymbol": "BONK",
        "purchasePrice": 0.00000234,
        "purchaseAmount": 1000000,
        "purchasePriceUsd": 0.000234,
        "currentPrice": 0.00000256,
        "currentPriceUsd": 0.000256,
        "positionValueSol": 2.56,
        "positionValueUsd": 256.00,
        "profitLossSol": 0.22,
        "profitLossUsd": 22.00,
        "profitLossPercent": 9.4,
        "priceChangePercent": 9.4,
        "currentStopLossPercentage": 25,
        "peakPrice": 0.00000260,
        "createdAt": "2025-01-20T08:00:00.000Z",
        "updatedAt": "2025-01-20T10:30:00.000Z",
        "purchaseTransactionId": "tx-abc123"
      }
    ],
    "timestamp": "2025-01-20T10:30:00.000Z"
  }
}

Position Fields

FieldTypeDescription
idstringPosition ID
agentIdUUIDAgent ID
walletAddressstringWallet holding position
tokenAddressstringToken mint address
tokenSymbolstringToken ticker
purchasePricenumberBuy price in SOL
purchaseAmountnumberOriginal token amount
remainingAmountnumberTokens remaining after take-profit sales
purchasePriceUsdnumberBuy price in USD
currentPricenumberCurrent price in SOL
currentPriceUsdnumberCurrent price in USD
positionValueSolnumberCurrent value in SOL (remaining tokens)
positionValueUsdnumberCurrent value in USD (remaining tokens)
profitLossSolnumberTotal P/L in SOL (realized + unrealized)
profitLossUsdnumberTotal P/L in USD (realized + unrealized)
profitLossPercentnumberTotal P/L percentage (vs original cost)
priceChangePercentnumberPrice change from entry
currentStopLossPercentagenumberStop loss percentage
peakPricenumberHighest price seen
totalInvestedSolnumberTotal invested (with DCA)
dcaCountnumberNumber of DCA orders
takeProfitLevelsHitnumberNumber of take-profit levels triggered
realizedProfitSolnumberSOL profit from take-profit sales
moonBagActivatedbooleanWhether moon bag is active
moonBagAmountnumberTokens reserved as moon bag
createdAtISO 8601Position created time
updatedAtISO 8601Last update time

Positions in initial_data come pre-enriched with current prices and P/L calculations from the server's price cache.

P/L with Take-Profit: For positions with take-profit enabled, profitLossSol and profitLossUsd combine realized profit (from take-profit sales stored in realizedProfitSol) with unrealized profit on remaining tokens. The profitLossPercent is calculated against the original cost basis (originalCostBasisSol).


position_update

Sent when a position is created, updated, or closed.

Position Created

{
  "type": "position_update",
  "data": {
    "eventType": "position_created",
    "position": {
      "id": "pos-456",
      "agentId": "550e8400-e29b-41d4-a716-446655440000",
      "tokenAddress": "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263",
      "tokenSymbol": "BONK",
      "purchasePrice": 0.00000234,
      "purchaseAmount": 500000,
      ...
    }
  }
}

Position Updated

Sent when position data changes (e.g., DCA order executed, stop loss adjusted):

{
  "type": "position_update",
  "data": {
    "eventType": "position_updated",
    "position": {
      "id": "pos-456",
      "dcaCount": 2,
      "totalInvestedSol": 1.5,
      ...
    }
  }
}

Position Closed

{
  "type": "position_update",
  "data": {
    "eventType": "position_closed",
    "positionId": "pos-456"
  }
}
Event TypeFieldsDescription
position_createdpositionFull position object
position_updatedpositionUpdated position object
position_closedpositionIdID of closed position

price_update

Sent when a single token price changes (legacy, prefer price_update_batch).

{
  "type": "price_update",
  "data": {
    "tokenAddress": "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263",
    "price": 0.00000260,
    "priceUsd": 0.000260,
    "timestamp": "2025-01-20T10:30:05.000Z"
  }
}
FieldTypeDescription
tokenAddressstringToken mint address
pricenumberPrice in SOL
priceUsdnumberPrice in USD

price_update_batch

Sent with multiple price updates at once (more efficient).

{
  "type": "price_update_batch",
  "data": {
    "updates": [
      {
        "tokenAddress": "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263",
        "price": 0.00000260,
        "priceUsd": 0.000260
      },
      {
        "tokenAddress": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
        "price": 0.0067,
        "priceUsd": 1.00
      }
    ],
    "timestamp": "2025-01-20T10:30:05.000Z"
  }
}

Price updates are only sent for tokens where the agent has open positions. This reduces unnecessary network traffic.


ping

Server heartbeat to check connection health. Client must respond with pong.

{
  "type": "ping",
  "timestamp": "2025-01-20T10:30:00.000Z"
}

error

Sent when an error occurs.

{
  "type": "error",
  "data": {
    "message": "Failed to load initial data: Database connection error"
  }
}

Client → Server Events

pong

Response to server ping. Required to keep connection alive.

{
  "type": "pong",
  "timestamp": "2025-01-20T10:30:00.000Z"
}

ping

Client can also send pings (optional). Server will respond with pong.

{
  "type": "ping",
  "timestamp": "2025-01-20T10:30:00.000Z"
}

subscribe

Acknowledge subscription (optional, subscription happens on connection).

{
  "type": "subscribe"
}

Server responds with:

{
  "type": "subscribed",
  "data": {
    "agentId": "550e8400-e29b-41d4-a716-446655440000"
  }
}

TypeScript Types

// Base message
interface WSMessage {
  type: string;
  data?: unknown;
  timestamp?: string;
}
 
// Server messages
interface ConnectedMessage extends WSMessage {
  type: 'connected';
  data: {
    agentId: string;
    timestamp: string;
  };
}
 
interface InitialDataMessage extends WSMessage {
  type: 'initial_data';
  data: {
    positions: EnrichedPosition[];
    timestamp: string;
  };
}
 
interface PositionUpdateMessage extends WSMessage {
  type: 'position_update';
  data: {
    eventType: 'position_created' | 'position_updated' | 'position_closed';
    position?: OpenPosition;
    positionId?: string;
  };
}
 
interface PriceUpdateMessage extends WSMessage {
  type: 'price_update';
  data: {
    tokenAddress: string;
    price: number;
    priceUsd: number;
    timestamp: string;
  };
}
 
interface PriceUpdateBatchMessage extends WSMessage {
  type: 'price_update_batch';
  data: {
    updates: Array<{
      tokenAddress: string;
      price: number;
      priceUsd: number;
    }>;
    timestamp: string;
  };
}
 
interface ErrorMessage extends WSMessage {
  type: 'error';
  data: {
    message: string;
  };
}
 
// Union type
type WebSocketMessage =
  | ConnectedMessage
  | InitialDataMessage
  | PositionUpdateMessage
  | PriceUpdateMessage
  | PriceUpdateBatchMessage
  | ErrorMessage;