{
  "openapi": "3.1.0",
  "info": {
    "title": "JTX Markets API",
    "version": "1.0.0",
    "description": "REST and WebSocket API for JTX Markets — the 24/7 multi-asset perpetuals exchange. Covers 56 REST endpoints across crypto, forex, equity, commodity and index perpetuals plus a WebSocket broadcast surface with 18 typed event variants.\n\n## Authentication\n\nTwo authentication tiers:\n\n- **Per-trader HMAC** — order, account and position routes are signed with the account's API key + secret using HMAC-SHA384. The signature covers the request method, path-without-query, nonce, and body. Per-account API keys are provisioned at signup and rotatable from the account dashboard.\n- **Admin token** — every `/v1/admin/*` route requires the `admin-token` request header. Set to the value of the engine's `ADMIN_TOKEN` env var.\n\nPublic market data routes (`/v1/market/*`, `/v1/funding/*`, `/v1/risk/*`, `/health`, `/metrics`, `/v1/insurance`, `/v1/maintenance-banner`, `/v1/ws/stats`) require no authentication.\n\n## WebSocket\n\nConnect to `wss://engine.jtxmarkets.com/ws`. Subscribe via JSON text frame:\n\n```json\n{ \"action\": \"subscribe\", \"channel\": \"orderbook.BTC-PERP\" }\n```\n\nChannels: `orderbook.{symbol}`, `trades.{symbol}`, `ticker.{symbol}`, `funding.{symbol}`, `market_status.{symbol}`, `circuit_breaker.{symbol}`, `private.{client_id}`.\n\nEvent variants (`type` field): `orderbook`, `trade`, `ticker`, `funding_rate`, `market_status`, `circuit_breaker`, `order_ack`, `fill`, `account_update`, `position_update`, `liquidated`, `funding_payment`, `margin_warning`, `subscribed`, `unsubscribed`, `pong`, `error`, `lagged`.\n\nFull WebSocket event catalogue is in the engine's `SPEC_08_API_CONTRACT.md` (will be published as AsyncAPI in v0.2 of these docs).",
    "contact": {
      "name": "JTX Markets API Support",
      "url":  "https://jtxmarkets.com/faq"
    }
  },
  "servers": [
    { "url": "https://engine.jtxmarkets.com", "description": "Production" },
    { "url": "http://localhost:3000",       "description": "Local dev (engine direct)" }
  ],
  "security": [],
  "tags": [
    { "name": "Health & Observability", "description": "Service health, metrics, WebSocket connection stats." },
    { "name": "Market Data",            "description": "Public market data — no auth required." },
    { "name": "Maintenance Banner",     "description": "Public read of the platform-wide notice; admin write." },
    { "name": "Accounts",               "description": "Per-trader account management — balance, deposits, withdrawals, history." },
    { "name": "Orders",                 "description": "Order lifecycle — submit, cancel, modify, list." },
    { "name": "Algos",                  "description": "TWAP and other algorithmic order strategies." },
    { "name": "OCO",                    "description": "One-Cancels-Other order pairs." },
    { "name": "Bracket",                "description": "Bracket orders — entry plus take-profit and stop-loss legs." },
    { "name": "Positions",              "description": "Per-trader position queries and bulk-close." },
    { "name": "Insurance",              "description": "Insurance fund balance." },
    { "name": "Risk",                   "description": "Halts, margin tiers, swap rates." },
    { "name": "Admin",                  "description": "Admin-token-gated operations." },
    { "name": "Internal",               "description": "Aggregator / book-seeder / relay-proxy endpoints (trust-boundary only)." }
  ],
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in":   "header",
        "name": "X-API-Key",
        "description": "Per-account API key. The request also requires `X-Signature`, `X-Nonce`, and (for POST/PUT/PATCH) `Content-Type: application/json`. Signature is HMAC-SHA384(secret, method + path + nonce + body) hex-encoded."
      },
      "AdminToken": {
        "type": "apiKey",
        "in":   "header",
        "name": "admin-token",
        "description": "Admin token from the engine's ADMIN_TOKEN env var. Required for every `/v1/admin/*` route."
      }
    },
    "schemas": {
      "DecimalString": {
        "type":        "string",
        "description": "Fixed-precision decimal as a string to avoid float rounding. Examples: \"69423.50\", \"0.001\".",
        "example":     "69423.50"
      },
      "Uuid": {
        "type":   "string",
        "format": "uuid",
        "example":"550e8400-e29b-41d4-a716-446655440000"
      },
      "ErrorResp": {
        "type": "object",
        "properties": {
          "error": { "type": "string", "description": "Human-readable error message." }
        },
        "required": ["error"]
      },
      "AccountResp": {
        "type": "object",
        "properties": {
          "client_id":      { "$ref": "#/components/schemas/Uuid" },
          "balance":        { "$ref": "#/components/schemas/DecimalString" },
          "available":      { "$ref": "#/components/schemas/DecimalString" },
          "locked_margin":  { "$ref": "#/components/schemas/DecimalString" },
          "unrealized_pnl": { "$ref": "#/components/schemas/DecimalString" },
          "realized_pnl":   { "$ref": "#/components/schemas/DecimalString" }
        }
      },
      "AccountDetail": {
        "type": "object",
        "properties": {
          "client_id":      { "$ref": "#/components/schemas/Uuid" },
          "balance":        { "$ref": "#/components/schemas/DecimalString" },
          "available":      { "$ref": "#/components/schemas/DecimalString" },
          "locked_margin":  { "$ref": "#/components/schemas/DecimalString" },
          "equity":         { "$ref": "#/components/schemas/DecimalString" },
          "unrealized_pnl": { "$ref": "#/components/schemas/DecimalString" },
          "realized_pnl":   { "$ref": "#/components/schemas/DecimalString" },
          "positions":      { "type": "array", "items": { "$ref": "#/components/schemas/PositionResp" } },
          "open_orders":    { "type": "array", "items": { "$ref": "#/components/schemas/OrderResp" } },
          "recent_fills":   { "type": "array", "items": { "type": "object", "additionalProperties": true } }
        }
      },
      "PositionResp": {
        "type": "object",
        "properties": {
          "client_id":         { "$ref": "#/components/schemas/Uuid" },
          "symbol":            { "type": "string", "example": "BTC-PERP" },
          "side":              { "type": "string", "enum": ["long", "short", "flat"] },
          "size":              { "$ref": "#/components/schemas/DecimalString" },
          "entry_price":       { "$ref": "#/components/schemas/DecimalString" },
          "mark_price":        { "$ref": "#/components/schemas/DecimalString" },
          "unrealized_pnl":    { "$ref": "#/components/schemas/DecimalString" },
          "realized_pnl":      { "$ref": "#/components/schemas/DecimalString" },
          "liquidation_price": { "$ref": "#/components/schemas/DecimalString" },
          "bankruptcy_price":  { "$ref": "#/components/schemas/DecimalString" },
          "allocated_margin":  { "$ref": "#/components/schemas/DecimalString" },
          "leverage":          { "type": "integer", "example": 10 }
        }
      },
      "OrderReq": {
        "type": "object",
        "required": ["client_id", "symbol", "side", "order_type", "quantity", "tif"],
        "properties": {
          "client_id":     { "$ref": "#/components/schemas/Uuid" },
          "symbol":        { "type": "string", "example": "BTC-PERP" },
          "side":          { "type": "string", "enum": ["buy", "sell"] },
          "order_type":    { "type": "string", "enum": ["limit", "market", "stoplimit", "stopmarket", "trailingstopmarket"] },
          "price":         { "$ref": "#/components/schemas/DecimalString", "description": "Required for limit / stoplimit." },
          "trigger_price": { "$ref": "#/components/schemas/DecimalString", "description": "Required for stoplimit / stopmarket." },
          "trail_amount":  { "$ref": "#/components/schemas/DecimalString", "description": "Required for trailingstopmarket." },
          "quantity":      { "$ref": "#/components/schemas/DecimalString" },
          "tif":           { "type": "string", "enum": ["gtc", "ioc", "fok", "gtx"] },
          "reduce_only":   { "type": "boolean", "default": false },
          "post_only":     { "type": "boolean", "default": false },
          "margin_mode":   { "type": "string", "enum": ["cross", "isolated"], "default": "cross" },
          "leverage":      { "type": "integer", "example": 10 },
          "stp_mode":      { "type": "string", "enum": ["cancel_taker", "cancel_maker", "cancel_both"] }
        }
      },
      "OrderResp": {
        "type": "object",
        "properties": {
          "order_id":           { "$ref": "#/components/schemas/Uuid" },
          "client_id":          { "$ref": "#/components/schemas/Uuid" },
          "symbol":             { "type": "string" },
          "side":               { "type": "string", "enum": ["buy", "sell"] },
          "order_type":         { "type": "string" },
          "price":              { "$ref": "#/components/schemas/DecimalString" },
          "quantity":           { "$ref": "#/components/schemas/DecimalString" },
          "filled_quantity":    { "$ref": "#/components/schemas/DecimalString" },
          "remaining_quantity": { "$ref": "#/components/schemas/DecimalString" },
          "status":             { "type": "string", "enum": ["New", "PartiallyFilled", "Filled", "Cancelled", "Rejected"] },
          "timestamp":          { "type": "integer", "description": "ns since epoch." },
          "trades":             { "type": "array", "items": { "type": "object", "additionalProperties": true } }
        }
      },
      "DepthResp": {
        "type": "object",
        "properties": {
          "symbol": { "type": "string" },
          "bids":   { "type": "array", "items": { "type": "array", "items": { "type": "string" }, "minItems": 2, "maxItems": 2 } },
          "asks":   { "type": "array", "items": { "type": "array", "items": { "type": "string" }, "minItems": 2, "maxItems": 2 } }
        }
      },
      "TickerResp": {
        "type": "object",
        "properties": {
          "symbol":                 { "type": "string" },
          "best_bid":               { "type": ["string", "null"] },
          "best_ask":               { "type": ["string", "null"] },
          "mark_price":             { "type": ["string", "null"] },
          "index_price":            { "type": ["string", "null"] },
          "funding_rate":           { "type": ["string", "null"] },
          "predicted_funding_rate": { "type": ["string", "null"] },
          "next_funding":           { "type": ["integer", "null"] }
        }
      }
    },
    "parameters": {
      "SymbolPath": {
        "name": "symbol", "in": "path", "required": true,
        "description": "Symbol identifier (e.g. BTC-PERP, EURUSD, TSLA-PERP).",
        "schema": { "type": "string" }
      },
      "ClientIdPath": {
        "name": "client_id", "in": "path", "required": true,
        "description": "Account UUID.",
        "schema": { "$ref": "#/components/schemas/Uuid" }
      },
      "AccountIdPath": {
        "name": "id", "in": "path", "required": true,
        "description": "Account UUID.",
        "schema": { "$ref": "#/components/schemas/Uuid" }
      },
      "OrderIdPath": {
        "name": "id", "in": "path", "required": true,
        "description": "Order / algo / OCO / bracket UUID.",
        "schema": { "$ref": "#/components/schemas/Uuid" }
      },
      "LimitQuery": {
        "name": "limit", "in": "query", "required": false,
        "description": "Maximum rows to return.",
        "schema": { "type": "integer", "default": 200, "maximum": 1000 }
      }
    },
    "responses": {
      "BadRequest":   { "description": "Validation error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResp" } } } },
      "Unauthorized": { "description": "Missing or invalid authentication.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResp" } } } },
      "Forbidden":    { "description": "Authenticated but not authorised.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResp" } } } },
      "NotFound":     { "description": "Resource not found.",       "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResp" } } } },
      "Conflict":     { "description": "State conflict (duplicate, already exists).", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResp" } } } }
    }
  },
  "paths": {
    "/health":  { "get": { "tags": ["Health & Observability"], "summary": "Service health check", "description": "Liveness probe. Returns `ok` plus the engine build version.", "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "status": { "type": "string", "example": "ok" }, "engine": { "type": "string", "example": "perp-engine v0.1.0" } } } } } } } } },
    "/metrics": { "get": { "tags": ["Health & Observability"], "summary": "Prometheus metrics", "description": "Prometheus exposition format — scrape with any compatible monitor.", "responses": { "200": { "description": "Text", "content": { "text/plain": { "schema": { "type": "string" } } } } } } },
    "/v1/ws/stats": { "get": { "tags": ["Health & Observability"], "summary": "WebSocket connection statistics", "description": "Current WebSocket subscriber + broadcast counts.", "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "ws_connections": { "type": "integer" }, "ws_subscribers": { "type": "integer" }, "broadcast_subs": { "type": "integer" } } } } } } } } },

    "/v1/market/symbols": {
      "get": { "tags": ["Market Data"], "summary": "List all tradable symbols", "description": "Returns metadata for every symbol the engine carries — symbol, asset class, base/quote, tick size, contract size, status.", "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "symbols": { "type": "array", "items": { "type": "object", "additionalProperties": true } } } } } } } } }
    },
    "/v1/market/{symbol}/depth": {
      "parameters": [{ "$ref": "#/components/parameters/SymbolPath" }],
      "get": { "tags": ["Market Data"], "summary": "Order book depth", "description": "Top-N bid / ask levels from the order book.", "parameters": [{ "name": "levels", "in": "query", "schema": { "type": "integer", "default": 20, "maximum": 100 }, "description": "Levels per side." }], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DepthResp" } } } } } }
    },
    "/v1/market/{symbol}/ticker": {
      "parameters": [{ "$ref": "#/components/parameters/SymbolPath" }],
      "get": { "tags": ["Market Data"], "summary": "Symbol ticker", "description": "Best bid / ask / mark / index / funding rate / next funding timestamp for one symbol.", "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TickerResp" } } } } } }
    },
    "/v1/market/{symbol}/status": {
      "parameters": [{ "$ref": "#/components/parameters/SymbolPath" }],
      "get": { "tags": ["Market Data"], "summary": "Market open / closed status", "description": "Whether the market is currently open or closed and (for time-bounded markets like forex) the next status change timestamp.", "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "symbol": { "type": "string" }, "status": { "type": "string", "enum": ["open", "closed", "unknown"] }, "next_event_at": { "type": ["integer", "null"] } } } } } } } }
    },
    "/v1/market/{symbol}/trades": {
      "parameters": [{ "$ref": "#/components/parameters/SymbolPath" }, { "$ref": "#/components/parameters/LimitQuery" }],
      "get": { "tags": ["Market Data"], "summary": "Recent trades (public)", "description": "Public trade prints for one symbol.", "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "trades": { "type": "array", "items": { "type": "object", "additionalProperties": true } } } } } } } } }
    },
    "/v1/market/{symbol}/klines": {
      "parameters": [{ "$ref": "#/components/parameters/SymbolPath" }],
      "get": { "tags": ["Market Data"], "summary": "OHLCV candles", "description": "Historical candles for charting.", "parameters": [{ "name": "interval", "in": "query", "schema": { "type": "string", "default": "1m" }, "description": "Candle interval (1m, 5m, 15m, 1h, 1d)." }, { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 500, "maximum": 1500 } }], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "interval": { "type": "string" }, "klines": { "type": "array", "items": { "type": "array", "items": { "type": "number" }, "minItems": 6, "maxItems": 6, "description": "[openTime, open, high, low, close, volume]" } } } } } } } } }
    },
    "/v1/funding/{symbol}": {
      "parameters": [{ "$ref": "#/components/parameters/SymbolPath" }],
      "get": { "tags": ["Market Data"], "summary": "Funding snapshot", "description": "Current funding rate, premium index, interest rate component, and next settlement.", "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "symbol": { "type": "string" }, "rate": { "$ref": "#/components/schemas/DecimalString" }, "premium_index": { "$ref": "#/components/schemas/DecimalString" }, "interest_rate": { "$ref": "#/components/schemas/DecimalString" }, "timestamp_ns": { "type": "integer" }, "next_settle": { "type": "integer" } } } } } } } }
    },

    "/v1/maintenance-banner": {
      "get": { "tags": ["Maintenance Banner"], "summary": "Get the current banner", "description": "Returns the platform-wide notice. `message` is null when no banner is set.", "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": ["string", "null"] }, "level": { "type": "string", "enum": ["info", "warn", "error"] }, "updated_at": { "type": "string", "format": "date-time" } } } } } } } }
    },
    "/v1/admin/maintenance-banner": {
      "put": { "tags": ["Admin"], "summary": "Set the maintenance banner", "security": [{ "AdminToken": [] }], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": ["string", "null"] }, "level": { "type": "string", "enum": ["info", "warn", "error"] } } } } } }, "responses": { "200": { "description": "Updated", "content": { "application/json": { "schema": { "type": "object", "properties": { "ok": { "type": "boolean" }, "updated_at": { "type": "string", "format": "date-time" } } } } } } } }
    },

    "/v1/accounts": {
      "get":  { "tags": ["Accounts"], "summary": "List all accounts", "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "accounts": { "type": "array", "items": { "allOf": [{ "$ref": "#/components/schemas/AccountResp" }, { "type": "object", "properties": { "open_positions": { "type": "integer" } } }] } }, "count": { "type": "integer" } } } } } } } },
      "post": { "tags": ["Accounts"], "summary": "Create an account", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["balance"], "properties": { "balance": { "$ref": "#/components/schemas/DecimalString" } } } } } }, "responses": { "200": { "description": "Created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AccountResp" } } } } } }
    },
    "/v1/accounts/{id}": {
      "parameters": [{ "$ref": "#/components/parameters/AccountIdPath" }],
      "get": { "tags": ["Accounts"], "summary": "Get account", "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AccountResp" } } } }, "404": { "$ref": "#/components/responses/NotFound" } } }
    },
    "/v1/accounts/{id}/detail": {
      "parameters": [{ "$ref": "#/components/parameters/AccountIdPath" }],
      "get": { "tags": ["Accounts"], "summary": "Full account snapshot", "description": "Returns balance, equity, every open position, every open order, and the most-recent fills.", "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AccountDetail" } } } } } }
    },
    "/v1/accounts/{id}/trades": {
      "parameters": [{ "$ref": "#/components/parameters/AccountIdPath" }, { "$ref": "#/components/parameters/LimitQuery" }],
      "get": { "tags": ["Accounts"], "summary": "Trade history for an account", "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "trades": { "type": "array", "items": { "type": "object", "additionalProperties": true } } } } } } } } }
    },
    "/v1/accounts/{id}/transactions": {
      "parameters": [{ "$ref": "#/components/parameters/AccountIdPath" }, { "$ref": "#/components/parameters/LimitQuery" }],
      "get": { "tags": ["Accounts"], "summary": "Deposit / withdrawal / admin-action history", "description": "Drawn from the admin_audit table — every change to the account's balance.", "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "transactions": { "type": "array", "items": { "type": "object", "additionalProperties": true } } } } } } } } }
    },
    "/v1/accounts/{id}/liquidations": {
      "parameters": [{ "$ref": "#/components/parameters/AccountIdPath" }, { "$ref": "#/components/parameters/LimitQuery" }],
      "get": { "tags": ["Accounts"], "summary": "Liquidation history for an account", "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "liquidations": { "type": "array", "items": { "type": "object", "additionalProperties": true } } } } } } } } }
    },
    "/v1/accounts/{id}/funding-history": {
      "parameters": [{ "$ref": "#/components/parameters/AccountIdPath" }, { "$ref": "#/components/parameters/LimitQuery" }],
      "get": { "tags": ["Accounts"], "summary": "Funding payment history for an account", "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "funding_payments": { "type": "array", "items": { "type": "object", "additionalProperties": true } } } } } } } } }
    },
    "/v1/accounts/{id}/deposit": {
      "parameters": [{ "$ref": "#/components/parameters/AccountIdPath" }],
      "post": { "tags": ["Accounts"], "summary": "Admin-immediate deposit", "description": "Credits the account immediately. Admin-side flow — for trader-initiated deposits use `/deposit-request`.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["amount"], "properties": { "amount": { "$ref": "#/components/schemas/DecimalString" } } } } } }, "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AccountResp" } } } } } }
    },
    "/v1/accounts/{id}/withdraw": {
      "parameters": [{ "$ref": "#/components/parameters/AccountIdPath" }],
      "post": { "tags": ["Accounts"], "summary": "Admin-immediate withdrawal", "description": "Debits the account immediately. Admin-side flow — for trader-initiated withdrawals use `/withdrawal-request`.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["amount"], "properties": { "amount": { "$ref": "#/components/schemas/DecimalString" } } } } } }, "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AccountResp" } } } }, "400": { "$ref": "#/components/responses/BadRequest" } } }
    },
    "/v1/accounts/{id}/deposit-request": {
      "parameters": [{ "$ref": "#/components/parameters/AccountIdPath" }],
      "post": { "tags": ["Accounts"], "summary": "Self-service deposit request", "description": "Queues a deposit for admin review. Engine balance is NOT credited until `/v1/admin/pending-deposits/:id/approve`.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["amount"], "properties": { "amount": { "$ref": "#/components/schemas/DecimalString" }, "chain": { "type": "string", "enum": ["ETH", "ARB", "TRON", "SOL"] }, "tx_hash": { "type": "string" }, "from_address": { "type": "string" }, "note": { "type": "string" } } } } } }, "responses": { "200": { "description": "Queued", "content": { "application/json": { "schema": { "type": "object", "properties": { "id": { "type": "integer" }, "client_id": { "$ref": "#/components/schemas/Uuid" }, "amount": { "$ref": "#/components/schemas/DecimalString" }, "status": { "type": "string", "enum": ["pending"] } } } } } } } }
    },
    "/v1/accounts/{id}/withdrawal-request": {
      "parameters": [{ "$ref": "#/components/parameters/AccountIdPath" }],
      "post": { "tags": ["Accounts"], "summary": "Self-service withdrawal request", "description": "Queues a withdrawal for admin review. Engine balance is NOT debited until `/v1/admin/pending-withdrawals/:id/approve`.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["amount", "chain", "wallet_address"], "properties": { "amount": { "$ref": "#/components/schemas/DecimalString" }, "chain": { "type": "string", "enum": ["ETH", "ARB", "TRON", "SOL"] }, "wallet_address": { "type": "string" }, "note": { "type": "string" } } } } } }, "responses": { "200": { "description": "Queued", "content": { "application/json": { "schema": { "type": "object", "properties": { "id": { "type": "integer" }, "client_id": { "$ref": "#/components/schemas/Uuid" }, "amount": { "$ref": "#/components/schemas/DecimalString" }, "status": { "type": "string", "enum": ["pending"] } } } } } } } }
    },

    "/v1/orders": {
      "post":   { "tags": ["Orders"], "summary": "Submit an order", "security": [{ "ApiKeyAuth": [] }], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OrderReq" } } } }, "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OrderResp" } } } }, "400": { "$ref": "#/components/responses/BadRequest" } } },
      "delete": { "tags": ["Orders"], "summary": "Cancel all open orders for a client", "security": [{ "ApiKeyAuth": [] }], "parameters": [{ "name": "client_id", "in": "query", "required": true, "schema": { "$ref": "#/components/schemas/Uuid" } }, { "name": "symbol", "in": "query", "required": false, "schema": { "type": "string" }, "description": "Optionally narrow to one symbol." }], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "cancelled": { "type": "integer" }, "order_ids": { "type": "array", "items": { "$ref": "#/components/schemas/Uuid" } } } } } } } } }
    },
    "/v1/orders/{symbol}/{id}": {
      "parameters": [{ "$ref": "#/components/parameters/SymbolPath" }, { "$ref": "#/components/parameters/OrderIdPath" }],
      "delete": { "tags": ["Orders"], "summary": "Cancel an order", "security": [{ "ApiKeyAuth": [] }], "responses": { "200": { "description": "Cancelled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OrderResp" } } } }, "404": { "$ref": "#/components/responses/NotFound" } } },
      "patch":  { "tags": ["Orders"], "summary": "Modify an order (in-place)", "description": "Reducing quantity preserves queue priority. Increasing quantity or changing price forfeits priority.", "security": [{ "ApiKeyAuth": [] }], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "price": { "$ref": "#/components/schemas/DecimalString" }, "quantity": { "$ref": "#/components/schemas/DecimalString" } } } } } }, "responses": { "200": { "description": "Modified", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OrderResp" } } } } } }
    },

    "/v1/algos/twap": { "post": { "tags": ["Algos"], "summary": "Submit a TWAP order", "security": [{ "ApiKeyAuth": [] }], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["client_id", "symbol", "side", "total_quantity", "slices", "interval_seconds", "order_type"], "properties": { "client_id": { "$ref": "#/components/schemas/Uuid" }, "symbol": { "type": "string" }, "side": { "type": "string", "enum": ["buy", "sell"] }, "total_quantity": { "$ref": "#/components/schemas/DecimalString" }, "slices": { "type": "integer" }, "interval_seconds": { "type": "integer" }, "order_type": { "type": "string", "enum": ["limit", "market"] }, "price": { "$ref": "#/components/schemas/DecimalString" }, "margin_mode": { "type": "string", "enum": ["cross", "isolated"] }, "leverage": { "type": "integer" }, "reduce_only": { "type": "boolean" } } } } } }, "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "algo_id": { "$ref": "#/components/schemas/Uuid" }, "status": { "type": "string" }, "scheduled_first_slice_ns": { "type": "integer" } } } } } } } } },
    "/v1/algos":        { "get":    { "tags": ["Algos"], "summary": "List active algos",        "security": [{ "ApiKeyAuth": [] }], "responses": { "200": { "description": "OK" } } } },
    "/v1/algos/{id}":   { "parameters": [{ "$ref": "#/components/parameters/OrderIdPath" }], "get": { "tags": ["Algos"], "summary": "Get algo state", "security": [{ "ApiKeyAuth": [] }], "responses": { "200": { "description": "OK" } } }, "delete": { "tags": ["Algos"], "summary": "Cancel remaining slices", "security": [{ "ApiKeyAuth": [] }], "responses": { "200": { "description": "OK" } } } },

    "/v1/orders/oco":      { "post": { "tags": ["OCO"], "summary": "Submit an OCO pair", "security": [{ "ApiKeyAuth": [] }], "responses": { "200": { "description": "OK" } } }, "get": { "tags": ["OCO"], "summary": "List OCO pairs", "security": [{ "ApiKeyAuth": [] }], "responses": { "200": { "description": "OK" } } } },
    "/v1/orders/oco/{id}": { "parameters": [{ "$ref": "#/components/parameters/OrderIdPath" }], "get": { "tags": ["OCO"], "summary": "Get OCO state", "security": [{ "ApiKeyAuth": [] }], "responses": { "200": { "description": "OK" } } }, "delete": { "tags": ["OCO"], "summary": "Cancel OCO pair", "security": [{ "ApiKeyAuth": [] }], "responses": { "200": { "description": "OK" } } } },

    "/v1/orders/bracket":      { "post": { "tags": ["Bracket"], "summary": "Submit a bracket order", "description": "Entry + take-profit + stop-loss legs in one call.", "security": [{ "ApiKeyAuth": [] }], "responses": { "200": { "description": "OK" } } }, "get": { "tags": ["Bracket"], "summary": "List bracket orders", "security": [{ "ApiKeyAuth": [] }], "responses": { "200": { "description": "OK" } } } },
    "/v1/orders/bracket/{id}": { "parameters": [{ "$ref": "#/components/parameters/OrderIdPath" }], "get": { "tags": ["Bracket"], "summary": "Get bracket state", "security": [{ "ApiKeyAuth": [] }], "responses": { "200": { "description": "OK" } } }, "delete": { "tags": ["Bracket"], "summary": "Cancel bracket", "security": [{ "ApiKeyAuth": [] }], "responses": { "200": { "description": "OK" } } } },

    "/v1/positions/{client_id}": {
      "parameters": [{ "$ref": "#/components/parameters/ClientIdPath" }],
      "get": { "tags": ["Positions"], "summary": "List all positions for a client", "security": [{ "ApiKeyAuth": [] }], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "positions": { "type": "array", "items": { "$ref": "#/components/schemas/PositionResp" } } } } } } } } }
    },
    "/v1/positions/{client_id}/{symbol}": {
      "parameters": [{ "$ref": "#/components/parameters/ClientIdPath" }, { "$ref": "#/components/parameters/SymbolPath" }],
      "get": { "tags": ["Positions"], "summary": "Get one position", "security": [{ "ApiKeyAuth": [] }], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PositionResp" } } } }, "404": { "$ref": "#/components/responses/NotFound" } } }
    },
    "/v1/positions/{client_id}/close_all": {
      "parameters": [{ "$ref": "#/components/parameters/ClientIdPath" }],
      "post": { "tags": ["Positions"], "summary": "Close every open position", "description": "Submits market-IOC reduce-only orders to flatten all positions. Used by the trader-side Close-All UI and by the ops Danger Zone.", "security": [{ "ApiKeyAuth": [] }], "responses": { "200": { "description": "OK" } } }
    },

    "/v1/insurance": { "get": { "tags": ["Insurance"], "summary": "Insurance fund balance", "description": "Per-shard balance. Sum across shards gives the platform total displayed in the trust strip.", "responses": { "200": { "description": "OK" } } } },

    "/v1/risk/halts":           { "get": { "tags": ["Risk"], "summary": "Currently halted markets", "responses": { "200": { "description": "OK" } } } },
    "/v1/risk/tiers/{symbol}":  { "parameters": [{ "$ref": "#/components/parameters/SymbolPath" }], "get": { "tags": ["Risk"], "summary": "Margin tier table for a symbol", "responses": { "200": { "description": "OK" } } } },
    "/v1/risk/swap/{symbol}":   { "parameters": [{ "$ref": "#/components/parameters/SymbolPath" }], "get": { "tags": ["Risk"], "summary": "Overnight swap rate (non-crypto)", "description": "Forex / commodity / index overnight swap rates. Crypto perpetuals return `applicable: false`.", "responses": { "200": { "description": "OK" } } } },

    "/v1/admin/diagnostics":               { "get":    { "tags": ["Admin"], "summary": "Engine diagnostics", "security": [{ "AdminToken": [] }], "responses": { "200": { "description": "OK" } } } },
    "/v1/admin/audit":                     { "get":    { "tags": ["Admin"], "summary": "Admin action audit log", "security": [{ "AdminToken": [] }], "parameters": [{ "name": "limit", "in": "query", "schema": { "type": "integer" } }, { "name": "before_id", "in": "query", "schema": { "type": "integer" } }, { "name": "client_id", "in": "query", "schema": { "$ref": "#/components/schemas/Uuid" } }], "responses": { "200": { "description": "OK" } } } },
    "/v1/admin/api_keys":                  { "post":   { "tags": ["Admin"], "summary": "Issue an API key", "security": [{ "AdminToken": [] }], "responses": { "200": { "description": "OK" } } }, "get": { "tags": ["Admin"], "summary": "List API keys", "security": [{ "AdminToken": [] }], "responses": { "200": { "description": "OK" } } } },
    "/v1/admin/api_keys/{key}":            { "parameters": [{ "name": "key", "in": "path", "required": true, "schema": { "type": "string" } }], "delete": { "tags": ["Admin"], "summary": "Revoke an API key", "security": [{ "AdminToken": [] }], "responses": { "200": { "description": "OK" } } } },
    "/v1/admin/risk_limits/{cid}":         { "parameters": [{ "name": "cid", "in": "path", "required": true, "schema": { "$ref": "#/components/schemas/Uuid" } }], "post": { "tags": ["Admin"], "summary": "Update per-client risk limits", "security": [{ "AdminToken": [] }], "responses": { "200": { "description": "OK" } } } },
    "/v1/admin/halt/{symbol}":             { "parameters": [{ "$ref": "#/components/parameters/SymbolPath" }], "post": { "tags": ["Admin"], "summary": "Halt or resume a symbol", "security": [{ "AdminToken": [] }], "responses": { "200": { "description": "OK" } } } },
    "/v1/admin/halt_all":                  { "post":   { "tags": ["Admin"], "summary": "Halt or resume all markets", "security": [{ "AdminToken": [] }], "responses": { "200": { "description": "OK" } } } },
    "/v1/admin/pending-deposits":          { "get":    { "tags": ["Admin"], "summary": "List pending deposits", "security": [{ "AdminToken": [] }], "responses": { "200": { "description": "OK" } } } },
    "/v1/admin/pending-deposits/{id}/approve":  { "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "integer" } }], "post": { "tags": ["Admin"], "summary": "Approve a pending deposit", "security": [{ "AdminToken": [] }], "responses": { "200": { "description": "OK" } } } },
    "/v1/admin/pending-deposits/{id}/reject":   { "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "integer" } }], "post": { "tags": ["Admin"], "summary": "Reject a pending deposit", "security": [{ "AdminToken": [] }], "responses": { "200": { "description": "OK" } } } },
    "/v1/admin/pending-withdrawals":       { "get":    { "tags": ["Admin"], "summary": "List pending withdrawals", "security": [{ "AdminToken": [] }], "responses": { "200": { "description": "OK" } } } },
    "/v1/admin/pending-withdrawals/{id}/approve": { "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "integer" } }], "post": { "tags": ["Admin"], "summary": "Approve a pending withdrawal", "security": [{ "AdminToken": [] }], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["payout_tx_hash"], "properties": { "payout_tx_hash": { "type": "string" }, "admin_note": { "type": "string" } } } } } }, "responses": { "200": { "description": "OK" } } } },
    "/v1/admin/pending-withdrawals/{id}/reject":  { "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "integer" } }], "post": { "tags": ["Admin"], "summary": "Reject a pending withdrawal", "security": [{ "AdminToken": [] }], "responses": { "200": { "description": "OK" } } } },

    "/v1/index-price":   { "post": { "tags": ["Internal"], "summary": "Aggregator index-price ingest", "description": "Used by the aggregator to push mark/index prices into the engine. Internal — assumed reachable only from inside the trust boundary.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["symbol", "price", "source"], "properties": { "symbol": { "type": "string" }, "price": { "$ref": "#/components/schemas/DecimalString" }, "source": { "type": "string" }, "timestamp_ms": { "type": "integer" } } } } } }, "responses": { "200": { "description": "OK" } } } },
    "/v1/book-snapshot": { "post": { "tags": ["Internal"], "summary": "Book-seeder snapshot ingest", "description": "Used by the book seeder to push an external order-book snapshot into the engine.", "responses": { "200": { "description": "OK" } } } },
    "/proxy/{target}":   { "parameters": [{ "name": "target", "in": "path", "required": true, "schema": { "type": "string" } }], "get": { "tags": ["Internal"], "summary": "Relay pass-through", "description": "Pass-through proxy to upstream market-data REST APIs for CORS reasons. Body and response shape mirror the upstream verbatim.", "responses": { "200": { "description": "OK" } } } },

    "/ws": { "get": { "tags": ["Health & Observability"], "summary": "WebSocket upgrade endpoint", "description": "HTTP-upgrade to the WebSocket broadcast stream. See the Info section at the top of these docs for the channel + event-type catalogue.", "responses": { "101": { "description": "Switching Protocols" } } } }
  }
}
