{
  "asyncapi": "2.6.0",
  "info": {
    "title": "Bitwyre WebSocket API",
    "version": "0.1.0",
    "description": "Real-time market data and account streams. Two endpoints: a public market feed and a JWT-authenticated private feed."
  },
  "servers": {
    "prod": {
      "url": "wss://ws.bitwyre.com",
      "protocol": "wss",
      "description": "Production"
    },
    "sandbox": {
      "url": "wss://ws-sandbox.bitwyre.com",
      "protocol": "wss",
      "description": "Sandbox"
    }
  },
  "channels": {
    "/ws/v1/market": {
      "description": "Public market data. No authentication. Clients receive order-book updates, public trades, and index prices as JSON frames.",
      "subscribe": {
        "operationId": "subscribeMarket",
        "summary": "Receive market data",
        "message": { "oneOf": [
          { "$ref": "#/components/messages/OrderBookUpdate" },
          { "$ref": "#/components/messages/PublicTrade" },
          { "$ref": "#/components/messages/IndexPriceUpdate" }
        ]}
      }
    },
    "/ws/v1/private": {
      "description": "Private account stream. Requires `Authorization: Bearer <JWT>` on the upgrade request. Messages are routed to the authenticated account_id only.",
      "bindings": {
        "ws": {
          "bindingVersion": "0.1.0",
          "headers": { "type": "object", "properties": { "Authorization": { "type": "string", "description": "Bearer <JWT>" } } }
        }
      },
      "subscribe": {
        "operationId": "subscribePrivate",
        "summary": "Receive private account messages",
        "message": { "oneOf": [
          { "$ref": "#/components/messages/ExecutionReport" },
          { "$ref": "#/components/messages/OrderStatusUpdate" },
          { "$ref": "#/components/messages/BalanceUpdate" }
        ]}
      }
    }
  },
  "components": {
    "messages": {
      "OrderBookUpdate": {
        "name": "OrderBookUpdate",
        "title": "Order book L2 delta",
        "summary": "Top-of-book + up to 20-level depth delta per symbol.",
        "payload": {
          "type": "object",
          "required": ["symbol", "bids", "asks", "timestamp"],
          "properties": {
            "symbol": { "type": "string", "example": "BTC/USDT" },
            "bids": { "type": "array", "items": { "type": "array", "items": { "type": "string" } }, "description": "Array of [price, size] decimal strings" },
            "asks": { "type": "array", "items": { "type": "array", "items": { "type": "string" } } },
            "timestamp": { "type": "integer", "format": "int64" }
          }
        }
      },
      "PublicTrade": {
        "name": "PublicTrade",
        "title": "Public trade print",
        "payload": {
          "type": "object",
          "properties": {
            "symbol": { "type": "string" },
            "price": { "type": "string" },
            "quantity": { "type": "string" },
            "side": { "type": "string", "enum": ["Buy", "Sell"] },
            "timestamp": { "type": "integer", "format": "int64" }
          }
        }
      },
      "IndexPriceUpdate": {
        "name": "IndexPriceUpdate",
        "title": "Aggregated index price across venues",
        "payload": {
          "type": "object",
          "properties": {
            "symbol": { "type": "string" },
            "indexPrice": { "type": "string" },
            "timestamp": { "type": "integer", "format": "int64" }
          }
        }
      },
      "ExecutionReport": {
        "name": "ExecutionReport",
        "title": "Execution / fill report for an order",
        "payload": {
          "type": "object",
          "properties": {
            "accountId": { "type": "integer", "format": "int64" },
            "orderId": { "type": "integer", "format": "int64" },
            "execType": { "type": "string", "enum": ["New", "Trade", "Cancelled", "Rejected"] },
            "lastQty": { "type": "string" },
            "lastPrice": { "type": "string" },
            "feeAmount": { "type": "string" },
            "feeCurrency": { "type": "string" },
            "timestamp": { "type": "integer", "format": "int64" }
          }
        }
      },
      "OrderStatusUpdate": {
        "name": "OrderStatusUpdate",
        "title": "Order state transition",
        "payload": {
          "type": "object",
          "properties": {
            "accountId": { "type": "integer", "format": "int64" },
            "orderId": { "type": "integer", "format": "int64" },
            "status": { "type": "string", "enum": ["New", "PartialFill", "Filled", "Cancelled", "Rejected"] },
            "cumQty": { "type": "string" },
            "leavesQty": { "type": "string" }
          }
        }
      },
      "BalanceUpdate": {
        "name": "BalanceUpdate",
        "title": "Per-account balance change",
        "payload": {
          "type": "object",
          "properties": {
            "accountId": { "type": "integer", "format": "int64" },
            "currency": { "type": "string" },
            "available": { "type": "string" },
            "locked": { "type": "string" },
            "total": { "type": "string" }
          }
        }
      }
    }
  }
}
