{
  "openapi": "3.1.0",
  "info": {
    "title": "NovaMarket Agent API",
    "version": "1.0.0",
    "summary": "Read-only, anonymous on-chain fund data for AI agents and developers.",
    "description": "HTTP API for NovaMarket — a multi-strategy on-chain first-loss fund platform.\n- The `/v1` surface (tags Protocol/Pools) is read-only `GET`, anonymous JSON. Errors use RFC 7807 `application/problem+json`.\n- The trading & program surface (tags Auth/Trading/Programs) lives at the site root and requires a SIWE session or a Bearer API key (`nm_…`). Errors are `{ error, detail? }` JSON (see the ErrorBody schema).\n- Amounts are USDC base units (`decimals: 6`); large integers are JSON strings.\n- Order placement is queue-semantic: 201 means queued; the platform executor routes to the venue on its next ~30s cycle.\n- Data is read live from Arbitrum; when contracts are not yet configured, lists are empty and /health reports `not-configured`.",
    "contact": {
      "name": "NovaMarket",
      "url": "https://novamarket.io"
    }
  },
  "servers": [
    {
      "url": "https://novamarket.io/api/v1"
    }
  ],
  "tags": [
    {
      "name": "Protocol",
      "description": "Platform metadata, contracts, markets, health"
    },
    {
      "name": "Pools",
      "description": "Capital pools and settlement history"
    },
    {
      "name": "Auth",
      "description": "SIWE session login (website/PWA)"
    },
    {
      "name": "Trading",
      "description": "Custodial execution — order routing, positions, equity (operator-authenticated). Orders are QUEUE-semantic: POST enqueues a PENDING row that the platform executor routes to the venue on its next cycle (~30s); 201 means queued, not filled."
    },
    {
      "name": "Programs",
      "description": "Program operators — register a quant program as a first-class operator (own EOA, leaderboard entry). Management is owner-session only; a deployed program trades through the Trading endpoints with its program-scoped API key."
    }
  ],
  "paths": {
    "/protocol": {
      "get": {
        "tags": [
          "Protocol"
        ],
        "operationId": "getProtocol",
        "summary": "Platform metadata: brand, chain, contracts, markets, discovery links.",
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "500": {
            "description": "Server error",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/contracts": {
      "get": {
        "tags": [
          "Protocol"
        ],
        "operationId": "getContracts",
        "summary": "Deployed contract addresses.",
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "500": {
            "description": "Server error",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/markets": {
      "get": {
        "tags": [
          "Protocol"
        ],
        "operationId": "listMarkets",
        "summary": "Supported venues (Hyperliquid, Polymarket, Uniswap) and planned ones.",
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "500": {
            "description": "Server error",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/health": {
      "get": {
        "tags": [
          "Protocol"
        ],
        "operationId": "getHealth",
        "summary": "Chain reachability + configuration status.",
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "500": {
            "description": "Server error",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/pools": {
      "get": {
        "tags": [
          "Pools"
        ],
        "operationId": "listPools",
        "summary": "List all capital pools with params and live balances.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "example": {
                  "items": [
                    {
                      "address": "0x…",
                      "strategy": {
                        "label": "Market Making"
                      },
                      "market": {
                        "id": 0,
                        "name": "Hyperliquid"
                      },
                      "status": {
                        "id": 2,
                        "name": "Active"
                      },
                      "params": {
                        "expectedReturnBpsYear": 1500,
                        "riskCapBps": 2000,
                        "carryBps": 2000,
                        "capTotal": "1000000000000"
                      },
                      "balances": {
                        "investorNav": "100000000000",
                        "marginStaked": "20000000000"
                      },
                      "decimals": 6
                    }
                  ],
                  "count": 1
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "500": {
            "description": "Server error",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/pools/{address}": {
      "get": {
        "tags": [
          "Pools"
        ],
        "operationId": "getPool",
        "summary": "One pool by CapitalPool address.",
        "parameters": [
          {
            "name": "address",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^0x[0-9a-fA-F]{40}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "500": {
            "description": "Server error",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/pools/{address}/settlements": {
      "get": {
        "tags": [
          "Pools"
        ],
        "operationId": "getPoolSettlements",
        "summary": "Recent on-chain Settled events (best-effort, bounded window).",
        "parameters": [
          {
            "name": "address",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^0x[0-9a-fA-F]{40}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "500": {
            "description": "Server error",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/auth/nonce": {
      "servers": [
        {
          "url": "https://novamarket.io"
        }
      ],
      "get": {
        "tags": [
          "Auth"
        ],
        "operationId": "getAuthNonce",
        "summary": "Mint a single-use SIWE nonce.",
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/auth/verify": {
      "servers": [
        {
          "url": "https://novamarket.io"
        }
      ],
      "post": {
        "tags": [
          "Auth"
        ],
        "operationId": "verifySiwe",
        "summary": "Verify a SIWE message+signature; sets the session cookie.",
        "responses": {
          "200": {
            "description": "OK"
          },
          "401": {
            "description": "Invalid signature/nonce"
          }
        }
      }
    },
    "/api/keys": {
      "servers": [
        {
          "url": "https://novamarket.io"
        }
      ],
      "get": {
        "tags": [
          "Auth"
        ],
        "operationId": "listApiKeys",
        "summary": "List the caller's API keys (metadata only).",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "401": {
            "description": "Unauthenticated"
          }
        }
      },
      "post": {
        "tags": [
          "Auth"
        ],
        "operationId": "mintApiKey",
        "summary": "Mint an API key (token shown once). Session only.",
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Created"
          },
          "403": {
            "description": "Session required"
          }
        }
      }
    },
    "/api/pools/{address}/credentials": {
      "servers": [
        {
          "url": "https://novamarket.io"
        }
      ],
      "parameters": [
        {
          "name": "address",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "pattern": "^0x[0-9a-fA-F]{40}$"
          }
        }
      ],
      "get": {
        "tags": [
          "Trading"
        ],
        "operationId": "getCredentialStatus",
        "summary": "Venue credential status (never returns the secret).",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      },
      "post": {
        "tags": [
          "Trading"
        ],
        "operationId": "setCredential",
        "summary": "Set/rotate the pool's sealed venue credential. Session only; operator only.",
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Stored"
          },
          "403": {
            "description": "Not operator / session required"
          }
        }
      },
      "delete": {
        "tags": [
          "Trading"
        ],
        "operationId": "deleteCredential",
        "summary": "Revoke the pool's venue credential.",
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/pools/{address}/orders": {
      "servers": [
        {
          "url": "https://novamarket.io"
        }
      ],
      "parameters": [
        {
          "name": "address",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "pattern": "^0x[0-9a-fA-F]{40}$"
          }
        }
      ],
      "post": {
        "tags": [
          "Trading"
        ],
        "operationId": "placeOrder",
        "summary": "Place an order on the pool's venue (operator only; pool must be Active). Idempotent on clientOrderId.",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "example": {
                "symbol": "ETH",
                "side": "BUY",
                "size": 1.5,
                "clientOrderId": "my-uuid"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Deduped"
          },
          "201": {
            "description": "Queued"
          },
          "401": {
            "description": "Unauthenticated"
          },
          "403": {
            "description": "Not operator"
          },
          "409": {
            "description": "Pool not Active / no credential"
          }
        }
      },
      "get": {
        "tags": [
          "Trading"
        ],
        "operationId": "listOrders",
        "summary": "List recent orders (?status=&limit=).",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      },
      "delete": {
        "tags": [
          "Trading"
        ],
        "operationId": "cancelAllOrders",
        "summary": "Cancel all resting venue orders (?symbol=).",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "202": {
            "description": "Queued"
          }
        }
      }
    },
    "/api/pools/{address}/positions": {
      "servers": [
        {
          "url": "https://novamarket.io"
        }
      ],
      "parameters": [
        {
          "name": "address",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "pattern": "^0x[0-9a-fA-F]{40}$"
          }
        }
      ],
      "get": {
        "tags": [
          "Trading"
        ],
        "operationId": "getPositions",
        "summary": "Latest venue positions snapshot (executor-written).",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/pools/{address}/equity": {
      "servers": [
        {
          "url": "https://novamarket.io"
        }
      ],
      "parameters": [
        {
          "name": "address",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "pattern": "^0x[0-9a-fA-F]{40}$"
          }
        }
      ],
      "get": {
        "tags": [
          "Trading"
        ],
        "operationId": "getEquity",
        "summary": "Latest venue equity snapshot (USDC 6dp).",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/pools/{address}/flatten": {
      "servers": [
        {
          "url": "https://novamarket.io"
        }
      ],
      "parameters": [
        {
          "name": "address",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "pattern": "^0x[0-9a-fA-F]{40}$"
          }
        }
      ],
      "post": {
        "tags": [
          "Trading"
        ],
        "operationId": "flatten",
        "summary": "Emergency: cancel all orders + market-close all positions.",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "202": {
            "description": "Queued"
          }
        }
      }
    },
    "/api/programs": {
      "servers": [
        {
          "url": "https://novamarket.io"
        }
      ],
      "get": {
        "tags": [
          "Programs"
        ],
        "operationId": "listPrograms",
        "summary": "List the caller's programs.",
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      },
      "post": {
        "tags": [
          "Programs"
        ],
        "operationId": "createProgram",
        "summary": "Register a program (Draft). Hosted mode needs a studio strategy core.",
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Created"
          }
        }
      }
    },
    "/api/programs/{id}/deploy": {
      "servers": [
        {
          "url": "https://novamarket.io"
        }
      ],
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "post": {
        "tags": [
          "Programs"
        ],
        "operationId": "deployProgram",
        "summary": "Auto-admission deploy: backtest thresholds + owner quota → mints the program operator EOA (self-hosted: also mints the program API key, shown once).",
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Deployed"
          },
          "409": {
            "description": "Admission failed"
          },
          "429": {
            "description": "Quota reached"
          }
        }
      }
    },
    "/api/programs/{id}/bind-pool": {
      "servers": [
        {
          "url": "https://novamarket.io"
        }
      ],
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "post": {
        "tags": [
          "Programs"
        ],
        "operationId": "bindProgramPool",
        "summary": "Program EOA signs acceptPool (margin from its own balance) and the strategy core goes live under the platform executor.",
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Live"
          },
          "409": {
            "description": "Preconditions failed"
          }
        }
      }
    },
    "/api/programs/{id}/keys": {
      "servers": [
        {
          "url": "https://novamarket.io"
        }
      ],
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "tags": [
          "Programs"
        ],
        "operationId": "listProgramKeys",
        "summary": "List the program's API keys (metadata only).",
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      },
      "post": {
        "tags": [
          "Programs"
        ],
        "operationId": "mintProgramKey",
        "summary": "Mint a program API key (authenticates AS the program EOA, pool-scoped; shown once).",
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Created"
          }
        }
      }
    },
    "/api/programs/{id}/runtime": {
      "servers": [
        {
          "url": "https://novamarket.io"
        }
      ],
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "tags": [
          "Programs"
        ],
        "operationId": "getProgramRuntime",
        "summary": "Live runtime: equity/positions snapshot, strategy health, recent orders, program-EOA balances; while Deployed, the paper-trading snapshot.",
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/pools/{address}/orders/{id}": {
      "servers": [
        {
          "url": "https://novamarket.io"
        }
      ],
      "parameters": [
        {
          "name": "address",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "pattern": "^0x[0-9a-fA-F]{40}$"
          }
        },
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "tags": [
          "Trading"
        ],
        "operationId": "getOrder",
        "summary": "One order by id.",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Trading"
        ],
        "operationId": "cancelOrder",
        "summary": "Cancel an order that is still PENDING (before the executor sends it).",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Cancelled"
          },
          "404": {
            "description": "Not found"
          },
          "409": {
            "description": "Already sent"
          }
        }
      }
    },
    "/api/pools/{address}/strategy": {
      "servers": [
        {
          "url": "https://novamarket.io"
        }
      ],
      "parameters": [
        {
          "name": "address",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "pattern": "^0x[0-9a-fA-F]{40}$"
          }
        }
      ],
      "get": {
        "tags": [
          "Trading"
        ],
        "operationId": "getStrategy",
        "summary": "The pool's hosted-strategy config (or null).",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      },
      "post": {
        "tags": [
          "Trading"
        ],
        "operationId": "setStrategy",
        "summary": "Deploy/update the hosted strategy (built-in name or a Verified community strategy). Session + operator only.",
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "example": {
                "strategyName": "趋势",
                "symbol": "ETH",
                "maxPosition": 1,
                "maxOrder": 0.5,
                "enabled": true,
                "stopMaxDrawdownBps": 1000,
                "stopDailyLossBps": 500
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Stored"
          },
          "403": {
            "description": "Session required / not operator"
          },
          "409": {
            "description": "Strategy not applicable / not verified"
          }
        }
      },
      "delete": {
        "tags": [
          "Trading"
        ],
        "operationId": "deleteStrategy",
        "summary": "Remove the hosted strategy (stops auto-trading).",
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/pools/{address}/fund-init": {
      "servers": [
        {
          "url": "https://novamarket.io"
        }
      ],
      "parameters": [
        {
          "name": "address",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "pattern": "^0x[0-9a-fA-F]{40}$"
          }
        }
      ],
      "get": {
        "tags": [
          "Trading"
        ],
        "operationId": "getFundInit",
        "summary": "Latest fund-init job + venue init checkpoint (poll target).",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      },
      "post": {
        "tags": [
          "Trading"
        ],
        "operationId": "startFundInit",
        "summary": "Queue a venue fund-init job after the browser-signed user-fund leg (HL/UNI: USDC transfer; PM: CCTP burnTx). Session only.",
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "example": {
                "market": "HYPERLIQUID",
                "amountUsdc6": "100000000"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Queued"
          },
          "409": {
            "description": "No credential / job in flight"
          }
        }
      }
    },
    "/api/pools/{address}/accounts/provision": {
      "servers": [
        {
          "url": "https://novamarket.io"
        }
      ],
      "parameters": [
        {
          "name": "address",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "pattern": "^0x[0-9a-fA-F]{40}$"
          }
        }
      ],
      "post": {
        "tags": [
          "Trading"
        ],
        "operationId": "provisionAccount",
        "summary": "Auto-create the pool's venue trading account (signer mints + seals the key; web only sees the public address). Session + operator only.",
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Created"
          },
          "409": {
            "description": "Credential exists"
          }
        }
      }
    },
    "/api/pools/{address}/accounts/init-state": {
      "servers": [
        {
          "url": "https://novamarket.io"
        }
      ],
      "parameters": [
        {
          "name": "address",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "pattern": "^0x[0-9a-fA-F]{40}$"
          }
        }
      ],
      "get": {
        "tags": [
          "Trading"
        ],
        "operationId": "getInitState",
        "summary": "Venue init pipeline checkpoint (resume/progress).",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/pools/{address}/stream": {
      "servers": [
        {
          "url": "https://novamarket.io"
        }
      ],
      "parameters": [
        {
          "name": "address",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "pattern": "^0x[0-9a-fA-F]{40}$"
          }
        }
      ],
      "get": {
        "tags": [
          "Trading"
        ],
        "operationId": "streamPool",
        "summary": "Server-sent events: live equity/positions/orders snapshots (text/event-stream).",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "SSE stream"
          }
        }
      }
    },
    "/api/programs/{id}": {
      "servers": [
        {
          "url": "https://novamarket.io"
        }
      ],
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "tags": [
          "Programs"
        ],
        "operationId": "getProgram",
        "summary": "Program detail (owner).",
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      },
      "patch": {
        "tags": [
          "Programs"
        ],
        "operationId": "updateProgram",
        "summary": "Edit while Draft/Validated (name, description, strategy core).",
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "409": {
            "description": "Not editable in this status"
          }
        }
      },
      "delete": {
        "tags": [
          "Programs"
        ],
        "operationId": "deleteProgram",
        "summary": "Delete a program that never minted an EOA.",
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "409": {
            "description": "Has an operator EOA"
          }
        }
      }
    },
    "/api/programs/{id}/provision": {
      "servers": [
        {
          "url": "https://novamarket.io"
        }
      ],
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "post": {
        "tags": [
          "Programs"
        ],
        "operationId": "provisionProgramPool",
        "summary": "Create the program pool's venue trading account (owner-session; mirrors the pool provision route).",
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Created"
          },
          "409": {
            "description": "Credential exists / no pool"
          }
        }
      }
    },
    "/api/programs/{id}/fund": {
      "servers": [
        {
          "url": "https://novamarket.io"
        }
      ],
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "post": {
        "tags": [
          "Programs"
        ],
        "operationId": "fundProgramPool",
        "summary": "Fund the program pool's venue account: program EOA signs drawFunds → transfer to the venue account → worker finishes the venue legs. HYPERLIQUID/UNISWAP only for now.",
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "example": {
                "market": "HYPERLIQUID",
                "amountUsdc6": "100000000"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Queued"
          },
          "409": {
            "description": "Not Live / no credential / job in flight"
          }
        }
      }
    },
    "/api/programs/{id}/withdraw": {
      "servers": [
        {
          "url": "https://novamarket.io"
        }
      ],
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "post": {
        "tags": [
          "Programs"
        ],
        "operationId": "withdrawProgram",
        "summary": "Pull earnings to the owner wallet: claimCarry / withdrawMargin from the pool, then transfer to the owner (recipient fixed server-side).",
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "example": {
                "kind": "carry",
                "amountUsdc6": "50000000"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Sent"
          },
          "409": {
            "description": "No pool"
          }
        }
      }
    },
    "/api/programs/{id}/stop": {
      "servers": [
        {
          "url": "https://novamarket.io"
        }
      ],
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "post": {
        "tags": [
          "Programs"
        ],
        "operationId": "stopProgram",
        "summary": "Stop the program: disable the hosted strategy, optionally flatten and revoke keys. Re-deploy resumes the same pool.",
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Stopped"
          }
        }
      }
    },
    "/api/programs/{id}/emergency-flatten": {
      "servers": [
        {
          "url": "https://novamarket.io"
        }
      ],
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "post": {
        "tags": [
          "Programs"
        ],
        "operationId": "emergencyFlattenProgram",
        "summary": "Owner kill switch: cancel all + market-close every position on the program's pool.",
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "202": {
            "description": "Queued"
          }
        }
      }
    },
    "/api/programs/{id}/bundle": {
      "servers": [
        {
          "url": "https://novamarket.io"
        }
      ],
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "tags": [
          "Programs"
        ],
        "operationId": "getProgramBundle",
        "summary": "Self-hosted starter bundle: strategy.py + run.py + .env.example as JSON files.",
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/programs/{id}/keys/{prefix}": {
      "servers": [
        {
          "url": "https://novamarket.io"
        }
      ],
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "prefix",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "delete": {
        "tags": [
          "Programs"
        ],
        "operationId": "revokeProgramKey",
        "summary": "Revoke one of the program's API keys.",
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not found"
          }
        }
      }
    },
    "/api/auth/me": {
      "servers": [
        {
          "url": "https://novamarket.io"
        }
      ],
      "get": {
        "tags": [
          "Auth"
        ],
        "operationId": "getMe",
        "summary": "Current session address (or null).",
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/auth/logout": {
      "servers": [
        {
          "url": "https://novamarket.io"
        }
      ],
      "post": {
        "tags": [
          "Auth"
        ],
        "operationId": "logout",
        "summary": "Clear the session cookie.",
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/keys/{prefix}": {
      "servers": [
        {
          "url": "https://novamarket.io"
        }
      ],
      "parameters": [
        {
          "name": "prefix",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "delete": {
        "tags": [
          "Auth"
        ],
        "operationId": "revokeApiKey",
        "summary": "Revoke one of the caller's API keys.",
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not found"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Problem": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "format": "uri"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "detail": {
            "type": "string"
          },
          "instance": {
            "type": "string"
          }
        },
        "required": [
          "type",
          "title",
          "status"
        ]
      },
      "ErrorBody": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          },
          "detail": {}
        },
        "required": [
          "error"
        ]
      }
    },
    "securitySchemes": {
      "cookieAuth": {
        "type": "apiKey",
        "in": "cookie",
        "name": "nm_session",
        "description": "SIWE session cookie (website/PWA)."
      },
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Operator API key: `Authorization: Bearer nm_…`."
      }
    }
  }
}
