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.

OpenAPI Specification

ondo-finance-perps-ws-openapi-original.json Raw ↑
{
    "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