{
  "openapi": "3.1.0",
  "info": {
    "title": "PolyTrackers API",
    "version": "2.0.0",
    "description": "External and agent-relevant API surface for PolyTrackers.\n\nThis v2 spec documents the current AI-agent API surface, including auth,\naccount/tier awareness, anomaly workflows, market discovery, and real-trading\nendpoints alongside existing whale-service integrations.\n\nInternal-only cron/test endpoints are excluded.\n"
  },
  "servers": [
    {
      "url": "https://polytrackers.com",
      "description": "Production"
    },
    {
      "url": "http://localhost:3003",
      "description": "Local development"
    }
  ],
  "tags": [
    {
      "name": "MCP"
    },
    {
      "name": "Auth"
    },
    {
      "name": "Account"
    },
    {
      "name": "Markets & Discovery"
    },
    {
      "name": "Leaderboard"
    },
    {
      "name": "Trades"
    },
    {
      "name": "Real Trading"
    },
    {
      "name": "API Keys"
    },
    {
      "name": "Anomalies"
    },
    {
      "name": "Public Data"
    },
    {
      "name": "Scan"
    },
    {
      "name": "Wallet & Roster"
    },
    {
      "name": "Whale Service"
    },
    {
      "name": "Webhooks"
    },
    {
      "name": "Deprecated"
    }
  ],
  "paths": {
    "/api/mcp": {
      "get": {
        "tags": ["MCP"],
        "summary": "MCP health and capability probe (unauthenticated)",
        "operationId": "mcpHealthProbe",
        "description": "Unauthenticated health and capability probe for the MCP server. Returns the server name, version, supported MCP protocol versions, and the capability list. Clients that open this endpoint with `Accept: text/event-stream` receive `405`; the optional server-to-client stream is `GET /api/mcp/events`, not this path. The `200` body is CDN-cacheable and changes only on deploy.",
        "security": [],
        "responses": {
          "200": {
            "description": "MCP server identity and capabilities.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": { "type": "boolean" },
                    "server": { "type": "string" },
                    "version": { "type": "string" },
                    "protocol_versions": {
                      "type": "array",
                      "items": { "type": "string" }
                    },
                    "capabilities": {
                      "type": "array",
                      "items": { "type": "string" }
                    }
                  }
                }
              }
            }
          },
          "405": {
            "description": "Returned when the request sets `Accept: text/event-stream`. Use `GET /api/mcp/events` for the SSE subchannel."
          }
        }
      },
      "post": {
        "tags": ["MCP"],
        "summary": "MCP JSON-RPC endpoint (Streamable HTTP)",
        "operationId": "mcpJsonRpc",
        "description": "JSON-RPC 2.0 over Streamable HTTP in stateless JSON mode. Send `Authorization: Bearer ptk_…` (the same Agent API Key used for the REST API). The server resolves the key, enforces per-key request rate limits, and forwards the call to a per-request MCP server instance. Tool and resource availability is governed by the key's scopes (`signals:read`, `trade:execute`, `agent:scan`, `agent:full`). A key without the required scope is rejected.",
        "security": [{ "ApiKeyBearer": [] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "A JSON-RPC 2.0 request object (or batch)."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "JSON-RPC 2.0 response.",
            "content": {
              "application/json": { "schema": { "type": "object" } }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/TooManyRequests" }
        }
      }
    },
    "/api/mcp/events": {
      "get": {
        "tags": ["MCP"],
        "summary": "MCP server-sent events subchannel (optional)",
        "operationId": "mcpEventStream",
        "description": "Optional server-sent events (SSE) subchannel for MCP notifications. Requires `Authorization: Bearer ptk_…`. Streams the `anomalies`, `whale_signals`, `copy_signals`, and `scan_progress` topics; filter with the `topics` query parameter. Topics are gated by the key's tier and disallowed topics are dropped silently. The stream emits a `: keepalive` comment frame roughly every 15 seconds.",
        "security": [{ "ApiKeyBearer": [] }],
        "parameters": [
          {
            "in": "query",
            "name": "topics",
            "required": false,
            "description": "Comma-separated subset of `anomalies`, `whale_signals`, `copy_signals`, `scan_progress`. Omit for all topics permitted by the key's tier.",
            "schema": { "type": "string" }
          }
        ],
        "responses": {
          "200": {
            "description": "An event stream of MCP notifications.",
            "content": {
              "text/event-stream": { "schema": { "type": "string" } }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/TooManyRequests" }
        }
      }
    },
    "/api/account": {
      "get": {
        "tags": ["Account"],
        "summary": "Get authenticated account summary",
        "operationId": "getAccountSummary",
        "security": [
          {
            "SessionCookie": []
          },
          {
            "UserBearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Account-level identity and tier summary.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountSummaryResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/account/risk-profile": {
      "get": {
        "tags": ["Account"],
        "summary": "Get account risk profile",
        "operationId": "getRiskProfile",
        "security": [
          {
            "SessionCookie": []
          },
          {
            "UserBearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Risk profile for the authenticated account.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "riskProfile": {
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/RiskProfile"
                        }
                      ],
                      "nullable": true
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      },
      "post": {
        "tags": ["Account"],
        "summary": "Update account risk profile",
        "operationId": "updateRiskProfile",
        "security": [
          {
            "SessionCookie": []
          },
          {
            "UserBearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["riskTolerance", "tradeFrequency", "timeHorizon"],
                "additionalProperties": false,
                "properties": {
                  "riskTolerance": {
                    "type": "string",
                    "enum": ["low", "medium", "high"]
                  },
                  "preferredCategories": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "politics",
                        "crypto",
                        "sports",
                        "economy",
                        "technology",
                        "other"
                      ]
                    },
                    "maxItems": 5
                  },
                  "tradeFrequency": {
                    "type": "string",
                    "enum": ["low", "medium", "high"]
                  },
                  "timeHorizon": {
                    "type": "string",
                    "enum": ["short", "medium", "long"]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated risk profile.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "riskProfile": {
                      "$ref": "#/components/schemas/RiskProfile"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/account/stats": {
      "get": {
        "tags": ["Account"],
        "summary": "Get account trading and anomaly stats",
        "operationId": "getAccountStats",
        "description": "Real-trading statistics are only populated for Elite tier users.\nNon-Elite responses return real-trading fields as zero.\n",
        "security": [
          {
            "SessionCookie": []
          },
          {
            "UserBearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Aggregated stats for the authenticated account.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountStatsResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/alerts/preferences": {
      "get": {
        "tags": ["Account"],
        "summary": "Get alert preferences",
        "operationId": "getAlertPreferences",
        "security": [
          {
            "SessionCookie": []
          },
          {
            "UserBearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "User alert preferences and capabilities.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AlertPreferencesResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      },
      "put": {
        "tags": ["Account"],
        "summary": "Update alert preferences",
        "operationId": "updateAlertPreferences",
        "description": "Free tier requests are accepted and return `200` with `upgradeRequired: true` and tier-safe preferences. Pro/Elite can fully configure alerts.",
        "security": [
          {
            "SessionCookie": []
          },
          {
            "UserBearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "enabled": {
                    "type": "boolean"
                  },
                  "frequency": {
                    "type": "string",
                    "enum": ["realtime", "digest_hourly"]
                  },
                  "channels": {
                    "type": "object",
                    "properties": {
                      "telegram": {
                        "type": "object",
                        "properties": {
                          "enabled": {
                            "type": "boolean"
                          },
                          "chatId": {
                            "type": "string",
                            "nullable": true
                          }
                        }
                      },
                      "discord": {
                        "type": "object",
                        "properties": {
                          "enabled": {
                            "type": "boolean"
                          },
                          "webhookUrl": {
                            "type": "string",
                            "nullable": true
                          }
                        }
                      },
                      "email": {
                        "type": "object",
                        "properties": {
                          "enabled": {
                            "type": "boolean"
                          },
                          "email": {
                            "type": "string",
                            "nullable": true
                          }
                        }
                      }
                    }
                  },
                  "thresholds": {
                    "type": "object",
                    "properties": {
                      "minScore": {
                        "type": "number"
                      },
                      "minCashValue": {
                        "type": "number"
                      },
                      "severities": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "enum": ["HIGH", "MEDIUM"]
                        }
                      },
                      "predictiveSignals": {
                        "type": "boolean"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated preferences.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AlertPreferencesResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      },
      "delete": {
        "tags": ["Account"],
        "summary": "Delete (reset) alert preferences",
        "operationId": "deleteAlertPreferences",
        "security": [
          {
            "SessionCookie": []
          },
          {
            "UserBearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Preferences reset to defaults.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AlertPreferencesResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/anomalies": {
      "get": {
        "tags": ["Anomalies"],
        "summary": "List anomaly detections visible to the caller tier",
        "operationId": "listAnomalies",
        "description": "Tier-scoped retention and max-result behavior:\n- Free: max 5 results, last 7 days, 1 hour delayed visibility\n- Pro: max 100 results, last 90 days\n- Elite: max 200 results, full retention window\n\nSupports session auth (`sb-*` cookie/JWT) or Agent API Keys\n(`Authorization: Bearer <api-key>`) with `signals:read` scope.\n",
        "security": [
          {
            "SessionCookie": []
          },
          {
            "UserBearer": []
          },
          {
            "ApiKeyBearer": []
          }
        ],
        "parameters": [
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "in": "query",
            "name": "severity",
            "required": false,
            "description": "Filter the feed by confidence tier. Only user-visible tiers are accepted (PT-L-015): low-confidence signals are research-only and are never returned by this endpoint, and requesting `low` (or the never-emitted `critical`) returns `400` with an invalid-severity error.",
            "schema": {
              "type": "string",
              "enum": ["medium", "high"]
            }
          },
          {
            "in": "query",
            "name": "anomaly_type",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "market_slug",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "since",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tier-scoped anomaly list.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnomalyListResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/anomalies/performance": {
      "get": {
        "tags": ["Anomalies"],
        "summary": "Aggregate anomaly detector performance over a time window",
        "operationId": "getAnomalyPerformance",
        "description": "Returns detector quality metrics — flagged volume, resolution coverage,\nwin rate, average return, total P&L, and an equal-dollar simulation —\naggregated from the `anomaly_performance_daily` view.\n\nThe `window` is clamped to `since..until` (default: last 30 days, max\n365 days). Results are returned as a single `totals` object plus a\n`series` keyed by `group_by`.\n\nAccepts session auth (`sb-*` cookie/JWT) or a Agent API Key\n(`Authorization: Bearer <api-key>`) with `signals:read` scope.\n",
        "security": [
          {
            "SessionCookie": []
          },
          {
            "UserBearer": []
          },
          {
            "ApiKeyBearer": []
          }
        ],
        "parameters": [
          {
            "in": "query",
            "name": "since",
            "required": false,
            "description": "ISO-8601 datetime. Defaults to `until - 30 days`.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "in": "query",
            "name": "until",
            "required": false,
            "description": "ISO-8601 datetime. Defaults to now.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "in": "query",
            "name": "group_by",
            "required": false,
            "description": "Cohort key for the `series` array.",
            "schema": {
              "type": "string",
              "enum": ["day", "month", "anomaly_type", "severity", "all"],
              "default": "day"
            }
          },
          {
            "in": "query",
            "name": "anomaly_type",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "severity",
            "required": false,
            "schema": {
              "type": "string",
              "enum": ["low", "medium", "high", "critical"]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Performance aggregation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnomalyPerformanceResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/anomalies/{id}": {
      "get": {
        "tags": ["Anomalies"],
        "summary": "Get single anomaly detail by ID",
        "operationId": "getAnomalyById",
        "description": "Returns `404` for unknown anomaly IDs and for anomalies outside the\ncaller's tier retention window.\n",
        "security": [
          {
            "SessionCookie": []
          },
          {
            "UserBearer": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Anomaly detail record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnomalyDetail"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "Not found (missing ID, unknown anomaly, or outside tier window).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/backtest": {
      "post": {
        "tags": ["Backtesting"],
        "summary": "Backtest a signal strategy against historical resolved markets",
        "operationId": "runBacktest",
        "description": "Replays historical PolyTrackers signals (detector anomalies by\nseverity, or a tracked whale wallet) chronologically against a\nsimulated bankroll. Capital accounting is honest: stakes lock at\ndetection, entries are skipped when cash runs out, open positions\nare valued at cost until resolution, slippage worsens entries, and\nfees shave winning proceeds. Results are a historical simulation —\nnot a prediction of future returns.\n\nTier behavior:\n- Free: exactly one demo configuration is accepted\n  (`{\"source\":{\"kind\":\"anomalies\",\"minSeverity\":\"HIGH\"},\"stake\":{\"mode\":\"flat\",\"amountUsd\":100},\"startingBankrollUsd\":1000,\"windowDays\":30,\"slippageBps\":50,\"feeBps\":0}`);\n  the trade list is capped at 5 rows.\n- Pro: custom configurations with `windowDays` up to 90.\n- Elite: custom configurations with `windowDays` up to 365.\n\nSupports session auth (`sb-*` cookie/JWT) or Agent API Keys\n(`Authorization: Bearer <api-key>`) with `signals:read` scope.\n",
        "security": [
          {
            "SessionCookie": []
          },
          {
            "UserBearer": []
          },
          {
            "ApiKeyBearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "source",
                  "stake",
                  "startingBankrollUsd",
                  "windowDays"
                ],
                "properties": {
                  "source": {
                    "oneOf": [
                      {
                        "type": "object",
                        "required": ["kind", "minSeverity"],
                        "properties": {
                          "kind": {
                            "type": "string",
                            "enum": ["anomalies"]
                          },
                          "minSeverity": {
                            "type": "string",
                            "description": "Minimum confidence tier to replay. Low-confidence signals are research-only and are never backtested (PT-L-015); requesting `LOW` is rejected as an invalid input.",
                            "enum": ["MEDIUM", "HIGH"]
                          },
                          "anomalyType": {
                            "type": "string",
                            "maxLength": 64
                          }
                        }
                      },
                      {
                        "type": "object",
                        "required": ["kind", "wallet"],
                        "properties": {
                          "kind": {
                            "type": "string",
                            "enum": ["whale"]
                          },
                          "wallet": {
                            "type": "string",
                            "pattern": "^0x[0-9a-fA-F]{40}$"
                          }
                        }
                      }
                    ]
                  },
                  "stake": {
                    "oneOf": [
                      {
                        "type": "object",
                        "required": ["mode", "amountUsd"],
                        "properties": {
                          "mode": {
                            "type": "string",
                            "enum": ["flat"]
                          },
                          "amountUsd": {
                            "type": "number",
                            "minimum": 1,
                            "maximum": 100000
                          }
                        }
                      },
                      {
                        "type": "object",
                        "required": ["mode", "pctOfBankroll"],
                        "properties": {
                          "mode": {
                            "type": "string",
                            "enum": ["percent"]
                          },
                          "pctOfBankroll": {
                            "type": "number",
                            "minimum": 0.1,
                            "maximum": 100
                          }
                        }
                      }
                    ]
                  },
                  "startingBankrollUsd": {
                    "type": "number",
                    "minimum": 10,
                    "maximum": 10000000
                  },
                  "windowDays": {
                    "type": "integer",
                    "enum": [30, 90, 180, 365]
                  },
                  "slippageBps": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 1000,
                    "default": 50
                  },
                  "feeBps": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 1000,
                    "default": 0
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Backtest result: strategy stats, equity curve, per-trade log, an all-signals baseline, and the fee/slippage assumptions.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "config": {
                      "type": "object"
                    },
                    "assumptions": {
                      "type": "object"
                    },
                    "disclaimer": {
                      "type": "string"
                    },
                    "strategy": {
                      "type": "object",
                      "properties": {
                        "stats": {
                          "type": "object"
                        },
                        "equityCurve": {
                          "type": "array",
                          "items": {
                            "type": "object"
                          }
                        },
                        "trades": {
                          "type": "array",
                          "items": {
                            "type": "object"
                          }
                        }
                      }
                    },
                    "baseline": {
                      "type": "object"
                    },
                    "signalsTruncated": {
                      "type": "boolean"
                    },
                    "tradesTruncated": {
                      "type": "boolean"
                    },
                    "demo": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/TierUpgradeRequired"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/auth/refresh": {
      "post": {
        "tags": ["Auth"],
        "summary": "Exchange refresh token for new session tokens",
        "operationId": "refreshAgentSession",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RefreshTokenRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Refreshed access and refresh token pair.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthTokensResponse"
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid refresh token payload.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Invalid or expired refresh token.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthErrorResponse"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/bets/sync": {
      "post": {
        "tags": ["Trades"],
        "summary": "Sync user bets from Polymarket",
        "operationId": "syncUserBets",
        "description": "Syncs user's bets from Polymarket using their linked wallet.",
        "security": [
          {
            "SessionCookie": []
          },
          {
            "UserBearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Sync results.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "newBets": {
                      "type": "integer"
                    },
                    "totalBets": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid wallet address.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "Profile not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/clob/price": {
      "get": {
        "tags": ["Public Data"],
        "summary": "Get live CLOB price for a market condition",
        "operationId": "getClobPrice",
        "parameters": [
          {
            "in": "query",
            "name": "conditionId",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Polymarket condition ID."
          },
          {
            "in": "query",
            "name": "outcome",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [true, false],
              "default": true
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Live price found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClobPriceResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "description": "No live price available for this condition/outcome.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "502": {
            "description": "Upstream CLOB fetch failed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/keys": {
      "get": {
        "tags": ["API Keys"],
        "summary": "List Agent API Key and server-derived trading credential metadata",
        "operationId": "listApiKeys",
        "description": "Pro and Elite only.\nLists masked Agent API Keys plus server-derived trading credential\nmetadata that remains list/revoke-only. Manual Polymarket credential\nstorage is retired.\n",
        "security": [
          {
            "SessionCookie": []
          },
          {
            "UserBearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Agent API Key and server-derived trading credential metadata list.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiKeysListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/TierUpgradeRequired"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      },
      "delete": {
        "tags": ["API Keys"],
        "summary": "Revoke an Agent API Key or trading credential by ID",
        "operationId": "deleteApiKey",
        "description": "Pro and Elite only.\nRevokes an Agent API Key or remaining server-derived trading\ncredential metadata entry by ID. New manual Polymarket credential\nstorage is not supported.\nThe underlying row is retained for audit (with `is_active=false` and\n`revoked_at` stamped); subsequent authentication attempts with that key\nwill be rejected immediately.\n",
        "security": [
          {
            "SessionCookie": []
          },
          {
            "UserBearer": []
          }
        ],
        "parameters": [
          {
            "in": "query",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Key revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuccessResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/TierUpgradeRequired"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/keys/generate": {
      "post": {
        "tags": ["API Keys"],
        "summary": "Generate a new Agent API Key",
        "operationId": "generateApiKey",
        "description": "JWT bearer auth only. The generated token is returned **once** and cannot\nbe retrieved again.\n\nGenerated Agent API Keys are scoped and expire automatically.\nPro keys can request `signals:read`, `trade:execute`, and optional `agent:scan` for scan triggers where allowed.\nElite keys can request `signals:read`, `trade:execute`, `agent:scan`, and `agent:full`.\n",
        "security": [
          {
            "JwtBearer": []
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "nickname": {
                    "type": "string",
                    "maxLength": 80
                  },
                  "expiresInDays": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 365,
                    "default": 90,
                    "description": "Number of days before key expiry."
                  },
                  "scopes": {
                    "type": "array",
                    "maxItems": 5,
                    "items": {
                      "type": "string",
                      "enum": [
                        "signals:read",
                        "trade:execute",
                        "agent:scan",
                        "agent:full"
                      ]
                    },
                    "description": "Optional list of granted scopes.\n`signals:read` is sufficient for read-only data.\n`trade:execute` allows real trade execution after readiness/preflight gates pass.\n`agent:scan` allows scan triggers where allowed.\n`agent:full` grants full agent/write/trade access and is Elite only.\n"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Agent API Key generated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiKeyGenerateResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/TierUpgradeRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/leaderboard": {
      "get": {
        "tags": ["Leaderboard"],
        "summary": "Get ranked whale leaderboard data",
        "operationId": "getLeaderboard",
        "description": "Supports session auth (`sb-*` cookie/JWT) or Agent API Keys\n(`Authorization: Bearer <api-key>`) with `signals:read` scope.\n",
        "security": [
          {
            "SessionCookie": []
          },
          {
            "UserBearer": []
          },
          {
            "ApiKeyBearer": []
          }
        ],
        "parameters": [
          {
            "in": "query",
            "name": "period",
            "required": false,
            "schema": {
              "type": "string",
              "enum": ["weekly", "monthly", "all-time"],
              "default": "weekly"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "in": "query",
            "name": "offset",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Leaderboard page with caller rank context.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeaderboardResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/markets": {
      "get": {
        "tags": ["Markets & Discovery"],
        "summary": "Discover and filter Polymarket markets",
        "operationId": "listMarkets",
        "description": "Public endpoint. Unauthenticated callers are rate-limited by IP.\n\nIf authenticated (`SessionCookie` or `UserBearer`), request-specific\npublic IP rate limiting is skipped.\n",
        "security": [],
        "parameters": [
          {
            "in": "query",
            "name": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 120
            }
          },
          {
            "in": "query",
            "name": "category",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 64
            }
          },
          {
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "type": "string",
              "enum": ["open", "resolved"],
              "default": "open"
            }
          },
          {
            "in": "query",
            "name": "sort",
            "required": false,
            "schema": {
              "type": "string",
              "enum": ["volume", "newest", "ending-soon"],
              "default": "volume"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Filtered market listing.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MarketsResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "502": {
            "description": "Upstream market source unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/public/copy-signals": {
      "get": {
        "tags": ["Public Data"],
        "summary": "List recent copy-trading signals for an Elite API key",
        "operationId": "listPublicCopySignals",
        "description": "Machine-friendly copy-trading signal feed for external integrations.\n\nThis route requires a Agent API Key (`Authorization: Bearer <api-key>`)\ncreated via `/api/keys/generate`, with `signals:read` scope, and the key\nowner must be on the Elite tier.\n",
        "security": [
          {
            "ApiKeyBearer": []
          }
        ],
        "parameters": [
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            },
            "description": "Maximum number of signals to return."
          },
          {
            "in": "query",
            "name": "since",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Return only signals with `detected_at >= since`."
          }
        ],
        "responses": {
          "200": {
            "description": "Recent copy-trading signals.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicCopySignalsResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "API key is valid but user tier is not Elite.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/public/whale-signals": {
      "get": {
        "tags": ["Public Data"],
        "summary": "List recent whale signals for an Elite API key",
        "operationId": "listPublicWhaleSignals",
        "description": "Machine-friendly whale signal feed for external integrations.\n\nThis route requires a Agent API Key (`Authorization: Bearer <api-key>`)\ncreated via `/api/keys/generate`, with `signals:read` scope, and the key\nowner must be on the Elite tier.\n",
        "security": [
          {
            "ApiKeyBearer": []
          }
        ],
        "parameters": [
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            },
            "description": "Maximum number of signals to return."
          },
          {
            "in": "query",
            "name": "since",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Return only signals with `detected_at >= since`."
          }
        ],
        "responses": {
          "200": {
            "description": "Recent whale signals.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicWhaleSignalsResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "API key is valid but user tier is not Elite.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/recommendations": {
      "get": {
        "tags": ["Markets & Discovery"],
        "summary": "Get trader recommendations based on risk profile",
        "operationId": "getRecommendations",
        "security": [
          {
            "SessionCookie": []
          },
          {
            "UserBearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "List of recommended traders and user risk profile.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "recommendations": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "wallet": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "matchScore": {
                            "type": "number"
                          },
                          "winRate": {
                            "type": "number"
                          },
                          "avgBetSize": {
                            "type": "number"
                          },
                          "topCategories": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "backtestCoverage": {
                            "$ref": "#/components/schemas/WhaleBacktestCoverage"
                          },
                          "whaleEdge": {
                            "$ref": "#/components/schemas/WhaleEdgeMetadata"
                          }
                        }
                      }
                    },
                    "riskProfile": {
                      "$ref": "#/components/schemas/RiskProfile"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/roster": {
      "get": {
        "tags": ["Wallet & Roster"],
        "summary": "List whale-to-wallet assignments",
        "operationId": "listRosterAssignments",
        "security": [
          {
            "WhaleServiceSecret": []
          },
          {
            "ServiceBearerSecret": []
          },
          {
            "SessionCookie": []
          }
        ],
        "responses": {
          "200": {
            "description": "Roster records.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["roster"],
                  "properties": {
                    "roster": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/RosterAssignment"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      },
      "post": {
        "tags": ["Wallet & Roster"],
        "summary": "Create whale assignment",
        "operationId": "createRosterAssignment",
        "security": [
          {
            "WhaleServiceSecret": []
          },
          {
            "ServiceBearerSecret": []
          },
          {
            "SessionCookie": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["address", "name", "walletId"],
                "properties": {
                  "address": {
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  },
                  "walletId": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Assignment created.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["whale"],
                  "properties": {
                    "whale": {
                      "$ref": "#/components/schemas/RosterAssignment"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "409": {
            "description": "Whale already actively assigned.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/roster/{address}": {
      "patch": {
        "tags": ["Wallet & Roster"],
        "summary": "Update whale assignment",
        "operationId": "updateRosterAssignment",
        "security": [
          {
            "WhaleServiceSecret": []
          },
          {
            "ServiceBearerSecret": []
          },
          {
            "SessionCookie": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "address",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "walletId": {
                    "type": "string"
                  },
                  "fromWalletId": {
                    "type": "string"
                  },
                  "reason": {
                    "type": "string"
                  },
                  "active": {
                    "type": "boolean"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Assignment updated.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["whale"],
                  "properties": {
                    "whale": {
                      "$ref": "#/components/schemas/RosterAssignment"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "Assignment not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "fromWalletId does not match current assignment.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      },
      "delete": {
        "tags": ["Wallet & Roster"],
        "summary": "Deactivate whale assignment",
        "operationId": "deleteRosterAssignment",
        "security": [
          {
            "WhaleServiceSecret": []
          },
          {
            "ServiceBearerSecret": []
          },
          {
            "SessionCookie": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "address",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "reason",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reason": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Assignment deactivated.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["whale"],
                  "properties": {
                    "whale": {
                      "$ref": "#/components/schemas/RosterAssignment"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "Active assignment not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/scan/run": {
      "post": {
        "tags": ["Scan"],
        "summary": "Trigger anomaly detection scan",
        "operationId": "runAnomalyScan",
        "description": "Runs a full anomaly detection pass.\n\nAuthorization options:\n- `x-scan-secret` header matching `SCAN_SECRET` (bypasses tier gate)\n- authenticated user context (`sb-*` session cookie or bearer token)\n\nWithout `x-scan-secret`, authenticated callers must resolve to Pro/Elite.\n",
        "security": [
          {
            "ScanSecret": []
          },
          {
            "SessionCookie": []
          },
          {
            "UserBearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Scan completed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["success", "count", "timestamp"],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "const": true
                    },
                    "count": {
                      "type": "integer"
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "Authenticated caller is free tier and did not provide scan secret.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/scan/trigger": {
      "post": {
        "tags": ["Scan"],
        "summary": "Trigger an on-demand anomaly scan for authenticated user context",
        "operationId": "triggerOnDemandScan",
        "description": "Requires authenticated user context and Pro/Elite tier.\n\nRate limits:\n- Pro: 2 scans/hour\n- Elite: 10 scans/hour\n",
        "x-polytrackers-auth": {
          "requiredTier": "pro"
        },
        "security": [
          {
            "SessionCookie": []
          },
          {
            "UserBearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Scan completed with mapped anomaly output.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScanTriggerResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "Tier upgrade required (Pro minimum).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/trade/execute": {
      "post": {
        "tags": ["Real Trading"],
        "summary": "Execute a real trade on Polymarket",
        "operationId": "executeRealTrade",
        "description": "Requires trading-readiness checks: active Polymarket trading credentials,\ntrading wallet/signing setup, wallet risk config, circuit-breaker state,\nidempotency, reservation, and audit logging.\n\nRequires `regionCertification: true` to certify the caller is not\nlocated in, resident in, or otherwise subject to a jurisdiction where\nPolymarket trading is restricted or prohibited.\n\nIdempotency: the `Idempotency-Key` request header is the canonical\ncarrier. The body field `idempotencyKey` is still accepted for\nbackward compatibility for browser/session callers; when both are\nsupplied they must be identical or the request is rejected with `400`.\nAgent API Key callers (`ApiKeyBearer` /\n`Authorization: Bearer <api-key>`) must send `Idempotency-Key`; they\ncannot rely on the legacy body field. Missing this header for an Agent\nAPI Key request returns `400 IDEMPOTENCY_KEY_REQUIRED`.\n\nRate limit: real-trade execution is limited to 20 requests per 60\nseconds per Agent API Key (a separate per-user limit also applies).\n\nSupports either browser session auth or Agent API Keys\n(`Authorization: Bearer <api-key>`) with `trade:execute` scope.\n",
        "x-polytrackers-auth": {
          "requiredTier": "pro",
          "requiredScopes": ["trade:execute"]
        },
        "x-rate-limit": {
          "perApiKey": {
            "limit": 20,
            "windowSeconds": 60
          }
        },
        "security": [
          {
            "SessionCookie": []
          },
          {
            "UserBearer": []
          },
          {
            "ApiKeyBearer": []
          }
        ],
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "description": "Canonical idempotency carrier (8-256 printable ASCII characters,\nUUIDv4 recommended). If the body also sets `idempotencyKey`, the two\nmust match or the request returns `400`. Required for Agent API Key\ncallers (`ApiKeyBearer` / `Authorization: Bearer <api-key>`);\nmissing it returns `400 IDEMPOTENCY_KEY_REQUIRED`. Browser/session\ncallers may rely on the legacy body `idempotencyKey`.\n",
            "schema": {
              "type": "string",
              "minLength": 8,
              "maxLength": 256
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TradeExecuteRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Trade executed (or idempotent replay returned).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TradeExecuteResponse"
                }
              }
            }
          },
          "400": {
            "description": "Input, risk, or credential precondition error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TradeErrorResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/TierUpgradeRequired"
          },
          "404": {
            "description": "Condition/market not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TradeErrorResponse"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "502": {
            "description": "Upstream order execution failure.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TradeErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Required execution readiness checks unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TradeErrorResponse"
                }
              }
            }
          },
          "504": {
            "description": "Trade execution timeout.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TradeErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/trade/history": {
      "get": {
        "tags": ["Real Trading"],
        "summary": "List real trade history entries",
        "operationId": "listRealTradeHistory",
        "description": "Elite tier only.\nSupports either browser session auth or Agent API Keys\n(`Authorization: Bearer <api-key>`) with `agent:full` scope.\n",
        "x-polytrackers-auth": {
          "requiredTier": "elite",
          "requiredScopes": ["agent:full"]
        },
        "security": [
          {
            "SessionCookie": []
          },
          {
            "UserBearer": []
          },
          {
            "ApiKeyBearer": []
          }
        ],
        "parameters": [
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          },
          {
            "in": "query",
            "name": "offset",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          },
          {
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "type": "string",
              "enum": ["pending", "filled", "partial", "cancelled", "failed"]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Real trade history page.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TradeHistoryResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/TierUpgradeRequired"
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TradeErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/trade/orders": {
      "get": {
        "tags": ["Real Trading"],
        "summary": "List currently open real-trading orders",
        "operationId": "listOpenTradeOrders",
        "description": "Elite tier only.\nSupports either browser session auth or Agent API Keys\n(`Authorization: Bearer <api-key>`) with `agent:full` scope.\n",
        "x-polytrackers-auth": {
          "requiredTier": "elite",
          "requiredScopes": ["agent:full"]
        },
        "security": [
          {
            "SessionCookie": []
          },
          {
            "UserBearer": []
          },
          {
            "ApiKeyBearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Open order list.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TradeOrdersResponse"
                }
              }
            }
          },
          "400": {
            "description": "Missing required trading credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TradeErrorResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/TierUpgradeRequired"
          },
          "502": {
            "description": "Upstream order fetch failure.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TradeErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/trade/orders/{id}": {
      "get": {
        "tags": ["Real Trading"],
        "summary": "Get a single real-trading order by order ID",
        "operationId": "getTradeOrder",
        "description": "Elite tier only.\nSupports either browser session auth or Agent API Keys\n(`Authorization: Bearer <api-key>`) with `agent:full` scope.\n",
        "x-polytrackers-auth": {
          "requiredTier": "elite",
          "requiredScopes": ["agent:full"]
        },
        "security": [
          {
            "SessionCookie": []
          },
          {
            "UserBearer": []
          },
          {
            "ApiKeyBearer": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Order found.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["order"],
                  "properties": {
                    "order": {
                      "$ref": "#/components/schemas/TradeOrder"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid order id or missing trading credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TradeErrorResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/TierUpgradeRequired"
          },
          "404": {
            "description": "Order not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TradeErrorResponse"
                }
              }
            }
          },
          "502": {
            "description": "Upstream order fetch failure.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TradeErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": ["Real Trading"],
        "summary": "Cancel an open real-trading order by order ID",
        "operationId": "cancelTradeOrder",
        "description": "Browser/session callers can cancel their own resting order regardless\nof tier, because cancellation reduces live exposure.\nAgent API Key callers must present a valid key with `agent:full`;\nmissing, invalid, or under-scoped API keys return `401 Unauthorized`\nfrom this REST operation.\n",
        "x-polytrackers-auth": {
          "requiredScopes": ["agent:full"]
        },
        "security": [
          {
            "SessionCookie": []
          },
          {
            "UserBearer": []
          },
          {
            "ApiKeyBearer": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Cancellation accepted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TradeCancelResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid order id or missing trading credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TradeErrorResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "502": {
            "description": "Upstream cancellation failure.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TradeErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/trader-lookup": {
      "get": {
        "tags": ["Trades"],
        "summary": "Look up a trader's trades",
        "operationId": "traderLookup",
        "security": [
          {
            "SessionCookie": []
          },
          {
            "UserBearer": []
          }
        ],
        "parameters": [
          {
            "in": "query",
            "name": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Trader username or wallet address."
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 100,
              "maximum": 500
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Trader trades found.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "query": {
                      "type": "string"
                    },
                    "trades": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      }
                    },
                    "count": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/trades": {
      "get": {
        "tags": ["Trades"],
        "summary": "Unified mock + real trade history feed",
        "operationId": "listTrades",
        "description": "Tier-gated history depth and data exposure:\n- Free: last 7 days, mock trades only\n- Pro: last 90 days, mock trades only\n- Elite: full history, mock + real access\n\nSupports session auth (`sb-*` cookie/JWT) or Agent API Keys\n(`Authorization: Bearer <api-key>`) with `signals:read` scope.\n`type=real` requires Elite and returns `403` otherwise.\n",
        "security": [
          {
            "SessionCookie": []
          },
          {
            "UserBearer": []
          },
          {
            "ApiKeyBearer": []
          }
        ],
        "parameters": [
          {
            "in": "query",
            "name": "type",
            "required": false,
            "schema": {
              "type": "string",
              "enum": ["mock", "real", "all"],
              "default": "all"
            }
          },
          {
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "type": "string",
              "enum": ["open", "closed", "all"],
              "default": "all"
            }
          },
          {
            "in": "query",
            "name": "walletId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "sort",
            "required": false,
            "schema": {
              "type": "string",
              "enum": ["newest", "oldest"],
              "default": "newest"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "in": "query",
            "name": "offset",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Trade history page.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TradesResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/TierUpgradeRequired"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/wallets": {
      "get": {
        "tags": ["Wallet & Roster"],
        "summary": "List mock wallets",
        "operationId": "listWallets",
        "security": [
          {
            "WhaleServiceSecret": []
          },
          {
            "ServiceBearerSecret": []
          },
          {
            "SessionCookie": []
          }
        ],
        "responses": {
          "200": {
            "description": "Wallets visible to requester.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["wallets"],
                  "properties": {
                    "wallets": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Wallet"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      },
      "post": {
        "tags": ["Wallet & Roster"],
        "summary": "Create mock wallet",
        "operationId": "createWallet",
        "security": [
          {
            "WhaleServiceSecret": []
          },
          {
            "ServiceBearerSecret": []
          },
          {
            "SessionCookie": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateWalletRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Wallet created.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["wallet"],
                  "properties": {
                    "wallet": {
                      "$ref": "#/components/schemas/Wallet"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      },
      "delete": {
        "tags": ["Wallet & Roster"],
        "summary": "Delete mock wallet",
        "operationId": "deleteWallet",
        "security": [
          {
            "WhaleServiceSecret": []
          },
          {
            "ServiceBearerSecret": []
          },
          {
            "SessionCookie": []
          }
        ],
        "parameters": [
          {
            "in": "query",
            "name": "walletId",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Wallet ID. Can also be sent in request body."
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "walletId": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Wallet deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuccessResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "Wallet not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/webhooks": {
      "get": {
        "tags": ["Webhooks"],
        "summary": "List user webhooks",
        "operationId": "listWebhooks",
        "security": [
          {
            "SessionCookie": []
          },
          {
            "UserBearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "List of webhook registrations.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "webhooks": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/WebhookRegistrationRecord"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      },
      "post": {
        "tags": ["Webhooks"],
        "summary": "Create a webhook",
        "operationId": "createWebhook",
        "description": "Requires Pro or Elite tier.",
        "x-polytrackers-auth": {
          "requiredTier": "pro"
        },
        "security": [
          {
            "SessionCookie": []
          },
          {
            "UserBearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string"
                  },
                  "filters": {
                    "type": "object",
                    "properties": {
                      "minScore": {
                        "type": "number"
                      },
                      "severity": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "anomalyTypes": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "marketCategories": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      }
                    }
                  },
                  "secret": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Webhook created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookRegistrationRecord"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "Authenticated user tier does not allow creating additional webhooks.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookCreateForbiddenError"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/webhooks/{id}": {
      "get": {
        "tags": ["Webhooks"],
        "summary": "Get a webhook by ID",
        "operationId": "getWebhook",
        "description": "Returns a single webhook registration owned by the caller, with the\nsame shape as the list endpoint's items.\n",
        "security": [
          {
            "SessionCookie": []
          },
          {
            "UserBearer": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Webhook registration.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookRegistrationRecord"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "Webhook not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      },
      "patch": {
        "tags": ["Webhooks"],
        "summary": "Update a webhook",
        "operationId": "updateWebhook",
        "description": "Updates a webhook registration owned by the caller. Provide at least\none of `url`, `filters`, or `secret`; omitted fields are left\nunchanged.\n",
        "security": [
          {
            "SessionCookie": []
          },
          {
            "UserBearer": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "minProperties": 1,
                "properties": {
                  "url": {
                    "type": "string"
                  },
                  "filters": {
                    "type": "object",
                    "properties": {
                      "minScore": {
                        "type": "number"
                      },
                      "severity": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "anomalyTypes": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "marketCategories": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      }
                    }
                  },
                  "secret": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Webhook updated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookRegistrationRecord"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "Webhook not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      },
      "delete": {
        "tags": ["Webhooks"],
        "summary": "Delete a webhook",
        "operationId": "deleteWebhook",
        "security": [
          {
            "SessionCookie": []
          },
          {
            "UserBearer": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Webhook deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuccessResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "Webhook not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/webhooks/{id}/deliveries": {
      "get": {
        "tags": ["Webhooks"],
        "summary": "List webhook deliveries",
        "operationId": "listWebhookDeliveries",
        "security": [
          {
            "SessionCookie": []
          },
          {
            "UserBearer": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 100,
              "maximum": 500
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Webhook delivery logs.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "deliveries": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/WebhookDeliveryLogRecord"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "Webhook not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/webhooks/{id}/test": {
      "post": {
        "tags": ["Webhooks"],
        "summary": "Send a test webhook delivery",
        "operationId": "sendTestWebhook",
        "security": [
          {
            "SessionCookie": []
          },
          {
            "UserBearer": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Test webhook delivered successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["success", "responseCode"],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "const": true
                    },
                    "responseCode": {
                      "type": "integer",
                      "nullable": true
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "Webhook not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "502": {
            "description": "Webhook endpoint rejected or failed test delivery.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["error"],
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "responseCode": {
                      "type": "integer",
                      "nullable": true
                    },
                    "details": {
                      "type": "string",
                      "nullable": true
                    }
                  }
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/whale/activity": {
      "get": {
        "tags": ["Whale Service"],
        "summary": "List whale activity feed",
        "operationId": "listWhaleActivity",
        "security": [
          {
            "WhaleServiceSecret": []
          },
          {
            "ServiceBearerSecret": []
          },
          {
            "SessionCookie": []
          }
        ],
        "parameters": [
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "in": "query",
            "name": "walletId",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Activity rows.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["activity"],
                  "properties": {
                    "activity": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/WhaleActivityRecord"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "Wallet scope forbidden.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/whale/backfill-market-titles": {
      "post": {
        "tags": ["Whale Service"],
        "summary": "Backfill stale market titles/slugs for whale records",
        "operationId": "backfillWhaleMarketTitles",
        "security": [
          {
            "WhaleServiceSecret": []
          },
          {
            "ServiceBearerSecret": []
          },
          {
            "SessionCookie": []
          }
        ],
        "responses": {
          "200": {
            "description": "Backfill summary.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "total",
                    "updated",
                    "skipped",
                    "failed",
                    "tradesUpdated",
                    "eventSlugBackfilled",
                    "resolvedMarkets"
                  ],
                  "properties": {
                    "total": {
                      "type": "integer"
                    },
                    "updated": {
                      "type": "integer"
                    },
                    "skipped": {
                      "type": "integer"
                    },
                    "failed": {
                      "type": "integer"
                    },
                    "tradesUpdated": {
                      "type": "integer"
                    },
                    "eventSlugBackfilled": {
                      "type": "integer"
                    },
                    "resolvedMarkets": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/whale/config": {
      "get": {
        "tags": ["Whale Service"],
        "summary": "Get wallet-scoped whale risk config",
        "operationId": "getWhaleConfig",
        "description": "Requires authenticated user session.",
        "security": [
          {
            "SessionCookie": []
          }
        ],
        "parameters": [
          {
            "in": "query",
            "name": "walletId",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Current config.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WhaleConfigResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "Wallet not owned or no wallet available.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      },
      "put": {
        "tags": ["Whale Service"],
        "summary": "Update wallet-scoped whale risk config",
        "operationId": "updateWhaleConfig",
        "description": "Requires authenticated user session.\n\nIf service secret auth is also present, shared global detection keys can\nbe updated in addition to wallet-scoped values.\n",
        "security": [
          {
            "SessionCookie": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WhaleConfigPatchRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated config.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WhaleConfigResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "Wallet not owned or no wallet available.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/whale/kill": {
      "post": {
        "tags": ["Whale Service"],
        "summary": "Trip whale circuit breaker (kill)",
        "operationId": "killWhaleService",
        "security": [
          {
            "WhaleServiceSecret": []
          },
          {
            "ServiceBearerSecret": []
          },
          {
            "SessionCookie": []
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reason": {
                    "type": "string",
                    "default": "manual-kill"
                  },
                  "walletId": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Breaker set to KILLED.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["success", "status"],
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "status": {
                      "type": "string",
                      "const": "KILLED"
                    },
                    "reason": {
                      "type": "string"
                    },
                    "walletId": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "Wallet not found/accessible for provided walletId.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/whale/performance": {
      "get": {
        "tags": ["Whale Service"],
        "summary": "Get whale performance analytics",
        "operationId": "getWhalePerformance",
        "security": [
          {
            "SessionCookie": []
          }
        ],
        "responses": {
          "200": {
            "description": "Performance payload.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["data"],
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/WhalePerformanceData"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/whale/resume": {
      "post": {
        "tags": ["Whale Service"],
        "summary": "Resume whale service after kill",
        "operationId": "resumeWhaleService",
        "security": [
          {
            "WhaleServiceSecret": []
          },
          {
            "ServiceBearerSecret": []
          },
          {
            "SessionCookie": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["confirmation"],
                "properties": {
                  "confirmation": {
                    "type": "boolean",
                    "enum": [true]
                  },
                  "confirm": {
                    "type": "boolean",
                    "enum": [true]
                  },
                  "walletId": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Breaker reset to ACTIVE.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["success", "status"],
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "status": {
                      "type": "string",
                      "const": "ACTIVE"
                    },
                    "walletId": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "Wallet not found/accessible for provided walletId.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/whale/roster-assign": {
      "post": {
        "tags": ["Whale Service"],
        "summary": "Add/remove assignment (legacy helper route)",
        "operationId": "rosterAssign",
        "description": "Convenience route used by the whale tracking UI.\nNew integrations should prefer `/api/roster` and `/api/roster/{address}`.\n",
        "security": [
          {
            "SessionCookie": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["walletId", "whaleAddress", "action"],
                "properties": {
                  "walletId": {
                    "type": "string"
                  },
                  "whaleAddress": {
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  },
                  "action": {
                    "type": "string",
                    "enum": ["add", "remove"]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Assignment action applied.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["success", "action"],
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "action": {
                      "type": "string",
                      "enum": ["add", "remove"]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "Wallet access denied.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/whale/signals": {
      "get": {
        "tags": ["Whale Service"],
        "summary": "List whale signals for authenticated user wallets",
        "operationId": "listWhaleSignals",
        "security": [
          {
            "SessionCookie": []
          }
        ],
        "parameters": [
          {
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "type": "string",
              "enum": ["all", "executed", "skipped"],
              "default": "all"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500,
              "default": 100
            }
          },
          {
            "in": "query",
            "name": "walletId",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Signal rows.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["signals"],
                  "properties": {
                    "signals": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/WhaleActivityRecord"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "Requested walletId not owned by requester.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/whale/status": {
      "get": {
        "tags": ["Whale Service"],
        "summary": "Get whale runtime status and breaker metrics",
        "operationId": "getWhaleStatus",
        "security": [
          {
            "WhaleServiceSecret": []
          },
          {
            "ServiceBearerSecret": []
          },
          {
            "SessionCookie": []
          }
        ],
        "parameters": [
          {
            "in": "query",
            "name": "walletId",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Optional wallet scope."
          }
        ],
        "responses": {
          "200": {
            "description": "Runtime status.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WhaleStatusResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "Wallet not accessible.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      },
      "post": {
        "tags": ["Whale Service"],
        "summary": "Update whale runtime heartbeat fields",
        "operationId": "updateWhaleRuntimeStatus",
        "security": [
          {
            "WhaleServiceSecret": []
          },
          {
            "ServiceBearerSecret": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "websocketConnected": {
                    "type": "boolean"
                  },
                  "pollingActive": {
                    "type": "boolean"
                  },
                  "lastError": {
                    "oneOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "lastTradeAt": {
                    "oneOf": [
                      {
                        "type": "string",
                        "format": "date-time"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Runtime fields updated.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["success", "runtime"],
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "runtime": {
                      "type": "object",
                      "additionalProperties": true
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/whale/trade": {
      "post": {
        "tags": ["Deprecated"],
        "summary": "Deprecated endpoint",
        "operationId": "deprecatedWhaleTrade",
        "deprecated": true,
        "responses": {
          "410": {
            "description": "Endpoint permanently deprecated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/whale/webhook": {
      "post": {
        "tags": ["Webhooks"],
        "summary": "Ingest Alchemy ADDRESS_ACTIVITY webhook",
        "operationId": "ingestAlchemyWebhook",
        "description": "Validates `x-alchemy-signature` against the raw request body and\nacknowledges quickly. Heavy processing is deferred to background tasks.\n",
        "security": [
          {
            "AlchemyWebhookSignature": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AlchemyWebhookPayload"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Accepted and queued for background processing.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["ok", "received"],
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "received": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid JSON/payload shape.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Signature validation failed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "description": "Missing server signing key or internal failure.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/whale/webhook/events": {
      "get": {
        "tags": ["Webhooks"],
        "summary": "List or fetch captured webhook events",
        "operationId": "listWebhookEvents",
        "description": "Service-auth is always allowed.\n\nSession-auth access is only allowed outside production.\n",
        "security": [
          {
            "WhaleServiceSecret": []
          },
          {
            "ServiceBearerSecret": []
          },
          {
            "SessionCookie": []
          }
        ],
        "parameters": [
          {
            "in": "query",
            "name": "id",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Fetch a single event by ID."
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "in": "query",
            "name": "includeRaw",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            },
            "description": "Include `raw_body` in single-event response."
          },
          {
            "in": "query",
            "name": "before",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Return events with `received_at` < `before`."
          }
        ],
        "responses": {
          "200": {
            "description": "Event payload(s).",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "required": ["event"],
                      "properties": {
                        "event": {
                          "$ref": "#/components/schemas/WebhookEvent"
                        }
                      }
                    },
                    {
                      "type": "object",
                      "required": ["events", "limit"],
                      "properties": {
                        "events": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/WebhookEvent"
                          }
                        },
                        "limit": {
                          "type": "integer"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "Session-auth access blocked in production.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Event ID not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/whale/webhook/replay": {
      "post": {
        "tags": ["Webhooks"],
        "summary": "Replay captured webhook events through ingestion endpoint",
        "operationId": "replayWebhookEvents",
        "description": "Service-auth is always allowed.\n\nSession-auth access is only allowed outside production.\n",
        "security": [
          {
            "WhaleServiceSecret": []
          },
          {
            "ServiceBearerSecret": []
          },
          {
            "SessionCookie": []
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "eventId": {
                    "type": "string",
                    "description": "Replay one specific event."
                  },
                  "limit": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 20,
                    "default": 1
                  },
                  "dryRun": {
                    "type": "boolean",
                    "default": false
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Replay summary.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookReplayResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "Session-auth access blocked in production.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Event not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "SessionCookie": {
        "type": "apiKey",
        "in": "cookie",
        "name": "sb-access-token",
        "description": "Supabase-managed authenticated browser session cookie.\nCookie names can vary by environment/project.\n"
      },
      "WhaleServiceSecret": {
        "type": "apiKey",
        "in": "header",
        "name": "x-whale-service-secret",
        "description": "Shared secret via `WHALE_SERVICE_SHARED_SECRET`."
      },
      "ServiceBearerSecret": {
        "type": "http",
        "scheme": "bearer",
        "description": "Same `WHALE_SERVICE_SHARED_SECRET` value, sent as\n`Authorization: Bearer <secret>`.\n"
      },
      "ApiKeyBearer": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "APIKey",
        "description": "User-scoped Agent API Key generated from `/api/keys/generate`; the same ptk_ key can be used for MCP server access when scopes allow.\nRequired for `/api/public/whale-signals` and `/api/public/copy-signals`.\n"
      },
      "UserBearer": {
        "type": "http",
        "scheme": "bearer",
        "description": "Supabase JWT bearer token accepted by user-scoped routes using\n`getAuthenticatedUser`.\n"
      },
      "JwtBearer": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "Supabase JWT bearer token. Required on endpoints that strictly verify\nJWT identity (for example `/api/keys/generate`).\n"
      },
      "AlchemyWebhookSignature": {
        "type": "apiKey",
        "in": "header",
        "name": "x-alchemy-signature",
        "description": "HMAC-SHA256 signature of raw body using `ALCHEMY_WEBHOOK_SIGNING_KEY`."
      },
      "ScanSecret": {
        "type": "apiKey",
        "in": "header",
        "name": "x-scan-secret",
        "description": "Secret matching `SCAN_SECRET`."
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Invalid request.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "Missing/invalid auth.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "TierUpgradeRequired": {
        "description": "Authenticated user does not meet required tier.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/TierUpgradeError"
            }
          }
        }
      },
      "InternalError": {
        "description": "Internal server error.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "TooManyRequests": {
        "description": "Rate limit exceeded.",
        "headers": {
          "Retry-After": {
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Seconds until the caller can retry."
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      }
    },
    "schemas": {
      "ErrorResponse": {
        "type": "object",
        "required": ["error"],
        "properties": {
          "error": {
            "type": "string"
          }
        }
      },
      "SuccessResponse": {
        "type": "object",
        "required": ["success"],
        "properties": {
          "success": {
            "type": "boolean"
          }
        }
      },
      "TierUpgradeError": {
        "type": "object",
        "required": [
          "error",
          "code",
          "requiredTier",
          "currentTier",
          "upgradeUrl"
        ],
        "properties": {
          "error": {
            "type": "string"
          },
          "code": {
            "type": "string",
            "const": "TIER_UPGRADE_REQUIRED"
          },
          "requiredTier": {
            "type": "string",
            "enum": ["pro", "elite"]
          },
          "currentTier": {
            "type": "string",
            "enum": ["free", "pro", "elite"]
          },
          "upgradeUrl": {
            "type": "string",
            "example": "/pricing"
          }
        }
      },
      "WebhookLimitReachedError": {
        "type": "object",
        "required": ["error", "code", "tier", "limit", "upgradeUrl"],
        "properties": {
          "error": {
            "type": "string"
          },
          "code": {
            "type": "string",
            "const": "WEBHOOK_LIMIT_REACHED"
          },
          "tier": {
            "type": "string",
            "enum": ["pro", "elite"]
          },
          "limit": {
            "type": "integer"
          },
          "upgradeUrl": {
            "type": "string",
            "example": "/pricing"
          }
        }
      },
      "WebhookCreateForbiddenError": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/TierUpgradeError"
          },
          {
            "$ref": "#/components/schemas/WebhookLimitReachedError"
          }
        ]
      },
      "RefreshTokenRequest": {
        "type": "object",
        "required": ["refresh_token"],
        "properties": {
          "refresh_token": {
            "type": "string",
            "minLength": 1
          }
        }
      },
      "AuthTokensResponse": {
        "type": "object",
        "required": [
          "access_token",
          "refresh_token",
          "token_type",
          "expires_in"
        ],
        "properties": {
          "access_token": {
            "type": "string"
          },
          "refresh_token": {
            "type": "string"
          },
          "token_type": {
            "type": "string",
            "example": "bearer"
          },
          "expires_in": {
            "type": "integer",
            "example": 3600
          }
        }
      },
      "AuthErrorResponse": {
        "type": "object",
        "required": ["error"],
        "properties": {
          "error": {
            "type": "string"
          },
          "code": {
            "type": "string"
          }
        }
      },
      "ApiKeyRecord": {
        "type": "object",
        "required": ["id", "nickname", "isActive", "createdAt"],
        "properties": {
          "id": {
            "type": "string"
          },
          "nickname": {
            "type": "string",
            "nullable": true
          },
          "isActive": {
            "type": "boolean",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "lastUsedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "maskedKey": {
            "type": "string",
            "nullable": true
          },
          "keyPurpose": {
            "type": "string",
            "enum": ["trading", "personal"],
            "nullable": true
          },
          "scopes": {
            "type": "array",
            "nullable": true,
            "items": {
              "type": "string"
            }
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "ApiKeysListResponse": {
        "type": "object",
        "required": ["keys"],
        "properties": {
          "keys": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApiKeyRecord"
            }
          }
        }
      },
      "ApiKeyGenerateResponse": {
        "type": "object",
        "required": ["api_key", "key"],
        "properties": {
          "api_key": {
            "type": "string",
            "description": "Returned only once at generation time."
          },
          "key": {
            "$ref": "#/components/schemas/ApiKeyRecord"
          }
        }
      },
      "AccountSummaryResponse": {
        "type": "object",
        "required": [
          "id",
          "email",
          "tier",
          "trialEndsAt",
          "onboardingCompleted",
          "polymarketWalletLinked",
          "apiKeysCount",
          "walletsCount",
          "createdAt"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "email": {
            "type": "string",
            "nullable": true
          },
          "tier": {
            "type": "string",
            "enum": ["free", "pro", "elite"]
          },
          "trialEndsAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "onboardingCompleted": {
            "type": "boolean"
          },
          "polymarketWalletLinked": {
            "type": "boolean"
          },
          "apiKeysCount": {
            "type": "integer"
          },
          "walletsCount": {
            "type": "integer"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "AccountStatsResponse": {
        "type": "object",
        "required": [
          "totalMockTrades",
          "totalMockPnL",
          "mockWinRate",
          "totalRealTrades",
          "totalRealPnL",
          "realWinRate",
          "whalesTracked",
          "anomaliesDetected",
          "activeWallets"
        ],
        "properties": {
          "totalMockTrades": {
            "type": "integer"
          },
          "totalMockPnL": {
            "type": "number"
          },
          "mockWinRate": {
            "type": "number"
          },
          "totalRealTrades": {
            "type": "integer"
          },
          "totalRealPnL": {
            "type": "number"
          },
          "realWinRate": {
            "type": "number"
          },
          "whalesTracked": {
            "type": "integer"
          },
          "anomaliesDetected": {
            "type": "integer"
          },
          "activeWallets": {
            "type": "integer"
          }
        }
      },
      "MarketSummary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true
          },
          "conditionId": {
            "type": "string",
            "nullable": true
          },
          "slug": {
            "type": "string",
            "nullable": true
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "category": {
            "type": "string",
            "nullable": true
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "status": {
            "type": "string",
            "enum": ["open", "resolved"]
          },
          "volume": {
            "type": "number"
          },
          "liquidity": {
            "type": "number"
          },
          "endDate": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "active": {
            "type": "boolean"
          },
          "closed": {
            "type": "boolean"
          }
        }
      },
      "MarketsResponse": {
        "type": "object",
        "required": ["markets", "count", "filters"],
        "properties": {
          "markets": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MarketSummary"
            }
          },
          "count": {
            "type": "integer"
          },
          "filters": {
            "type": "object",
            "required": ["query", "category", "status", "sort", "limit"],
            "properties": {
              "query": {
                "type": "string",
                "nullable": true
              },
              "category": {
                "type": "string",
                "nullable": true
              },
              "status": {
                "type": "string",
                "enum": ["open", "resolved"]
              },
              "sort": {
                "type": "string",
                "enum": ["volume", "newest", "ending-soon"]
              },
              "limit": {
                "type": "integer"
              }
            }
          }
        }
      },
      "WhaleBacktestCoverage": {
        "type": "object",
        "description": "Candidate-level whale backtest source coverage. Derived from resolved_receipts joined to anomaly_logs.wallet, the same retained signal source used by whale backtests.",
        "required": [
          "backtestable",
          "trackedSignalCount",
          "trackedSignalCount90d",
          "trackedSignalCount180d",
          "backtestSource",
          "backtestWindowDays",
          "coverageTruncated"
        ],
        "properties": {
          "backtestable": {
            "type": "boolean",
            "description": "True when the wallet has at least one retained resolved signal in the max whale-backtest window."
          },
          "trackedSignalCount": {
            "type": "integer",
            "description": "Retained resolved signal count in the max whale-backtest window."
          },
          "trackedSignalCount90d": {
            "type": "integer",
            "description": "Retained resolved signal count in the last 90 days."
          },
          "trackedSignalCount180d": {
            "type": "integer",
            "description": "Retained resolved signal count in the last 180 days."
          },
          "backtestSource": {
            "type": "string",
            "enum": ["resolved_receipts.anomaly_logs"]
          },
          "backtestWindowDays": {
            "type": "integer",
            "enum": [365]
          },
          "coverageTruncated": {
            "type": "boolean"
          }
        }
      },
      "WhaleEdgeMetadata": {
        "type": "object",
        "description": "Realized post-cost whale edge from resolved receipts over 90d/180d windows.",
        "properties": {
          "dataAvailable": {
            "type": "boolean"
          },
          "coverageSource": {
            "type": "string",
            "enum": ["resolved_receipts.anomaly_logs"]
          },
          "sampleCount": {
            "type": "integer"
          },
          "sampleCount90d": {
            "type": "integer"
          },
          "sampleCount180d": {
            "type": "integer"
          },
          "roiPct90d": {
            "type": "number",
            "nullable": true
          },
          "roiPct180d": {
            "type": "number",
            "nullable": true
          },
          "netPnlUsd90d": {
            "type": "number"
          },
          "netPnlUsd180d": {
            "type": "number"
          },
          "capitalUsd90d": {
            "type": "number"
          },
          "capitalUsd180d": {
            "type": "number"
          },
          "baselineRoiPct": {
            "type": "number",
            "enum": [0]
          },
          "beatsBaseline90d": {
            "type": "boolean",
            "nullable": true
          },
          "beatsBaseline180d": {
            "type": "boolean",
            "nullable": true
          },
          "edgeWindowDays": {
            "type": "integer",
            "enum": [180]
          },
          "coverageTruncated": {
            "type": "boolean"
          }
        }
      },
      "LeaderboardEntry": {
        "type": "object",
        "required": [
          "rank",
          "wallet",
          "name",
          "pnl",
          "volume",
          "followScore",
          "periodPnl",
          "weeklyRank",
          "monthlyRank",
          "alltimeRank",
          "profileImage",
          "bio"
        ],
        "properties": {
          "rank": {
            "type": "integer"
          },
          "wallet": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "pnl": {
            "type": "number"
          },
          "volume": {
            "type": "number"
          },
          "followScore": {
            "type": "number"
          },
          "backtestCoverage": {
            "$ref": "#/components/schemas/WhaleBacktestCoverage"
          },
          "whaleEdge": {
            "$ref": "#/components/schemas/WhaleEdgeMetadata"
          },
          "periodPnl": {
            "type": "number"
          },
          "weeklyRank": {
            "type": "integer",
            "nullable": true
          },
          "monthlyRank": {
            "type": "integer",
            "nullable": true
          },
          "alltimeRank": {
            "type": "integer",
            "nullable": true
          },
          "profileImage": {
            "type": "string"
          },
          "bio": {
            "type": "string"
          }
        }
      },
      "LeaderboardResponse": {
        "type": "object",
        "required": [
          "period",
          "leaderboard",
          "total",
          "limit",
          "offset",
          "summary",
          "me"
        ],
        "properties": {
          "period": {
            "type": "string",
            "enum": ["weekly", "monthly", "all-time"]
          },
          "leaderboard": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LeaderboardEntry"
            }
          },
          "total": {
            "type": "integer"
          },
          "limit": {
            "type": "integer"
          },
          "offset": {
            "type": "integer"
          },
          "summary": {
            "type": "object",
            "additionalProperties": true
          },
          "me": {
            "type": "object",
            "required": ["wallet", "rank", "entry"],
            "properties": {
              "wallet": {
                "type": "string",
                "nullable": true
              },
              "rank": {
                "type": "integer",
                "nullable": true
              },
              "entry": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/LeaderboardEntry"
                  }
                ],
                "nullable": true
              }
            }
          }
        }
      },
      "TradeListItem": {
        "type": "object",
        "required": [
          "id",
          "type",
          "walletId",
          "conditionId",
          "marketTitle",
          "side",
          "outcome",
          "status",
          "amount",
          "price",
          "pnl",
          "createdAt",
          "closedAt",
          "rawStatus"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "enum": ["mock", "real"]
          },
          "walletId": {
            "type": "string",
            "nullable": true
          },
          "conditionId": {
            "type": "string",
            "nullable": true
          },
          "marketTitle": {
            "type": "string",
            "nullable": true
          },
          "side": {
            "type": "string",
            "nullable": true
          },
          "outcome": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "enum": ["open", "closed"]
          },
          "amount": {
            "type": "number",
            "nullable": true
          },
          "price": {
            "type": "number",
            "nullable": true
          },
          "pnl": {
            "type": "number",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "closedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "rawStatus": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "TradesResponse": {
        "type": "object",
        "required": [
          "trades",
          "pagination",
          "filters",
          "tier",
          "historyDepthDays"
        ],
        "properties": {
          "trades": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TradeListItem"
            }
          },
          "pagination": {
            "type": "object",
            "required": ["limit", "offset", "total", "hasMore"],
            "properties": {
              "limit": {
                "type": "integer"
              },
              "offset": {
                "type": "integer"
              },
              "total": {
                "type": "integer"
              },
              "hasMore": {
                "type": "boolean"
              }
            }
          },
          "filters": {
            "type": "object",
            "required": ["type", "status", "walletId", "sort"],
            "properties": {
              "type": {
                "type": "string",
                "enum": ["mock", "real", "all"]
              },
              "status": {
                "type": "string",
                "enum": ["open", "closed", "all"]
              },
              "walletId": {
                "type": "string",
                "nullable": true
              },
              "sort": {
                "type": "string",
                "enum": ["newest", "oldest"]
              }
            }
          },
          "tier": {
            "type": "string",
            "enum": ["free", "pro", "elite"]
          },
          "historyDepthDays": {
            "type": "integer",
            "nullable": true
          }
        }
      },
      "AnomalyListItem": {
        "type": "object",
        "required": [
          "id",
          "market_title",
          "market_slug",
          "market_url",
          "anomaly_type",
          "severity",
          "score",
          "side",
          "outcome",
          "bet_recommendation",
          "detected_at"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "market_title": {
            "type": "string",
            "nullable": true
          },
          "market_slug": {
            "type": "string",
            "nullable": true
          },
          "market_url": {
            "type": "string",
            "nullable": true
          },
          "anomaly_type": {
            "type": "string",
            "nullable": true
          },
          "severity": {
            "type": "string",
            "nullable": true
          },
          "score": {
            "type": "number"
          },
          "side": {
            "type": "string",
            "nullable": true
          },
          "outcome": {
            "type": "string",
            "nullable": true
          },
          "bet_recommendation": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true
          },
          "detected_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "AnomalyListResponse": {
        "type": "array",
        "items": {
          "$ref": "#/components/schemas/AnomalyListItem"
        }
      },
      "AnomalyDetail": {
        "allOf": [
          {
            "$ref": "#/components/schemas/AnomalyListItem"
          },
          {
            "type": "object",
            "required": [
              "condition_id",
              "trader_wallet",
              "trader_name",
              "cash_value",
              "price",
              "shares",
              "reasons",
              "context",
              "user_profile",
              "days_to_resolution",
              "created_at"
            ],
            "properties": {
              "condition_id": {
                "type": "string",
                "nullable": true
              },
              "trader_wallet": {
                "type": "string",
                "nullable": true
              },
              "trader_name": {
                "type": "string",
                "nullable": true
              },
              "cash_value": {
                "type": "number",
                "nullable": true
              },
              "price": {
                "type": "number",
                "nullable": true
              },
              "shares": {
                "type": "number",
                "nullable": true
              },
              "reasons": {
                "type": "array",
                "items": {
                  "oneOf": [
                    {
                      "type": "string"
                    },
                    {
                      "type": "object",
                      "additionalProperties": true
                    }
                  ]
                }
              },
              "context": {
                "type": "object",
                "nullable": true,
                "additionalProperties": true
              },
              "user_profile": {
                "type": "object",
                "nullable": true,
                "additionalProperties": true
              },
              "days_to_resolution": {
                "type": "number",
                "nullable": true
              },
              "created_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              }
            }
          }
        ]
      },
      "AnomalyPerformanceCohort": {
        "type": "object",
        "required": [
          "cohort",
          "flagged",
          "resolved",
          "wins",
          "losses",
          "voids",
          "winRate",
          "avgReturnPct",
          "totalPnlUsd",
          "equalDollarPnlPer100"
        ],
        "properties": {
          "cohort": {
            "type": "string",
            "description": "Bucket key derived from `group_by`. For `day`: `YYYY-MM-DD`. For\n`month`: `YYYY-MM`. For `anomaly_type`/`severity`: the underlying\nenum value (or `\"UNKNOWN\"` when null). For `all`: literally `\"all\"`.\n"
          },
          "flagged": {
            "type": "integer",
            "description": "Anomalies emitted by the detector during the cohort."
          },
          "resolved": {
            "type": "integer",
            "description": "Flagged anomalies whose underlying market has since resolved."
          },
          "wins": {
            "type": "integer"
          },
          "losses": {
            "type": "integer"
          },
          "voids": {
            "type": "integer",
            "description": "Resolved rows with no decidable outcome (e.g. market voided)."
          },
          "winRate": {
            "type": "number",
            "nullable": true,
            "description": "`wins / (wins + losses)`. `null` when no decided rows exist in the\ncohort.\n"
          },
          "avgReturnPct": {
            "type": "number",
            "nullable": true,
            "description": "Mean per-anomaly return across decided rows, expressed as a decimal\nfraction (e.g. `0.12` = +12%). `null` when no decided rows exist.\n"
          },
          "totalPnlUsd": {
            "type": "number",
            "description": "Aggregate realized P&L in USD across the cohort."
          },
          "equalDollarPnlPer100": {
            "type": "number",
            "description": "Equal-dollar simulation: $100 flat-staked on every decided anomaly\nin the cohort, expressed as total dollars of P&L.\n"
          }
        }
      },
      "AnomalyPerformanceResponse": {
        "type": "object",
        "required": [
          "window",
          "totals",
          "series",
          "coverage",
          "coverageThreshold",
          "headlineReliable"
        ],
        "properties": {
          "window": {
            "type": "object",
            "required": ["since", "until"],
            "properties": {
              "since": {
                "type": "string",
                "format": "date-time"
              },
              "until": {
                "type": "string",
                "format": "date-time"
              }
            }
          },
          "totals": {
            "$ref": "#/components/schemas/AnomalyPerformanceCohort"
          },
          "series": {
            "type": "array",
            "description": "Cohort rows sorted ascending by `cohort`.",
            "items": {
              "$ref": "#/components/schemas/AnomalyPerformanceCohort"
            }
          },
          "coverage": {
            "type": "number",
            "description": "`totals.resolved / totals.flagged` for the window (0–1)."
          },
          "coverageThreshold": {
            "type": "number",
            "description": "Minimum `coverage` at which headline metrics should be surfaced\nwithout a caveat. Currently `0.5`.\n"
          },
          "headlineReliable": {
            "type": "boolean",
            "description": "`coverage >= coverageThreshold`."
          }
        }
      },
      "ScanTriggerResponse": {
        "type": "object",
        "required": [
          "success",
          "tier",
          "count",
          "timestamp",
          "tradesAnalyzed",
          "anomalies"
        ],
        "properties": {
          "success": {
            "type": "boolean"
          },
          "tier": {
            "type": "string",
            "enum": ["pro", "elite"]
          },
          "count": {
            "type": "integer"
          },
          "timestamp": {
            "type": "string",
            "format": "date-time"
          },
          "tradesAnalyzed": {
            "type": "integer"
          },
          "anomalies": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AnomalyListItem"
            }
          }
        }
      },
      "TradeExecuteRequest": {
        "type": "object",
        "required": ["conditionId", "side", "amount", "regionCertification"],
        "properties": {
          "conditionId": {
            "type": "string"
          },
          "side": {
            "type": "string",
            "enum": ["YES", "NO"]
          },
          "amount": {
            "type": "number",
            "exclusiveMinimum": 0
          },
          "regionCertification": {
            "type": "boolean",
            "enum": [true],
            "description": "Must be true to certify the caller is permitted to trade in their jurisdiction and is not in a restricted or prohibited Polymarket trading region."
          },
          "limitPrice": {
            "type": "number",
            "minimum": 0,
            "maximum": 1,
            "nullable": true
          },
          "idempotencyKey": {
            "type": "string",
            "maxLength": 256,
            "nullable": true
          }
        }
      },
      "TradeExecuteResponse": {
        "type": "object",
        "required": ["orderId", "status", "fillPrice", "fillAmount"],
        "properties": {
          "orderId": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "enum": ["pending", "partial", "filled", "cancelled", "failed"]
          },
          "fillPrice": {
            "type": "number",
            "nullable": true
          },
          "fillAmount": {
            "type": "number",
            "nullable": true
          },
          "error": {
            "type": "string"
          },
          "warning": {
            "type": "string"
          },
          "idempotencyReused": {
            "type": "boolean"
          }
        }
      },
      "TradeErrorResponse": {
        "type": "object",
        "required": ["error"],
        "properties": {
          "error": {
            "type": "string"
          },
          "code": {
            "type": "string"
          }
        },
        "additionalProperties": true
      },
      "TradeHistoryResponse": {
        "type": "object",
        "required": ["trades", "limit", "offset", "status"],
        "properties": {
          "trades": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "limit": {
            "type": "integer"
          },
          "offset": {
            "type": "integer"
          },
          "status": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "TradeOrder": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "market": {
            "type": "string",
            "nullable": true
          },
          "assetId": {
            "type": "string",
            "nullable": true
          },
          "outcome": {
            "type": "string",
            "nullable": true
          },
          "side": {
            "type": "string",
            "nullable": true
          },
          "price": {
            "type": "number",
            "nullable": true
          },
          "originalSize": {
            "type": "number",
            "nullable": true
          },
          "sizeMatched": {
            "type": "number",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "expiration": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "TradeOrdersResponse": {
        "type": "object",
        "required": ["orders"],
        "properties": {
          "orders": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TradeOrder"
            }
          }
        }
      },
      "TradeCancelResponse": {
        "type": "object",
        "required": ["orderId", "status", "result"],
        "properties": {
          "orderId": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "const": "cancelled"
          },
          "result": {
            "type": "object",
            "additionalProperties": true
          }
        }
      },
      "ClobPriceResponse": {
        "type": "object",
        "required": ["tokenId", "price", "bid", "ask", "spread", "timestamp"],
        "properties": {
          "tokenId": {
            "type": "string"
          },
          "price": {
            "type": "number"
          },
          "bid": {
            "type": "number",
            "nullable": true
          },
          "ask": {
            "type": "number",
            "nullable": true
          },
          "spread": {
            "type": "number",
            "nullable": true
          },
          "timestamp": {
            "type": "integer"
          }
        }
      },
      "Wallet": {
        "type": "object",
        "description": "Normalized wallet object returned by `/api/wallets`.\n\nAdditional fields may be present as schema evolves.\n",
        "required": [
          "id",
          "userId",
          "name",
          "currentBalance",
          "initialBalance",
          "isActive"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "userId": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "strategy": {
            "type": "string"
          },
          "color": {
            "type": "string"
          },
          "currentBalance": {
            "type": "number"
          },
          "initialBalance": {
            "type": "number"
          },
          "totalDeposited": {
            "type": "number"
          },
          "totalWithdrawn": {
            "type": "number"
          },
          "totalTrades": {
            "type": "number"
          },
          "winCount": {
            "type": "number"
          },
          "lossCount": {
            "type": "number"
          },
          "realizedPnl": {
            "type": "number"
          },
          "unrealizedPnl": {
            "type": "number"
          },
          "isActive": {
            "type": "boolean"
          },
          "allocationPct": {
            "type": "number"
          },
          "maxDailyTrades": {
            "type": "number"
          },
          "dailyPnl": {
            "type": "number"
          },
          "tradesToday": {
            "type": "number"
          },
          "openPositions": {
            "type": "number"
          },
          "whaleCount": {
            "type": "number"
          },
          "assignedWhales": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": true
      },
      "CreateWalletRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "initialBalance": {
            "type": "number"
          },
          "initial_balance": {
            "type": "number"
          },
          "strategy": {
            "type": "string"
          },
          "color": {
            "type": "string"
          },
          "userId": {
            "type": "string"
          },
          "user_id": {
            "type": "string"
          }
        },
        "additionalProperties": false
      },
      "RosterAssignment": {
        "type": "object",
        "required": [
          "id",
          "address",
          "name",
          "wallet_id",
          "walletId",
          "active",
          "added_at"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "address": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "wallet_id": {
            "type": "string"
          },
          "walletId": {
            "type": "string"
          },
          "active": {
            "type": "boolean"
          },
          "added_at": {
            "type": "string",
            "format": "date-time"
          },
          "deactivated_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "deactivation_reason": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "WhaleRuntimeConfig": {
        "type": "object",
        "properties": {
          "relativeSizeMultiplier": {
            "type": "number"
          },
          "userHistoryMultiplier": {
            "type": "number"
          },
          "detectionMinTradeSize": {
            "type": "number"
          },
          "largeTradeThreshold": {
            "type": "number"
          },
          "whaleTradeThreshold": {
            "type": "number"
          },
          "maxPerTrade": {
            "type": "number"
          },
          "hourlyLossLimit": {
            "type": "number"
          },
          "dailyLossLimit": {
            "type": "number"
          },
          "consecutiveLossMax": {
            "type": "integer"
          },
          "maxSlippage": {
            "type": "number"
          },
          "staleSignalMs": {
            "type": "integer"
          },
          "balanceFloor": {
            "type": "number"
          },
          "maxOpenPositions": {
            "type": "integer"
          },
          "maxDailyTrades": {
            "type": "integer"
          },
          "executionMode": {
            "type": "string",
            "enum": ["mock", "real"]
          },
          "copyPercentage": {
            "type": "number"
          },
          "maxPositionPct": {
            "type": "number"
          },
          "minTradeSize": {
            "type": "number"
          },
          "kellyFraction": {
            "type": "number"
          },
          "pollIntervalMs": {
            "type": "integer"
          },
          "websocketEnabled": {
            "type": "boolean"
          },
          "autoDiscoveryEnabled": {
            "type": "boolean"
          },
          "runtime": {
            "type": "object",
            "properties": {
              "lastHeartbeatAt": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              },
              "websocketConnected": {
                "type": "boolean"
              },
              "pollingActive": {
                "type": "boolean"
              },
              "lastError": {
                "type": "string",
                "nullable": true
              },
              "lastTradeAt": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              }
            },
            "additionalProperties": true
          }
        },
        "additionalProperties": true
      },
      "WhaleStatusResponse": {
        "type": "object",
        "required": ["webhook", "circuitBreaker", "wallet", "stats"],
        "properties": {
          "webhook": {
            "type": "object",
            "required": ["connected", "websocketConnected", "pollingActive"],
            "properties": {
              "connected": {
                "type": "boolean"
              },
              "lastHeartbeatAt": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              },
              "websocketConnected": {
                "type": "boolean"
              },
              "pollingActive": {
                "type": "boolean"
              },
              "lastError": {
                "type": "string",
                "nullable": true
              },
              "lastTradeAt": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              }
            },
            "additionalProperties": true
          },
          "circuitBreaker": {
            "type": "object",
            "required": ["status", "config"],
            "properties": {
              "id": {
                "type": "string",
                "nullable": true
              },
              "status": {
                "type": "string"
              },
              "hourlyPnl": {
                "type": "number"
              },
              "dailyPnl": {
                "type": "number"
              },
              "consecutiveLosses": {
                "type": "number"
              },
              "lastTradeAt": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              },
              "lastBreakerTrip": {
                "type": "string",
                "nullable": true
              },
              "lastBreakerTripAt": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              },
              "config": {
                "$ref": "#/components/schemas/WhaleRuntimeConfig"
              }
            },
            "additionalProperties": true
          },
          "wallet": {
            "type": "object",
            "required": [
              "id",
              "name",
              "balance",
              "initialBalance",
              "openPositions",
              "dailyTrades"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "balance": {
                "type": "number"
              },
              "initialBalance": {
                "type": "number"
              },
              "openPositions": {
                "type": "number",
                "description": "Legacy aggregate risk open-position counter. Prefer riskOpenPositions, mockOpenPositions, or realOpenPositions for explicit semantics."
              },
              "riskOpenPositions": {
                "type": "number",
                "description": "Aggregate open positions enforced by risk checks, including mock and real positions."
              },
              "mockOpenPositions": {
                "type": "number",
                "description": "Open mock-trade positions for the requested mock wallet."
              },
              "realOpenPositions": {
                "type": "number",
                "description": "Inferred open real-trade positions included in the aggregate risk counter."
              },
              "dailyTrades": {
                "type": "number"
              }
            },
            "additionalProperties": true
          },
          "openPositionBreakdown": {
            "type": "object",
            "required": [
              "riskOpenPositions",
              "mockOpenPositions",
              "realOpenPositions"
            ],
            "properties": {
              "riskOpenPositions": {
                "type": "number"
              },
              "mockOpenPositions": {
                "type": "number"
              },
              "realOpenPositions": {
                "type": "number"
              },
              "legacyWalletOpenPositionsSource": {
                "type": "string"
              },
              "mockOpenPositionsSource": {
                "type": "string"
              }
            },
            "additionalProperties": true
          },
          "stats": {
            "type": "object",
            "required": [
              "hourlyPnl",
              "dailyPnl",
              "consecutiveLosses",
              "mirroredTrades24h",
              "skippedSignals24h",
              "lastActivityAt"
            ],
            "properties": {
              "hourlyPnl": {
                "type": "number"
              },
              "dailyPnl": {
                "type": "number"
              },
              "consecutiveLosses": {
                "type": "number"
              },
              "mirroredTrades24h": {
                "type": "number"
              },
              "skippedSignals24h": {
                "type": "number"
              },
              "lastActivityAt": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              }
            },
            "additionalProperties": true
          },
          "walletStats": {
            "type": "object",
            "additionalProperties": true
          }
        }
      },
      "WhaleConfigResponse": {
        "type": "object",
        "required": ["status", "config", "walletId", "source"],
        "properties": {
          "status": {
            "type": "string"
          },
          "config": {
            "$ref": "#/components/schemas/WhaleRuntimeConfig"
          },
          "walletId": {
            "type": "string"
          },
          "source": {
            "type": "string",
            "enum": ["wallet", "legacy"]
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "WhaleConfigPatchRequest": {
        "type": "object",
        "properties": {
          "walletId": {
            "type": "string"
          },
          "executionMode": {
            "type": "string",
            "enum": ["mock", "real"]
          },
          "relativeSizeMultiplier": {
            "type": "number"
          },
          "userHistoryMultiplier": {
            "type": "number"
          },
          "detectionMinTradeSize": {
            "type": "number"
          },
          "largeTradeThreshold": {
            "type": "number"
          },
          "whaleTradeThreshold": {
            "type": "number"
          },
          "maxPerTrade": {
            "type": "number"
          },
          "hourlyLossLimit": {
            "type": "number"
          },
          "dailyLossLimit": {
            "type": "number"
          },
          "maxSlippage": {
            "type": "number"
          },
          "balanceFloor": {
            "type": "number"
          },
          "copyPercentage": {
            "type": "number"
          },
          "maxPositionPct": {
            "type": "number"
          },
          "minTradeSize": {
            "type": "number"
          },
          "kellyFraction": {
            "type": "number"
          },
          "consecutiveLossMax": {
            "type": "integer"
          },
          "staleSignalMs": {
            "type": "integer"
          },
          "maxOpenPositions": {
            "type": "integer"
          },
          "maxDailyTrades": {
            "type": "integer"
          }
        },
        "additionalProperties": false
      },
      "WhaleActivityRecord": {
        "type": "object",
        "description": "Whale activity row with optional decision traces.",
        "properties": {
          "id": {
            "type": "string"
          },
          "mock_wallet_id": {
            "type": "string",
            "nullable": true
          },
          "wallet_address": {
            "type": "string",
            "nullable": true
          },
          "wallet_alias": {
            "type": "string",
            "nullable": true
          },
          "market_slug": {
            "type": "string",
            "nullable": true
          },
          "market_title": {
            "type": "string",
            "nullable": true
          },
          "condition_id": {
            "type": "string",
            "nullable": true
          },
          "side": {
            "type": "string",
            "nullable": true
          },
          "outcome": {
            "type": "string",
            "nullable": true
          },
          "size": {
            "type": "number",
            "nullable": true
          },
          "price": {
            "type": "number",
            "nullable": true
          },
          "detected_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "signal_type": {
            "type": "string",
            "nullable": true
          },
          "mirrored": {
            "type": "boolean",
            "nullable": true
          },
          "mirror_trade_id": {
            "type": "string",
            "nullable": true
          },
          "skip_reason": {
            "type": "string",
            "nullable": true
          },
          "meta": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true
          },
          "decision_traces": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          }
        },
        "additionalProperties": true
      },
      "PublicWhaleSignal": {
        "type": "object",
        "required": [
          "id",
          "trader",
          "market",
          "side",
          "size",
          "timestamp",
          "signalType",
          "confidence",
          "signalMetadata"
        ],
        "properties": {
          "id": {
            "type": "string",
            "nullable": true
          },
          "trader": {
            "type": "object",
            "required": ["address", "alias"],
            "properties": {
              "address": {
                "type": "string",
                "nullable": true
              },
              "alias": {
                "type": "string",
                "nullable": true
              }
            }
          },
          "market": {
            "type": "object",
            "required": ["conditionId", "slug", "title", "outcome"],
            "properties": {
              "conditionId": {
                "type": "string",
                "nullable": true
              },
              "slug": {
                "type": "string",
                "nullable": true
              },
              "title": {
                "type": "string",
                "nullable": true
              },
              "outcome": {
                "type": "string",
                "nullable": true
              }
            }
          },
          "side": {
            "type": "string",
            "nullable": true
          },
          "size": {
            "type": "number",
            "nullable": true
          },
          "price": {
            "type": "number",
            "nullable": true
          },
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "signalType": {
            "type": "string",
            "nullable": true
          },
          "confidence": {
            "type": "number",
            "nullable": true
          },
          "signalMetadata": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true
          }
        }
      },
      "PublicWhaleSignalsResponse": {
        "type": "object",
        "required": ["signals", "count"],
        "properties": {
          "signals": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicWhaleSignal"
            }
          },
          "count": {
            "type": "integer"
          }
        }
      },
      "PublicCopySignal": {
        "type": "object",
        "required": [
          "id",
          "trader",
          "market",
          "side",
          "confidence",
          "timestamp",
          "execution",
          "signalMetadata"
        ],
        "properties": {
          "id": {
            "type": "string",
            "nullable": true
          },
          "trader": {
            "type": "object",
            "required": ["address", "alias"],
            "properties": {
              "address": {
                "type": "string",
                "nullable": true
              },
              "alias": {
                "type": "string",
                "nullable": true
              }
            }
          },
          "market": {
            "type": "object",
            "required": ["conditionId", "slug", "title", "outcome"],
            "properties": {
              "conditionId": {
                "type": "string",
                "nullable": true
              },
              "slug": {
                "type": "string",
                "nullable": true
              },
              "title": {
                "type": "string",
                "nullable": true
              },
              "outcome": {
                "type": "string",
                "nullable": true
              }
            }
          },
          "side": {
            "type": "string",
            "nullable": true
          },
          "size": {
            "type": "number",
            "nullable": true
          },
          "price": {
            "type": "number",
            "nullable": true
          },
          "confidence": {
            "type": "number",
            "nullable": true
          },
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "signalType": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "enum": ["detected", "executed", "skipped"]
          },
          "execution": {
            "type": "object",
            "required": ["mirrored", "mirrorTradeId", "skipReason"],
            "properties": {
              "mirrored": {
                "type": "boolean",
                "nullable": true
              },
              "mirrorTradeId": {
                "type": "string",
                "nullable": true
              },
              "skipReason": {
                "type": "string",
                "nullable": true
              }
            }
          },
          "signalMetadata": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true
          }
        }
      },
      "PublicCopySignalsResponse": {
        "type": "object",
        "required": ["signals", "count"],
        "properties": {
          "signals": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicCopySignal"
            }
          },
          "count": {
            "type": "integer"
          }
        }
      },
      "WhalePerformanceData": {
        "type": "object",
        "required": [
          "summary",
          "whales",
          "wallets",
          "roster",
          "walletName",
          "generatedAt",
          "warnings"
        ],
        "properties": {
          "summary": {
            "type": "object",
            "required": [
              "realizedPnl",
              "totalTrades",
              "closedTrades",
              "winningTrades",
              "overallWinRate",
              "walletBalance",
              "whaleCount"
            ],
            "properties": {
              "realizedPnl": {
                "type": "number"
              },
              "totalTrades": {
                "type": "number"
              },
              "closedTrades": {
                "type": "number"
              },
              "winningTrades": {
                "type": "number"
              },
              "overallWinRate": {
                "type": "number"
              },
              "walletBalance": {
                "type": "number"
              },
              "whaleCount": {
                "type": "number"
              }
            }
          },
          "whales": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "wallets": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "roster": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "walletName": {
            "type": "string",
            "nullable": true
          },
          "generatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "AlchemyWebhookPayload": {
        "type": "object",
        "properties": {
          "webhookId": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "type": {
            "type": "string"
          },
          "event": {
            "type": "object",
            "properties": {
              "network": {
                "type": "string"
              },
              "activity": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/AlchemyAddressActivity"
                }
              }
            },
            "additionalProperties": true
          }
        },
        "additionalProperties": true
      },
      "AlchemyAddressActivity": {
        "type": "object",
        "properties": {
          "fromAddress": {
            "type": "string"
          },
          "toAddress": {
            "type": "string"
          },
          "hash": {
            "type": "string"
          },
          "category": {
            "type": "string"
          },
          "asset": {
            "type": "string"
          },
          "value": {
            "oneOf": [
              {
                "type": "number"
              },
              {
                "type": "string"
              }
            ]
          },
          "rawContract": {
            "type": "object",
            "properties": {
              "address": {
                "type": "string"
              },
              "rawValue": {
                "type": "string"
              },
              "decimals": {
                "type": "integer"
              }
            },
            "additionalProperties": true
          },
          "log": {
            "type": "object",
            "properties": {
              "address": {
                "type": "string"
              }
            },
            "additionalProperties": true
          },
          "erc1155Metadata": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "tokenId": {
                  "type": "string"
                },
                "value": {
                  "oneOf": [
                    {
                      "type": "number"
                    },
                    {
                      "type": "string"
                    }
                  ]
                }
              },
              "additionalProperties": true
            }
          }
        },
        "additionalProperties": true
      },
      "WebhookEvent": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "provider": {
            "type": "string"
          },
          "external_event_id": {
            "type": "string",
            "nullable": true
          },
          "webhook_id": {
            "type": "string",
            "nullable": true
          },
          "network": {
            "type": "string",
            "nullable": true
          },
          "activity_count": {
            "type": "integer"
          },
          "replayed": {
            "type": "boolean"
          },
          "replay_source_event_id": {
            "type": "string",
            "nullable": true
          },
          "replay_count": {
            "type": "integer",
            "nullable": true
          },
          "last_replayed_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "last_replay_status": {
            "type": "string",
            "nullable": true
          },
          "received_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "raw_body": {
            "type": "string"
          }
        },
        "additionalProperties": true
      },
      "WebhookReplayResponse": {
        "type": "object",
        "required": [
          "replayed",
          "succeeded",
          "failed",
          "dryRun",
          "target",
          "results"
        ],
        "properties": {
          "replayed": {
            "type": "integer"
          },
          "succeeded": {
            "type": "integer"
          },
          "failed": {
            "type": "integer"
          },
          "dryRun": {
            "type": "boolean"
          },
          "target": {
            "type": "string"
          },
          "results": {
            "type": "array",
            "items": {
              "type": "object",
              "required": ["id", "ok", "status", "message"],
              "properties": {
                "id": {
                  "type": "string"
                },
                "ok": {
                  "type": "boolean"
                },
                "status": {
                  "type": "integer",
                  "nullable": true
                },
                "message": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "RiskProfile": {
        "type": "object",
        "required": [
          "riskTolerance",
          "preferredCategories",
          "tradeFrequency",
          "timeHorizon"
        ],
        "additionalProperties": false,
        "properties": {
          "riskTolerance": {
            "type": "string",
            "enum": ["low", "medium", "high"]
          },
          "preferredCategories": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "politics",
                "crypto",
                "sports",
                "economy",
                "technology",
                "other"
              ]
            },
            "maxItems": 5
          },
          "tradeFrequency": {
            "type": "string",
            "enum": ["low", "medium", "high"]
          },
          "timeHorizon": {
            "type": "string",
            "enum": ["short", "medium", "long"]
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "AlertPreferences": {
        "type": "object",
        "required": ["enabled", "frequency", "channels", "thresholds"],
        "properties": {
          "enabled": {
            "type": "boolean"
          },
          "frequency": {
            "type": "string",
            "enum": ["realtime", "digest_hourly"]
          },
          "channels": {
            "type": "object",
            "properties": {
              "telegram": {
                "type": "object",
                "properties": {
                  "enabled": {
                    "type": "boolean"
                  },
                  "chatId": {
                    "type": "string",
                    "nullable": true
                  }
                }
              },
              "discord": {
                "type": "object",
                "properties": {
                  "enabled": {
                    "type": "boolean"
                  },
                  "webhookUrl": {
                    "type": "string",
                    "nullable": true
                  }
                }
              },
              "email": {
                "type": "object",
                "properties": {
                  "enabled": {
                    "type": "boolean"
                  },
                  "email": {
                    "type": "string",
                    "nullable": true
                  }
                }
              }
            }
          },
          "thresholds": {
            "type": "object",
            "properties": {
              "minScore": {
                "type": "number"
              },
              "minCashValue": {
                "type": "number"
              },
              "severities": {
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": ["HIGH", "MEDIUM"]
                }
              },
              "predictiveSignals": {
                "type": "boolean"
              }
            }
          }
        }
      },
      "AlertPreferencesResponse": {
        "type": "object",
        "properties": {
          "preferences": {
            "$ref": "#/components/schemas/AlertPreferences"
          },
          "tier": {
            "type": "string"
          },
          "canConfigureAlerts": {
            "type": "boolean"
          },
          "canEnablePredictiveSignals": {
            "type": "boolean"
          },
          "upgradeRequired": {
            "type": "boolean"
          }
        }
      },
      "WebhookRegistrationRecord": {
        "type": "object",
        "required": [
          "id",
          "url",
          "filters",
          "status",
          "failureCount",
          "lastDeliveryAt",
          "createdAt",
          "updatedAt"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "filters": {
            "type": "object",
            "additionalProperties": true
          },
          "status": {
            "type": "string",
            "enum": ["active", "paused", "failed"]
          },
          "failureCount": {
            "type": "integer"
          },
          "lastDeliveryAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "WebhookDeliveryLogRecord": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "webhookId": {
            "type": "string"
          },
          "anomalyId": {
            "type": "string",
            "nullable": true
          },
          "marketKey": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string"
          },
          "responseCode": {
            "type": "integer",
            "nullable": true
          },
          "attemptCount": {
            "type": "integer"
          },
          "nextRetryAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "lastError": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      }
    }
  }
}
