Ondo Perps WebSocket API
Real-time WebSocket API for Ondo Perps: market data, order/position/balance/funding updates and a dead-man-switch, across 22 subscription channels.
Real-time WebSocket API for Ondo Perps: market data, order/position/balance/funding updates and a dead-man-switch, across 22 subscription channels.
{
"openapi": "3.0.3",
"info": {
"title": "Ondo Perps WebSocket API",
"version": "1.0",
"description": "WebSocket API for Ondo Perps: real-time market data, order updates, positions, balance, funding, and more.\n\n## Connection\n\nConnect via `wss://api.ondoperps.xyz/ws`. The server enforces a 32 KB max message size and a rate limit of 25 requests/second (burst 50).\n\n## Authentication\n\nPublic channels (market data) require no authentication. Private channels (orders, fills, positions, balance, etc.) require a `login` message first.\n\n### JWT Login\n```json\n{\"op\": \"login\", \"args\": {\"token\": \"<JWT>\"}}\n```\n\n### API Key Login\n```json\n{\"op\": \"login\", \"args\": {\"key\": \"<api_key_id>\", \"time\": \"<unix_ms>\", \"sign\": \"<hex_hmac>\"}}\n```\n\nSignature: `HMAC-SHA256(api_secret, \"ondo_perps_ws_login\" + time)`\n\n## Heartbeat\n\nSend `{\"op\": \"ping\"}` periodically. The server responds with `{\"type\": \"pong\"}`. Connections idle for 180 seconds are closed.\n\n## Message Format\n\n### Client → Server\nAll client messages use the `op` field: `ping`, `login`, `subscribe`, `unsubscribe`, `sendMessage`.\n\n### Server → Client\nAll server messages use the `type` field: `pong`, `loggedIn`, `subscribed`, `unsubscribed`, `update`, `error`.\nChannel data updates arrive as `{\"type\": \"update\", \"channel\": \"<name>\", \"data\": <payload>}`."
},
"servers": [
{ "url": "wss://api.ondoperps.xyz", "description": "Production" }
],
"paths": {
"/ws/topOfBooksPerps": {
"post": {
"summary": "Subscribe: Perps Top of Book",
"operationId": "subscribe_topOfBooksPerps",
"description": "Subscribe to the `topOfBooksPerps` channel.\n\nOptional `markets` to filter; omit for all markets.",
"tags": ["Public Channels"],
"requestBody": {
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/WebSocketRequest" },
"example": { "op": "subscribe", "channel": "topOfBooksPerps" }
}
}
},
"responses": {
"200": {
"description": "Channel update for `topOfBooksPerps`",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"type": { "type": "string", "enum": ["update"] },
"channel": {
"type": "string",
"enum": ["topOfBooksPerps"]
},
"data": {
"type": "array",
"items": { "$ref": "#/components/schemas/BookSnapshot" }
}
}
},
"example": {
"type": "update",
"channel": "topOfBooksPerps",
"data": [
{
"market": "AAPL-USD.P",
"time": "2025-03-05T14:30:00Z",
"asks": [{ "price": "227.60", "size": "80.0" }],
"bids": [{ "price": "227.40", "size": "100.0" }]
}
]
}
}
}
}
}
}
},
"/ws/depthBooksPerps": {
"post": {
"summary": "Subscribe: Perps Depth Book",
"operationId": "subscribe_depthBooksPerps",
"description": "Subscribe to the `depthBooksPerps` channel.\n\nOptional `markets`, `depthLevels` (price grouping), and `limit` (max levels).",
"tags": ["Public Channels"],
"requestBody": {
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/WebSocketRequest" },
"example": { "op": "subscribe", "channel": "depthBooksPerps" }
}
}
},
"responses": {
"200": {
"description": "Channel update for `depthBooksPerps`",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"type": { "type": "string", "enum": ["update"] },
"channel": {
"type": "string",
"enum": ["depthBooksPerps"]
},
"data": {
"type": "array",
"items": { "$ref": "#/components/schemas/BookSnapshot" }
}
}
}
}
}
}
}
}
},
"/ws/tradesPerps": {
"post": {
"summary": "Subscribe: Perps Trades",
"operationId": "subscribe_tradesPerps",
"description": "Subscribe to the `tradesPerps` channel.\n\nOptional `markets` and `numPastTrades` (number of historical trades on subscribe).",
"tags": ["Public Channels"],
"requestBody": {
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/WebSocketRequest" },
"example": { "op": "subscribe", "channel": "tradesPerps" }
}
}
},
"responses": {
"200": {
"description": "Channel update for `tradesPerps`",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"type": { "type": "string", "enum": ["update"] },
"channel": { "type": "string", "enum": ["tradesPerps"] },
"data": {
"type": "array",
"items": { "$ref": "#/components/schemas/Trade" }
}
}
},
"example": {
"type": "update",
"channel": "tradesPerps",
"data": [
{
"market": "AAPL-USD.P",
"price": "227.50",
"size": "5.00",
"cost": "1137.50",
"aggressor_side": "buy",
"time": "2025-03-05T14:30:00Z",
"id": "70a37d8f972f2494837f9dba8364cbb4"
}
]
}
}
}
}
}
}
},
"/ws/fundingRatesPerps": {
"post": {
"summary": "Subscribe: Perps Funding Rates",
"operationId": "subscribe_fundingRatesPerps",
"description": "Subscribe to the `fundingRatesPerps` channel.\n\nOptional `markets` to filter.",
"tags": ["Public Channels"],
"requestBody": {
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/WebSocketRequest" },
"example": { "op": "subscribe", "channel": "fundingRatesPerps" }
}
}
},
"responses": {
"200": {
"description": "Channel update for `fundingRatesPerps`",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"type": { "type": "string", "enum": ["update"] },
"channel": {
"type": "string",
"enum": ["fundingRatesPerps"]
},
"data": {
"type": "array",
"items": { "$ref": "#/components/schemas/FundingRate" }
}
}
}
}
}
}
}
}
},
"/ws/markPricesPerps": {
"post": {
"summary": "Subscribe: Perps Mark Prices",
"operationId": "subscribe_markPricesPerps",
"description": "Subscribe to the `markPricesPerps` channel.\n\nOptional `markets` to filter.",
"tags": ["Public Channels"],
"requestBody": {
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/WebSocketRequest" },
"example": { "op": "subscribe", "channel": "markPricesPerps" }
}
}
},
"responses": {
"200": {
"description": "Channel update for `markPricesPerps`",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"type": { "type": "string", "enum": ["update"] },
"channel": {
"type": "string",
"enum": ["markPricesPerps"]
},
"data": {
"type": "array",
"items": { "$ref": "#/components/schemas/MarkPrice" }
}
}
},
"example": {
"type": "update",
"channel": "markPricesPerps",
"data": [{ "market": "AAPL-USD.P", "markPrice": "227.50" }]
}
}
}
}
}
}
},
"/ws/liquidationAnnouncementsPerps": {
"post": {
"summary": "Subscribe: Perps Liquidation Announcements",
"operationId": "subscribe_liquidationAnnouncementsPerps",
"description": "Subscribe to the `liquidationAnnouncementsPerps` channel.",
"tags": ["Public Channels"],
"requestBody": {
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/WebSocketRequest" },
"example": {
"op": "subscribe",
"channel": "liquidationAnnouncementsPerps"
}
}
}
},
"responses": {
"200": {
"description": "Channel update for `liquidationAnnouncementsPerps`",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"type": { "type": "string", "enum": ["update"] },
"channel": {
"type": "string",
"enum": ["liquidationAnnouncementsPerps"]
},
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/LiquidationAnnouncement"
}
}
}
}
}
}
}
}
}
},
"/ws/kLinePerps": {
"post": {
"summary": "Subscribe: Perps Kline / Candlesticks",
"operationId": "subscribe_kLinePerps",
"description": "Subscribe to the `kLinePerps` channel.\n\n**Required**: exactly one `markets` entry and a `resolution`.\n\nValid resolutions: `1`, `5`, `15`, `1H`, `4H`, `1D`, `1W`.",
"tags": ["Public Channels"],
"requestBody": {
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/WebSocketRequest" },
"example": { "op": "subscribe", "channel": "kLinePerps" }
}
}
},
"responses": {
"200": {
"description": "Channel update for `kLinePerps`",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"type": { "type": "string", "enum": ["update"] },
"channel": { "type": "string", "enum": ["kLinePerps"] },
"data": { "$ref": "#/components/schemas/Kline" }
}
},
"example": {
"type": "update",
"channel": "kLinePerps",
"data": {
"m": "AAPL-USD.P",
"t": 1709648400,
"s": 1709648340,
"e": 1709648400,
"o": 226.8,
"h": 228.1,
"l": 226.5,
"c": 227.5,
"v": 12345.67,
"x": false
}
}
}
}
}
}
}
},
"/ws/ordersPerps": {
"post": {
"summary": "Subscribe: Perps Orders",
"operationId": "subscribe_ordersPerps",
"description": "Subscribe to the `ordersPerps` channel. Requires authentication (login first).\n\nOptional `markets` to filter.",
"tags": ["Private Channels"],
"requestBody": {
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/WebSocketRequest" },
"example": { "op": "subscribe", "channel": "ordersPerps" }
}
}
},
"responses": {
"200": {
"description": "Channel update for `ordersPerps`",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"type": { "type": "string", "enum": ["update"] },
"channel": { "type": "string", "enum": ["ordersPerps"] },
"data": {
"type": "array",
"items": { "$ref": "#/components/schemas/Order" }
}
}
},
"example": {
"type": "update",
"channel": "ordersPerps",
"data": [
{
"orderId": "197ec08e001658690721be129e7fa595",
"side": "buy",
"price": "227.50",
"size": "10.00",
"market": "AAPL-USD.P",
"filledSize": "0.00",
"filledCost": "0.00",
"fee": "0.00",
"status": "open",
"createdAt": "2025-03-05T14:30:00Z",
"type": "limit",
"timeInForce": "GTC"
}
]
}
}
}
}
}
}
},
"/ws/fillsPerps": {
"post": {
"summary": "Subscribe: Perps Fills",
"operationId": "subscribe_fillsPerps",
"description": "Subscribe to the `fillsPerps` channel. Requires authentication (login first).\n\nOptional `markets` to filter.",
"tags": ["Private Channels"],
"requestBody": {
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/WebSocketRequest" },
"example": { "op": "subscribe", "channel": "fillsPerps" }
}
}
},
"responses": {
"200": {
"description": "Channel update for `fillsPerps`",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"type": { "type": "string", "enum": ["update"] },
"channel": { "type": "string", "enum": ["fillsPerps"] },
"data": {
"type": "array",
"items": { "$ref": "#/components/schemas/Fill" }
}
}
}
}
}
}
}
}
},
"/ws/positionsPerps": {
"post": {
"summary": "Subscribe: Perps Positions",
"operationId": "subscribe_positionsPerps",
"description": "Subscribe to the `positionsPerps` channel. Requires authentication (login first).",
"tags": ["Private Channels"],
"requestBody": {
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/WebSocketRequest" },
"example": { "op": "subscribe", "channel": "positionsPerps" }
}
}
},
"responses": {
"200": {
"description": "Channel update for `positionsPerps`",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"type": { "type": "string", "enum": ["update"] },
"channel": { "type": "string", "enum": ["positionsPerps"] },
"data": {
"type": "array",
"items": { "$ref": "#/components/schemas/Position" }
}
}
},
"example": {
"type": "update",
"channel": "positionsPerps",
"data": [
{
"market": "AAPL-USD.P",
"direction": "long",
"netQuantity": "10.00",
"averageEntryPrice": "225.00",
"usedMargin": "1125.00",
"unrealizedPnl": "25.00",
"markPrice": "227.50",
"liquidationPrice": "180.00",
"bankruptcyPrice": "170.00",
"maintenanceMargin": "112.50",
"notionalValue": "2275.00",
"leverage": "2.0",
"netFundingSinceNeutral": "-1.23",
"returnOnEquity": "0.022"
}
]
}
}
}
}
}
}
},
"/ws/balancePerps": {
"post": {
"summary": "Subscribe: Perps Balance",
"operationId": "subscribe_balancePerps",
"description": "Subscribe to the `balancePerps` channel. Requires authentication (login first).",
"tags": ["Private Channels"],
"requestBody": {
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/WebSocketRequest" },
"example": { "op": "subscribe", "channel": "balancePerps" }
}
}
},
"responses": {
"200": {
"description": "Channel update for `balancePerps`",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"type": { "type": "string", "enum": ["update"] },
"channel": { "type": "string", "enum": ["balancePerps"] },
"data": { "$ref": "#/components/schemas/Balance" }
}
},
"example": {
"type": "update",
"channel": "balancePerps",
"data": {
"walletBalance": "5000.00",
"realizedPnl": "250.00",
"unrealizedPnl": "-50.00",
"marginBalance": "4950.00",
"usedMargin": "1125.00"
}
}
}
}
}
}
}
},
"/ws/liquidationPerps": {
"post": {
"summary": "Subscribe: Perps Liquidation",
"operationId": "subscribe_liquidationPerps",
"description": "Subscribe to the `liquidationPerps` channel. Requires authentication (login first).",
"tags": ["Private Channels"],
"requestBody": {
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/WebSocketRequest" },
"example": { "op": "subscribe", "channel": "liquidationPerps" }
}
}
},
"responses": {
"200": {
"description": "Channel update for `liquidationPerps`",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"type": { "type": "string", "enum": ["update"] },
"channel": {
"type": "string",
"enum": ["liquidationPerps"]
},
"data": { "$ref": "#/components/schemas/LiquidationEvent" }
}
}
}
}
}
}
}
},
"/ws/marginTransfersPerps": {
"post": {
"summary": "Subscribe: Perps Margin Transfers",
"operationId": "subscribe_marginTransfersPerps",
"description": "Subscribe to the `marginTransfersPerps` channel. Requires authentication (login first).",
"tags": ["Private Channels"],
"requestBody": {
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/WebSocketRequest" },
"example": {
"op": "subscribe",
"channel": "marginTransfersPerps"
}
}
}
},
"responses": {
"200": {
"description": "Channel update for `marginTransfersPerps`",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"type": { "type": "string", "enum": ["update"] },
"channel": {
"type": "string",
"enum": ["marginTransfersPerps"]
},
"data": { "$ref": "#/components/schemas/MarginTransfer" }
}
}
}
}
}
}
}
},
"/ws/ordersSummariesPerps": {
"post": {
"summary": "Subscribe: Perps Order Summaries",
"operationId": "subscribe_ordersSummariesPerps",
"description": "Subscribe to the `ordersSummariesPerps` channel. Requires authentication (login first).",
"tags": ["Private Channels"],
"requestBody": {
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/WebSocketRequest" },
"example": {
"op": "subscribe",
"channel": "ordersSummariesPerps"
}
}
}
},
"responses": {
"200": {
"description": "Channel update for `ordersSummariesPerps`",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"type": { "type": "string", "enum": ["update"] },
"channel": {
"type": "string",
"enum": ["ordersSummariesPerps"]
},
"data": {
"type": "array",
"items": { "$ref": "#/components/schemas/OrdersSummary" }
}
}
}
}
}
}
}
}
},
"/ws/fundingPaymentsPerps": {
"post": {
"summary": "Subscribe: Perps Funding Payments",
"operationId": "subscribe_fundingPaymentsPerps",
"description": "Subscribe to the `fundingPaymentsPerps` channel. Requires authentication (login first).",
"tags": ["Private Channels"],
"requestBody": {
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/WebSocketRequest" },
"example": {
"op": "subscribe",
"channel": "fundingPaymentsPerps"
}
}
}
},
"responses": {
"200": {
"description": "Channel update for `fundingPaymentsPerps`",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"type": { "type": "string", "enum": ["update"] },
"channel": {
"type": "string",
"enum": ["fundingPaymentsPerps"]
},
"data": { "$ref": "#/components/schemas/FundingPayment" }
}
}
}
}
}
}
}
},
"/ws/cancelAllOrdersAfterPerps": {
"post": {
"summary": "Subscribe: Perps Dead Man's Switch",
"operationId": "subscribe_cancelAllOrdersAfterPerps",
"description": "Subscribe to the `cancelAllOrdersAfterPerps` channel. Requires authentication (login first).\n\n**Required**: `timeout_seconds` (the dead man's switch duration in seconds).",
"tags": ["Private Channels"],
"requestBody": {
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/WebSocketRequest" },
"example": {
"op": "subscribe",
"channel": "cancelAllOrdersAfterPerps"
}
}
}
},
"responses": {
"200": {
"description": "Channel update for `cancelAllOrdersAfterPerps`",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"type": { "type": "string", "enum": ["update"] },
"channel": {
"type": "string",
"enum": ["cancelAllOrdersAfterPerps"]
},
"data": { "type": "object" }
}
}
}
}
}
}
}
},
"/ws/deposits": {
"post": {
"summary": "Subscribe: Deposits",
"operationId": "subscribe_deposits",
"description": "Subscribe to the `deposits` channel. Requires authentication (login first).",
"tags": ["Private Channels"],
"requestBody": {
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/WebSocketRequest" },
"example": { "op": "subscribe", "channel": "deposits" }
}
}
},
"responses": {
"200": {
"description": "Channel update for `deposits`",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"type": { "type": "string", "enum": ["update"] },
"channel": { "type": "string", "enum": ["deposits"] },
"data": { "$ref": "#/components/schemas/Deposit" }
}
}
}
}
}
}
}
},
"/ws/withdrawals": {
"post": {
"summary": "Subscribe: Withdrawals",
"operationId": "subscribe_withdrawals",
"description": "Subscribe to the `withdrawals` channel. Requires authentication (login first).",
"tags": ["Private Channels"],
"requestBody": {
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/WebSocketRequest" },
"example": { "op": "subscribe", "channel": "withdrawals" }
}
}
},
"responses": {
"200": {
"description": "Channel update for `withdrawals`",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"type": { "type": "string", "enum": ["update"] },
"channel": { "type": "string", "enum": ["withdrawals"] },
"data": { "$ref": "#/components/schemas/Withdrawal" }
}
}
}
}
}
}
}
},
"/ws/chat": {
"post": {
"summary": "Subscribe: Chat",
"operationId": "subscribe_chat",
"description": "Subscribe to the `chat` channel. Requires authentication (login first).",
"tags": ["Chat"],
"requestBody": {
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/WebSocketRequest" },
"example": { "op": "subscribe", "channel": "chat" }
}
}
},
"responses": {
"200": {
"description": "Channel update for `chat`",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"type": { "type": "string", "enum": ["update"] },
"channel": { "type": "string", "enum": ["chat"] },
"data": { "$ref": "#/components/schemas/ChatMessage" }
}
}
}
}
}
}
}
},
"/ws": {
"get": {
"summary": "Connect",
"operationId": "wsConnect",
"description": "Establish a WebSocket connection. After connecting, send JSON messages to interact with the API.",
"tags": ["Connection"],
"responses": {
"101": {
"description": "Switching Protocols - WebSocket connection established"
}
}
},
"post": {
"summary": "Ping",
"operationId": "wsPing",
"description": "Send `{\"op\": \"ping\"}` to keep the connection alive. The server responds with `{\"type\": \"pong\"}`.",
"tags": ["Connection"],
"requestBody": {
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/WebSocketRequest" },
"example": { "op": "ping" }
}
}
},
"responses": {
"200": {
"description": "Pong response",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"type": { "type": "string", "enum": ["pong"] }
}
},
"example": { "type": "pong" }
}
}
}
}
}
},
"/ws/login": {
"post": {
"summary": "Login",
"operationId": "wsLogin",
"de
# --- truncated at 32 KB (56 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/ondo-finance/refs/heads/main/openapi/ondo-finance-perps-ws-openapi-original.json