{
  "openapi": "3.1.0",
  "info": {
    "title": "CrowdIntel API",
    "version": "1.0.0",
    "summary": "Read-only on-chain Polymarket smart-money intelligence.",
    "description": "The CrowdIntel API is a public, paid, **read-only** intelligence API over CrowdIntel's Polymarket smart-money data: whale signals, wallet intel, leaderboards, market sentiment, on-chain trades, sybil clusters, investigations, and a live on-demand market analyze object.\n\n## Authentication\n\nEvery request requires a bearer API key:\n\n```\nAuthorization: Bearer cint_api_xxxxxxxxxxxxxxxxxxxxxxxx\n```\n\nKeys are minted in the dashboard at `/settings/api` (Terminal $99+ subscription required to mint a key). Keys are secrets — never expose them in a browser. The API is server-to-server only and sends no CORS headers.\n\n## Tiers\n\nEach endpoint declares a minimum tier in its description. A key resolves to a tier from the owner's subscription:\n\n| Tier | Plan | Hourly | Monthly |\n|------|------|--------|---------|\n| `free` | any valid key | 50/hr | 500/mo |\n| `terminal` | Terminal ($99/mo) | 1,000/hr | 50,000/mo |\n| `terminal_pro` | Terminal Pro ($299/mo) | 5,000/hr | 250,000/mo |\n\n`free`-tier endpoints (the \"taste\" surface) are reachable by any valid key. `terminal` and `terminal_pro` endpoints require the corresponding paid plan or a `403 forbidden`.\n\n## Rate limits\n\nLimits are enforced as **rolling hourly AND monthly** windows; whichever is hit first returns `429`. There is no overage billing and no metered top-ups. Every response carries:\n\n- `X-RateLimit-Limit` — the binding window's cap\n- `X-RateLimit-Remaining` — calls left in the binding window\n- `X-RateLimit-Reset` — Unix epoch seconds when the binding window resets\n\nA `429` additionally sets `Retry-After` (seconds).\n\n## Conventions\n\n- **JSON casing:** all responses are `snake_case`.\n- **Errors:** `{ \"error\": { \"code\", \"message\", \"request_id\" } }` with the matching HTTP status. The `request_id` is echoed in the `X-Request-Id` header.\n- **Cursor pagination:** list endpoints return `{ \"data\": [...], \"next_cursor\": \"...\" }`. Pass the opaque `next_cursor` back as `?cursor=` to fetch the next page; `next_cursor` is `null` on the last page. Hard `limit` and max-depth caps apply.\n- **Freshness:** near-real-time, a few minutes behind chain (indexer lag). No hard SLA on self-serve tiers.\n\n## Bundled MCP server\n\nTerminal ($99+) bundles the CrowdIntel MCP server (12 read-only tools, `cint_mcp_` keys) as the agent-native channel into Claude Desktop, Cursor, Zed, or any MCP client.",
    "contact": {
      "name": "CrowdIntel",
      "url": "https://crowdintel.xyz/pricing"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://crowdintel.xyz/pricing"
    }
  },
  "servers": [
    {
      "url": "https://crowdintel.xyz/api",
      "description": "Production"
    }
  ],
  "externalDocs": {
    "description": "Pricing & plans",
    "url": "https://crowdintel.xyz/pricing"
  },
  "tags": [
    { "name": "Signals", "description": "Headline smart-money score + confidence + raw breakdown per wallet/market, the edge screener, and market movers." },
    { "name": "Wallets", "description": "Pseudonymous wallet profiles, per-category stats, bet-timing, correlated wallets, per-wallet trade history, and search." },
    { "name": "Leaderboards", "description": "Top wallets by volume / PnL / category edge." },
    { "name": "Markets", "description": "Market detail, whale sentiment + implied probability, trending/moving markets, and order flow." },
    { "name": "Analyze", "description": "On-demand, live-computed structured market intelligence object (Terminal Pro)." },
    { "name": "Clusters", "description": "Sybil clusters and funding-cluster graphs (Terminal Pro)." },
    { "name": "Investigations", "description": "Curated coordinated-wallet investigations with statistical evidence (Terminal Pro)." },
    { "name": "Trades", "description": "Raw on-chain trade fills — filtered, keyset-paginated (Terminal); single fill by tx hash." },
    { "name": "Utility", "description": "Connectivity and auth probe." }
  ],
  "security": [{ "bearerAuth": [] }],
  "paths": {
    "/v1/_ping": {
      "get": {
        "tags": ["Utility"],
        "operationId": "ping",
        "summary": "Connectivity & auth probe",
        "description": "**Min tier: `free`.** Verifies a key resolves, passes tier gating, rate limiting, and metering. Returns the caller's resolved tier.",
        "responses": {
          "200": {
            "description": "Probe OK.",
            "headers": { "$ref": "#/components/headers/RateLimitSet" },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": { "type": "boolean", "const": true },
                    "tier": { "$ref": "#/components/schemas/ApiTier" }
                  },
                  "required": ["ok", "tier"]
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/signals/wallet/{address}": {
      "get": {
        "tags": ["Signals"],
        "operationId": "getWalletSignal",
        "summary": "Wallet smart-money signal",
        "description": "**Min tier: `free`.** Single-wallet smart-money lookup (taste tier). Returns the headline `smart_money_score` (0-100), `confidence` (0-1), the raw signal breakdown, the wallet type, and core stats. Score comes from the persisted V3 8-signal scorer or a Bayesian-win-rate fallback.",
        "parameters": [{ "$ref": "#/components/parameters/AddressPath" }],
        "responses": {
          "200": {
            "description": "Wallet signal.",
            "headers": { "$ref": "#/components/headers/RateLimitSet" },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/WalletSignal" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/signals/market/{slug}": {
      "get": {
        "tags": ["Signals"],
        "operationId": "getMarketSignal",
        "summary": "Market smart-money signal",
        "description": "**Min tier: `free`.** Single-market smart-money lookup (taste tier). Combines whale sentiment with the whale-implied probability for the market slug.",
        "parameters": [{ "$ref": "#/components/parameters/SlugPath" }],
        "responses": {
          "200": {
            "description": "Market signal.",
            "headers": { "$ref": "#/components/headers/RateLimitSet" },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/MarketSignal" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/signals/screen": {
      "get": {
        "tags": ["Signals"],
        "operationId": "screenWalletsByEdge",
        "summary": "Edge screener",
        "description": "**Min tier: `terminal`.** Scope-edge screener: wallets whose per-category win rate beats their global win rate, ranked by edge. Cursor-paginated; offset depth is hard-capped at 1,000 rows.",
        "parameters": [
          { "$ref": "#/components/parameters/Cursor" },
          { "name": "limit", "in": "query", "description": "Page size (default 25, max 100).", "schema": { "type": "integer", "default": 25, "minimum": 1, "maximum": 100 } },
          { "name": "min_edge", "in": "query", "description": "Minimum edge (per-category WR minus global WR), e.g. 0.15.", "schema": { "type": "number" } },
          { "name": "min_bets", "in": "query", "description": "Minimum resolved bets in the category.", "schema": { "type": "integer" } },
          { "$ref": "#/components/parameters/CategoryFilter" }
        ],
        "responses": {
          "200": { "$ref": "#/components/responses/WalletEdgePage" },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/signals/movers": {
      "get": {
        "tags": ["Signals"],
        "operationId": "getMarketMovers",
        "summary": "Market movers",
        "description": "**Min tier: `terminal`.** Volume-ranked market movers over a recent window. Bounded top-N (no deep pagination).",
        "parameters": [
          { "name": "period_hours", "in": "query", "description": "Look-back window in hours (default 24, max 168).", "schema": { "type": "integer", "default": 24, "minimum": 1, "maximum": 168 } },
          { "$ref": "#/components/parameters/CategoryFilter" },
          { "name": "limit", "in": "query", "description": "Top-N to return (default 20, max 100).", "schema": { "type": "integer", "default": 20, "minimum": 1, "maximum": 100 } }
        ],
        "responses": {
          "200": {
            "description": "Market movers.",
            "headers": { "$ref": "#/components/headers/RateLimitSet" },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "period_hours": { "type": "integer" },
                    "count": { "type": "integer" },
                    "movers": { "type": "array", "items": { "$ref": "#/components/schemas/MarketMover" } }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/wallets/{address}": {
      "get": {
        "tags": ["Wallets"],
        "operationId": "getWallet",
        "summary": "Wallet profile",
        "description": "**Min tier: `free`.** Wallet profile + stats. `free` keys get the lightweight `wallet_stats`-only profile; `terminal`+ keys get the full dossier (recent trades, alerts, funding cluster).",
        "parameters": [{ "$ref": "#/components/parameters/AddressPath" }],
        "responses": {
          "200": {
            "description": "Wallet profile. Shape depends on caller tier (lite for `free`, full dossier for `terminal`+).",
            "headers": { "$ref": "#/components/headers/RateLimitSet" },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/WalletProfile" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/wallets/{address}/categories": {
      "get": {
        "tags": ["Wallets"],
        "operationId": "getWalletCategories",
        "summary": "Per-category wallet stats",
        "description": "**Min tier: `terminal`.** Per-category win rate and PnL for the wallet.",
        "parameters": [{ "$ref": "#/components/parameters/AddressPath" }],
        "responses": {
          "200": {
            "description": "Per-category stats.",
            "headers": { "$ref": "#/components/headers/RateLimitSet" },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "address": { "$ref": "#/components/schemas/Address" },
                    "categories": { "type": "array", "items": { "$ref": "#/components/schemas/WalletCategoryStat" } }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/wallets/{address}/timing": {
      "get": {
        "tags": ["Wallets"],
        "operationId": "getWalletTiming",
        "summary": "Bet-timing distribution",
        "description": "**Min tier: `terminal`.** Distribution of how early/late the wallet bets relative to market resolution, over its last 500 resolved trades (row-bounded scan).",
        "parameters": [{ "$ref": "#/components/parameters/AddressPath" }],
        "responses": {
          "200": {
            "description": "Bet-timing distribution.",
            "headers": { "$ref": "#/components/headers/RateLimitSet" },
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/WalletTiming" } } }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/wallets/{address}/correlated": {
      "get": {
        "tags": ["Wallets"],
        "operationId": "getCorrelatedWallets",
        "summary": "Correlated wallets",
        "description": "**Min tier: `terminal`.** Wallets that traded the same markets on the same side over a 30-day window (live self-join, bounded to 20 anchor markets).",
        "parameters": [
          { "$ref": "#/components/parameters/AddressPath" },
          { "name": "limit", "in": "query", "description": "Max correlated wallets (default 5, max 20).", "schema": { "type": "integer", "default": 5, "minimum": 1, "maximum": 20 } }
        ],
        "responses": {
          "200": {
            "description": "Correlated wallets.",
            "headers": { "$ref": "#/components/headers/RateLimitSet" },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "address": { "$ref": "#/components/schemas/Address" },
                    "correlated": { "type": "array", "items": { "$ref": "#/components/schemas/CorrelatedWallet" } }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/wallets/{address}/trades": {
      "get": {
        "tags": ["Wallets"],
        "operationId": "getWalletTrades",
        "summary": "Per-wallet trade history",
        "description": "**Min tier: `terminal`.** Per-wallet trade fills, newest first. Keyset cursor pagination on `(trade_timestamp, id)`; row-bounded via the proxy-wallet index (never time-bounded).",
        "parameters": [
          { "$ref": "#/components/parameters/AddressPath" },
          { "$ref": "#/components/parameters/Cursor" },
          { "name": "limit", "in": "query", "description": "Page size (default 20, max 100).", "schema": { "type": "integer", "default": 20, "minimum": 1, "maximum": 100 } }
        ],
        "responses": {
          "200": { "$ref": "#/components/responses/TradePage" },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/wallets/search": {
      "get": {
        "tags": ["Wallets"],
        "operationId": "searchWallets",
        "summary": "Search wallets",
        "description": "**Min tier: `terminal`.** Search by address or Polymarket name. Bounded point search.",
        "parameters": [
          { "name": "q", "in": "query", "required": true, "description": "Search query (min 3 chars) — address fragment or Polymarket name.", "schema": { "type": "string", "minLength": 3 } },
          { "name": "limit", "in": "query", "description": "Max results (default 10, max 25).", "schema": { "type": "integer", "default": 10, "minimum": 1, "maximum": 25 } }
        ],
        "responses": {
          "200": {
            "description": "Search results.",
            "headers": { "$ref": "#/components/headers/RateLimitSet" },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "query": { "type": "string" },
                    "results": { "type": "array", "items": { "$ref": "#/components/schemas/WalletSearchResult" } }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/leaderboards/whales": {
      "get": {
        "tags": ["Leaderboards"],
        "operationId": "getWhaleLeaderboard",
        "summary": "Whale leaderboard",
        "description": "**Min tier: `terminal`.** Top wallets by ClickHouse-rollup-backed metrics. `free` keys see the top 25 only; `terminal`+ paginate to depth 500. Cursor-paginated.",
        "parameters": [
          { "name": "sort", "in": "query", "description": "Sort key.", "schema": { "type": "string", "enum": ["volume", "winRate", "zScore", "totalBets"], "default": "volume" } },
          { "name": "limit", "in": "query", "description": "Page size (default 50, max 100).", "schema": { "type": "integer", "default": 50, "minimum": 1, "maximum": 100 } },
          { "name": "min_volume", "in": "query", "description": "Minimum total volume (USD) filter.", "schema": { "type": "number" } },
          { "name": "min_resolved_bets", "in": "query", "description": "Minimum resolved-bet count filter.", "schema": { "type": "integer" } },
          { "$ref": "#/components/parameters/Cursor" }
        ],
        "responses": {
          "200": { "$ref": "#/components/responses/LeaderboardPage" },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/leaderboards/pnl": {
      "get": {
        "tags": ["Leaderboards"],
        "operationId": "getPnlLeaderboard",
        "summary": "PnL leaderboard",
        "description": "**Min tier: `terminal`.** Wallets ranked by accounting-grade PnL (`polymarket_pnl ?? total_pnl`). `free` keys see the top 25; `terminal`+ paginate to depth 500. Cursor-paginated.",
        "parameters": [
          { "name": "sort_dir", "in": "query", "description": "Sort direction.", "schema": { "type": "string", "enum": ["asc", "desc"], "default": "desc" } },
          { "name": "limit", "in": "query", "description": "Page size (default 50, max 100).", "schema": { "type": "integer", "default": 50, "minimum": 1, "maximum": 100 } },
          { "name": "min_resolved_bets", "in": "query", "description": "Minimum resolved bets (default 5).", "schema": { "type": "integer", "default": 5, "minimum": 0 } },
          { "$ref": "#/components/parameters/Cursor" }
        ],
        "responses": {
          "200": { "$ref": "#/components/responses/LeaderboardPage" },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/leaderboards/category/{cat}": {
      "get": {
        "tags": ["Leaderboards"],
        "operationId": "getCategoryLeaderboard",
        "summary": "Category leaderboard",
        "description": "**Min tier: `terminal`.** Top wallets within a market category. `free` keys see the top 25; `terminal`+ paginate to depth 500. Cursor-paginated.",
        "parameters": [
          { "name": "cat", "in": "path", "required": true, "description": "Category slug.", "schema": { "type": "string", "enum": ["politics", "crypto", "sports", "culture", "economics", "breaking-news"] } },
          { "name": "sort", "in": "query", "description": "Sort key.", "schema": { "type": "string", "enum": ["win_rate", "counter_consensus_wins", "pnl", "volume"], "default": "pnl" } },
          { "name": "limit", "in": "query", "description": "Page size (default 50, max 100).", "schema": { "type": "integer", "default": 50, "minimum": 1, "maximum": 100 } },
          { "name": "min_bets", "in": "query", "description": "Minimum bets in the category (default 20).", "schema": { "type": "integer", "default": 20, "minimum": 1 } },
          { "$ref": "#/components/parameters/Cursor" }
        ],
        "responses": {
          "200": { "$ref": "#/components/responses/LeaderboardPage" },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/markets/{slug}": {
      "get": {
        "tags": ["Markets"],
        "operationId": "getMarket",
        "summary": "Market detail",
        "description": "**Min tier: `terminal`.** Market detail — aggregate stats, top YES/NO holders, recent price history, and resolution outcome.",
        "parameters": [{ "$ref": "#/components/parameters/SlugPath" }],
        "responses": {
          "200": {
            "description": "Market detail.",
            "headers": { "$ref": "#/components/headers/RateLimitSet" },
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MarketDetail" } } }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/markets/{slug}/sentiment": {
      "get": {
        "tags": ["Markets"],
        "operationId": "getMarketSentiment",
        "summary": "Market sentiment + implied probability",
        "description": "**Min tier: `terminal`.** Whale YES/NO sentiment and whale-implied probability over a 30-day window (whale/insider wallets only, Bayesian-WR-weighted).",
        "parameters": [{ "$ref": "#/components/parameters/SlugPath" }],
        "responses": {
          "200": {
            "description": "Market sentiment.",
            "headers": { "$ref": "#/components/headers/RateLimitSet" },
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    { "$ref": "#/components/schemas/Sentiment" },
                    {
                      "type": "object",
                      "properties": { "implied_probability": { "$ref": "#/components/schemas/ImpliedProbability" } }
                    }
                  ]
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/markets/{slug}/flow": {
      "get": {
        "tags": ["Markets"],
        "operationId": "getMarketFlow",
        "summary": "Market order flow",
        "description": "**Min tier: `terminal`.** Recent order flow — time-bucketed YES/NO buy/sell volume, net flow, unique wallets, and average price. Timestamp-bounded read (never an unfiltered trades scan).",
        "parameters": [
          { "$ref": "#/components/parameters/SlugPath" },
          { "name": "minutes", "in": "query", "description": "Look-back window in minutes (default 60, range 5-1440).", "schema": { "type": "integer", "default": 60, "minimum": 5, "maximum": 1440 } },
          { "name": "whales_only", "in": "query", "description": "Restrict to wallets with >$50k total volume (default true).", "schema": { "type": "boolean", "default": true } }
        ],
        "responses": {
          "200": {
            "description": "Order flow.",
            "headers": { "$ref": "#/components/headers/RateLimitSet" },
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MarketFlow" } } }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/markets/trending": {
      "get": {
        "tags": ["Markets"],
        "operationId": "getTrendingMarkets",
        "summary": "Trending markets",
        "description": "**Min tier: `terminal`.** Markets ranked by whale volume over a recent window. Cursor-paginated; time-bounded aggregate.",
        "parameters": [
          { "name": "period_hours", "in": "query", "description": "Look-back window in hours (default 24, range 1-168).", "schema": { "type": "integer", "default": 24, "minimum": 1, "maximum": 168 } },
          { "name": "limit", "in": "query", "description": "Page size (default 20, max 100).", "schema": { "type": "integer", "default": 20, "minimum": 1, "maximum": 100 } },
          { "$ref": "#/components/parameters/Cursor" },
          { "$ref": "#/components/parameters/CategoryFilter" },
          { "name": "search", "in": "query", "description": "Title substring filter.", "schema": { "type": "string" } }
        ],
        "responses": {
          "200": { "$ref": "#/components/responses/MarketRankPage" },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/markets/moving": {
      "get": {
        "tags": ["Markets"],
        "operationId": "getMovingMarkets",
        "summary": "Moving markets",
        "description": "**Min tier: `terminal`.** Markets ranked by absolute price change over a recent window (requires >= 3 trades per market). Cursor-paginated.",
        "parameters": [
          { "name": "period_hours", "in": "query", "description": "Look-back window in hours (default 24, range 1-168).", "schema": { "type": "integer", "default": 24, "minimum": 1, "maximum": 168 } },
          { "name": "limit", "in": "query", "description": "Page size (default 20, max 100).", "schema": { "type": "integer", "default": 20, "minimum": 1, "maximum": 100 } },
          { "$ref": "#/components/parameters/Cursor" },
          { "$ref": "#/components/parameters/CategoryFilter" },
          { "name": "search", "in": "query", "description": "Title substring filter.", "schema": { "type": "string" } }
        ],
        "responses": {
          "200": { "$ref": "#/components/responses/MarketRankPage" },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/analyze/market/{slug}": {
      "get": {
        "tags": ["Analyze"],
        "operationId": "analyzeMarket",
        "summary": "On-demand market analysis",
        "description": "**Min tier: `terminal_pro`.** Live-computed structured intelligence object for a market: smart-money probability, market price, divergence, top positions, sentiment, and 24h flow. Deterministic (no LLM). Cached ~30s.",
        "parameters": [{ "$ref": "#/components/parameters/SlugPath" }],
        "responses": {
          "200": {
            "description": "Market analysis object.",
            "headers": { "$ref": "#/components/headers/RateLimitSet" },
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MarketAnalysis" } } }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/clusters/sybil": {
      "get": {
        "tags": ["Clusters"],
        "operationId": "getSybilClusters",
        "summary": "Sybil clusters",
        "description": "**Min tier: `terminal_pro`.** Pre-computed sybil-cluster rollup (no on-demand graph build).",
        "parameters": [
          { "name": "limit", "in": "query", "description": "Max clusters (default 100, max 200).", "schema": { "type": "integer", "default": 100, "minimum": 1, "maximum": 200 } },
          { "name": "sort", "in": "query", "description": "Sort key.", "schema": { "type": "string", "enum": ["members", "volume", "pnl"], "default": "members" } }
        ],
        "responses": {
          "200": {
            "description": "Sybil clusters.",
            "headers": { "$ref": "#/components/headers/RateLimitSet" },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": { "clusters": { "type": "array", "items": { "$ref": "#/components/schemas/SybilCluster" } } }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/clusters/{funder}/graph": {
      "get": {
        "tags": ["Clusters"],
        "operationId": "getClusterGraph",
        "summary": "Funding-cluster graph",
        "description": "**Min tier: `terminal_pro`.** Funding-cluster graph rooted at a funder address: proxy nodes funded by it plus their stats. Hard node cap of 500 — the Polymarket proxy factory and any funder with >= 500 proxies are rejected with `400` (graph blowup guard).",
        "parameters": [{ "$ref": "#/components/parameters/FunderPath" }],
        "responses": {
          "200": {
            "description": "Cluster graph.",
            "headers": { "$ref": "#/components/headers/RateLimitSet" },
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ClusterGraph" } } }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/investigations": {
      "get": {
        "tags": ["Investigations"],
        "operationId": "listInvestigations",
        "summary": "List investigations",
        "description": "**Min tier: `terminal_pro`.** Curated coordinated-wallet investigations, ordered by p-value ascending then recency. Cursor-paginated.",
        "parameters": [
          { "$ref": "#/components/parameters/Cursor" },
          { "name": "limit", "in": "query", "description": "Page size (default 20, max 100).", "schema": { "type": "integer", "default": 20, "minimum": 1, "maximum": 100 } },
          { "$ref": "#/components/parameters/CategoryFilter" },
          { "name": "type", "in": "query", "description": "Investigation type filter.", "schema": { "type": "string" } }
        ],
        "responses": {
          "200": {
            "description": "Investigations page.",
            "headers": { "$ref": "#/components/headers/RateLimitSet" },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": { "type": "array", "items": { "$ref": "#/components/schemas/InvestigationSummary" } },
                    "next_cursor": { "type": ["string", "null"] }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/investigations/{id}": {
      "get": {
        "tags": ["Investigations"],
        "operationId": "getInvestigation",
        "summary": "Get investigation",
        "description": "**Min tier: `terminal_pro`.** Full investigation by numeric id — wallets, evidence, and statistical summary.",
        "parameters": [
          { "name": "id", "in": "path", "required": true, "description": "Investigation id.", "schema": { "type": "integer", "minimum": 1 } }
        ],
        "responses": {
          "200": {
            "description": "Investigation.",
            "headers": { "$ref": "#/components/headers/RateLimitSet" },
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Investigation" } } }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/trades": {
      "get": {
        "tags": ["Trades"],
        "operationId": "listTrades",
        "summary": "Query trade fills",
        "description": "**Min tier: `terminal`.** Raw on-chain trade fills. **At least one selective filter (`wallet`, `market`, or a fully-bounded `start`+`end` window) is required** — unfiltered scans of the 1.3B-row trades table are rejected with `400`. Time windows must supply both `start` and `end` and cannot exceed 90 days. Keyset cursor pagination on `(trade_timestamp, id)`; routes to ClickHouse for heavy reads.",
        "parameters": [
          { "name": "wallet", "in": "query", "description": "Filter by proxy wallet address.", "schema": { "$ref": "#/components/schemas/Address" } },
          { "name": "market", "in": "query", "description": "Filter by market condition id.", "schema": { "type": "string" } },
          { "name": "side", "in": "query", "description": "Trade side.", "schema": { "type": "string", "enum": ["BUY", "SELL"] } },
          { "name": "min_bet", "in": "query", "description": "Minimum bet value (USD).", "schema": { "type": "number", "minimum": 0 } },
          { "name": "start", "in": "query", "description": "Window start — ISO-8601 or unix-ms. Required with `end` when no wallet/market filter.", "schema": { "type": "string" } },
          { "name": "end", "in": "query", "description": "Window end — ISO-8601 or unix-ms. Window capped at 90 days.", "schema": { "type": "string" } },
          { "name": "limit", "in": "query", "description": "Page size (default 25, max 100).", "schema": { "type": "integer", "default": 25, "minimum": 1, "maximum": 100 } },
          { "$ref": "#/components/parameters/Cursor" }
        ],
        "responses": {
          "200": { "$ref": "#/components/responses/TradePage" },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/trades/{txHash}": {
      "get": {
        "tags": ["Trades"],
        "operationId": "getTrade",
        "summary": "Get trade by tx hash",
        "description": "**Min tier: `terminal`.** Single trade fill by transaction hash (Postgres point lookup).",
        "parameters": [
          { "name": "txHash", "in": "path", "required": true, "description": "Transaction hash.", "schema": { "type": "string" } }
        ],
        "responses": {
          "200": {
            "description": "Trade fill.",
            "headers": { "$ref": "#/components/headers/RateLimitSet" },
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Trade" } } }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "cint_api_*",
        "description": "Bearer API key. Format: `cint_api_` followed by 48 hex chars. Mint at /settings/api (Terminal $99+)."
      }
    },
    "headers": {
      "RateLimitSet": {
        "description": "Rate-limit state for the binding (hourly or monthly) window. Present on every authenticated response.",
        "schema": { "type": "string" }
      }
    },
    "parameters": {
      "AddressPath": {
        "name": "address",
        "in": "path",
        "required": true,
        "description": "0x-prefixed 40-hex Polygon wallet address.",
        "schema": { "$ref": "#/components/schemas/Address" }
      },
      "SlugPath": {
        "name": "slug",
        "in": "path",
        "required": true,
        "description": "Polymarket market slug.",
        "schema": { "type": "string" }
      },
      "FunderPath": {
        "name": "funder",
        "in": "path",
        "required": true,
        "description": "0x-prefixed 40-hex funder address.",
        "schema": { "$ref": "#/components/schemas/Address" }
      },
      "Cursor": {
        "name": "cursor",
        "in": "query",
        "description": "Opaque pagination cursor from a previous response's `next_cursor`. Omit for the first page.",
        "schema": { "type": "string" }
      },
      "CategoryFilter": {
        "name": "category",
        "in": "query",
        "description": "Filter by market category.",
        "schema": { "type": "string" }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Malformed parameters or a rejected guardrail (e.g. unfiltered trades query, cluster blowup, window > 90 days).",
        "headers": { "X-Request-Id": { "schema": { "type": "string" } } },
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" }, "example": { "error": { "code": "bad_request", "message": "Invalid wallet address", "request_id": "5f8e..." } } } }
      },
      "Unauthorized": {
        "description": "Missing, invalid, or revoked API key.",
        "headers": { "X-Request-Id": { "schema": { "type": "string" } } },
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" }, "example": { "error": { "code": "unauthorized", "message": "Missing Authorization: Bearer token", "request_id": "5f8e..." } } } }
      },
      "Forbidden": {
        "description": "Key valid but its tier is below this endpoint's minimum.",
        "headers": { "X-Request-Id": { "schema": { "type": "string" } } },
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" }, "example": { "error": { "code": "forbidden", "message": "This endpoint requires the terminal_pro API tier", "request_id": "5f8e..." } } } }
      },
      "NotFound": {
        "description": "The requested resource was not found.",
        "headers": { "X-Request-Id": { "schema": { "type": "string" } } },
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" }, "example": { "error": { "code": "not_found", "message": "Wallet not found", "request_id": "5f8e..." } } } }
      },
      "RateLimited": {
        "description": "Hourly or monthly rate limit exceeded.",
        "headers": {
          "X-RateLimit-Limit": { "schema": { "type": "integer" } },
          "X-RateLimit-Remaining": { "schema": { "type": "integer" } },
          "X-RateLimit-Reset": { "schema": { "type": "integer" }, "description": "Unix epoch seconds." },
          "Retry-After": { "schema": { "type": "integer" }, "description": "Seconds until the binding window resets." },
          "X-Request-Id": { "schema": { "type": "string" } }
        },
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" }, "example": { "error": { "code": "rate_limited", "message": "Rate limit exceeded", "request_id": "5f8e..." } } } }
      },
      "WalletEdgePage": {
        "description": "Cursor-paginated edge-screen results.",
        "headers": { "$ref": "#/components/headers/RateLimitSet" },
        "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/WalletEdge" } }, "next_cursor": { "type": ["string", "null"] } } } } }
      },
      "TradePage": {
        "description": "Cursor-paginated trade fills.",
        "headers": { "$ref": "#/components/headers/RateLimitSet" },
        "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/Trade" } }, "next_cursor": { "type": ["string", "null"] } } } } }
      },
      "LeaderboardPage": {
        "description": "Cursor-paginated leaderboard rows.",
        "headers": { "$ref": "#/components/headers/RateLimitSet" },
        "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/LeaderboardEntry" } }, "next_cursor": { "type": ["string", "null"] } } } } }
      },
      "MarketRankPage": {
        "description": "Cursor-paginated ranked markets.",
        "headers": { "$ref": "#/components/headers/RateLimitSet" },
        "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/MarketRank" } }, "next_cursor": { "type": ["string", "null"] } } } } }
      }
    },
    "schemas": {
      "ApiTier": { "type": "string", "enum": ["free", "terminal", "terminal_pro"] },
      "Address": { "type": "string", "pattern": "^0x[0-9a-fA-F]{40}$", "example": "0x0000000000000000000000000000000000000000" },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": { "type": "string", "enum": ["unauthorized", "forbidden", "rate_limited", "not_found", "bad_request", "internal_error"] },
              "message": { "type": "string" },
              "request_id": { "type": "string", "description": "Echoed in the X-Request-Id header; quote it in support requests." }
            },
            "required": ["code", "message", "request_id"]
          }
        },
        "required": ["error"]
      },
      "WalletStats": {
        "type": "object",
        "nullable": true,
        "properties": {
          "total_bets": { "type": "integer" },
          "resolved_bets": { "type": "integer" },
          "win_rate": { "type": ["number", "null"] },
          "bayesian_win_rate": { "type": ["number", "null"] },
          "total_volume": { "type": ["number", "null"] },
          "total_pnl": { "type": ["number", "null"] },
          "markets_traded": { "type": ["integer", "null"] }
        }
      },
      "WalletSignal": {
        "type": "object",
        "properties": {
          "wallet": { "$ref": "#/components/schemas/Address" },
          "smart_money_score": { "type": "number", "minimum": 0, "maximum": 100, "description": "Headline composite suspicion/edge score." },
          "confidence": { "type": "number", "minimum": 0, "maximum": 1, "description": "Bayesian confidence in the score." },
          "breakdown": { "type": "object", "additionalProperties": true, "description": "Raw per-signal contribution breakdown." },
          "wallet_type": { "type": ["string", "null"] },
          "stats": { "$ref": "#/components/schemas/WalletStats" }
        }
      },
      "Sentiment": {
        "type": "object",
        "properties": {
          "sentiment": { "type": ["string", "null"], "description": "Label: bullish / bearish / mixed." },
          "yes_ratio": { "type": ["number", "null"] },
          "yes_volume": { "type": ["number", "null"] },
          "no_volume": { "type": ["number", "null"] },
          "total_whale_volume": { "type": ["number", "null"] },
          "unique_whales": { "type": ["integer", "null"] }
        }
      },
      "ImpliedProbability": {
        "type": "object",
        "nullable": true,
        "properties": {
          "yes_implied_prob": { "type": ["number", "null"] },
          "no_implied_prob": { "type": ["number", "null"] },
          "current_price": { "type": ["number", "null"] },
          "edge": { "type": ["number", "null"], "description": "Whale-implied probability minus market price." },
          "samples": { "type": ["integer", "null"] },
          "unique_wallets": { "type": ["integer", "null"] }
        }
      },
      "MarketSignal": {
        "type": "object",
        "properties": {
          "market": { "type": "object", "additionalProperties": true, "description": "Market metadata (slug, title, category, condition id)." },
          "sentiment": {
            "type": "object",
            "properties": {
              "direction": { "type": ["string", "null"] },
              "yes_ratio": { "type": ["number", "null"] },
              "yes_volume": { "type": ["number", "null"] },
              "no_volume": { "type": ["number", "null"] },
              "total_whale_volume": { "type": ["number", "null"] },
              "unique_whales": { "type": ["integer", "null"] }
            }
          },
          "smart_money_probability": { "$ref": "#/components/schemas/ImpliedProbability" }
        }
      },
      "WalletEdge": {
        "type": "object",
        "properties": {
          "address": { "$ref": "#/components/schemas/Address" },
          "polymarket_name": { "type": ["string", "null"] },
          "category": { "type": ["string", "null"] },
          "category_win_rate": { "type": ["number", "null"] },
          "global_win_rate": { "type": ["number", "null"] },
          "edge": { "type": ["number", "null"] },
          "bets": { "type": ["integer", "null"] },
          "total_pnl": { "type": ["number", "null"] }
        }
      },
      "MarketMover": {
        "type": "object",
        "properties": {
          "slug": { "type": "string" },
          "title": { "type": ["string", "null"] },
          "category": { "type": ["string", "null"] },
          "volume": { "type": ["number", "null"] },
          "trade_count": { "type": ["integer", "null"] },
          "net_flow": { "type": ["number", "null"] }
        }
      },
      "WalletProfile": {
        "type": "object",
        "description": "Lite (`free`) or full dossier (`terminal`+). Lite is a subset of the full shape.",
        "properties": {
          "address": { "$ref": "#/components/schemas/Address" },
          "polymarket_name": { "type": ["string", "null"] },
          "wallet_type": { "type": ["string", "null"] },
          "stats": { "$ref": "#/components/schemas/WalletStats" },
          "recent_trades": { "type": "array", "items": { "$ref": "#/components/schemas/Trade" }, "description": "Full dossier only." },
          "alerts": { "type": "array", "items": { "type": "object", "additionalProperties": true }, "description": "Full dossier only." },
          "funding_cluster": { "type": ["object", "null"], "additionalProperties": true, "description": "Full dossier only." }
        }
      },
      "WalletCategoryStat": {
        "type": "object",
        "properties": {
          "category": { "type": "string" },
          "bets": { "type": ["integer", "null"] },
          "wins": { "type": ["integer", "null"] },
          "win_rate": { "type": ["number", "null"] },
          "pnl": { "type": ["number", "null"] },
          "volume": { "type": ["number", "null"] }
        }
      },
      "WalletTiming": {
        "type": "object",
        "properties": {
          "address": { "$ref": "#/components/schemas/Address" },
          "buckets": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "label": { "type": "string" },
                "count": { "type": "integer" },
                "win_rate": { "type": ["number", "null"] }
              }
            }
          }
        }
      },
      "CorrelatedWallet": {
        "type": "object",
        "properties": {
          "address": { "$ref": "#/components/schemas/Address" },
          "polymarket_name": { "type": ["string", "null"] },
          "shared_markets": { "type": ["integer", "null"] },
          "same_side_ratio": { "type": ["number", "null"] }
        }
      },
      "WalletSearchResult": {
        "type": "object",
        "properties": {
          "address": { "$ref": "#/components/schemas/Address" },
          "polymarket_name": { "type": ["string", "null"] },
          "total_volume": { "type": ["number", "null"] },
          "total_pnl": { "type": ["number", "null"] }
        }
      },
      "LeaderboardEntry": {
        "type": "object",
        "properties": {
          "address": { "$ref": "#/components/schemas/Address" },
          "polymarket_name": { "type": ["string", "null"] },
          "total_volume": { "type": ["number", "null"] },
          "total_pnl": { "type": ["number", "null"] },
          "win_rate": { "type": ["number", "null"] },
          "z_score": { "type": ["number", "null"] },
          "total_bets": { "type": ["integer", "null"] }
        }
      },
      "MarketDetail": {
        "type": "object",
        "properties": {
          "slug": { "type": "string" },
          "title": { "type": ["string", "null"] },
          "category": { "type": ["string", "null"] },
          "condition_id": { "type": ["string", "null"] },
          "resolved_outcome": { "type": ["string", "null"] },
          "stats": { "type": "object", "additionalProperties": true },
          "top_yes_holders": { "type": "array", "items": { "type": "object", "additionalProperties": true } },
          "top_no_holders": { "type": "array", "items": { "type": "object", "additionalProperties": true } },
          "price_history": { "type": "array", "items": { "type": "object", "additionalProperties": true } }
        }
      },
      "MarketFlow": {
        "type": "object",
        "properties": {
          "slug": { "type": "string" },
          "window_minutes": { "type": "integer" },
          "whales_only": { "type": "boolean" },
          "total_volume": { "type": ["number", "null"] },
          "net_yes": { "type": ["number", "null"] },
          "net_no": { "type": ["number", "null"] },
          "buckets": { "type": "array", "items": { "type": "object", "additionalProperties": true } }
        }
      },
      "MarketRank": {
        "type": "object",
        "properties": {
          "slug": { "type": "string" },
          "title": { "type": ["string", "null"] },
          "category": { "type": ["string", "null"] },
          "whale_volume": { "type": ["number", "null"] },
          "price_change": { "type": ["number", "null"] },
          "trade_count": { "type": ["integer", "null"] }
        }
      },
      "MarketAnalysis": {
        "type": "object",
        "properties": {
          "market_slug": { "type": "string" },
          "market_title": { "type": ["string", "null"] },
          "market_category": { "type": ["string", "null"] },
          "condition_id": { "type": ["string", "null"] },
          "smart_money_prob": { "type": ["number", "null"], "minimum": 0, "maximum": 1 },
          "market_price": { "type": ["number", "null"], "minimum": 0, "maximum": 1 },
          "divergence": { "type": ["number", "null"], "description": "smart_money_prob - market_price." },
          "sample_wallets": { "type": "integer" },
          "top_positions": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "address": { "$ref": "#/components/schemas/Address" },
                "market_side": { "type": "string", "enum": ["YES", "NO"] },
                "volume": { "type": ["number", "null"] },
                "trade_count": { "type": ["integer", "null"] },
                "wallet_type": { "type": ["string", "null"] },
                "win_rate": { "type": ["number", "null"] },
                "total_pnl": { "type": ["number", "null"] },
                "polymarket_name": { "type": ["string", "null"] }
              }
            }
          },
          "sentiment": { "$ref": "#/components/schemas/Sentiment" },
          "flow_24h": {
            "type": "object",
            "properties": {
              "window_minutes": { "type": "integer" },
              "whales_only": { "type": "boolean" },
              "relaxed": { "type": "boolean" },
              "total_volume": { "type": ["number", "null"] },
              "net_yes": { "type": ["number", "null"] },
              "net_no": { "type": ["number", "null"] },
              "buckets": { "type": "array", "items": { "type": "object", "additionalProperties": true } }
            }
          },
          "computed_at": { "type": "string", "format": "date-time" }
        }
      },
      "SybilCluster": {
        "type": "object",
        "properties": {
          "id": { "type": ["integer", "string"] },
          "funder": { "$ref": "#/components/schemas/Address" },
          "members": { "type": ["integer", "null"] },
          "total_volume": { "type": ["number", "null"] },
          "total_pnl": { "type": ["number", "null"] }
        }
      },
      "ClusterGraph": {
        "type": "object",
        "properties": {
          "funder": { "$ref": "#/components/schemas/Address" },
          "proxy_count": { "type": "integer" },
          "truncated": { "type": "boolean" },
          "node_count": { "type": "integer" },
          "edge_count": { "type": "integer" },
          "total_volume": { "type": ["number", "null"] },
          "total_bets": { "type": ["integer", "null"] },
          "nodes": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": { "type": "string" },
                "type": { "type": "string", "enum": ["funder", "proxy"] },
                "bets": { "type": ["integer", "null"] },
                "wins": { "type": ["integer", "null"] },
                "win_rate": { "type": ["number", "null"] },
                "pnl": { "type": ["number", "null"] },
                "volume": { "type": ["number", "null"] }
              }
            }
          },
          "edges": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "source": { "type": "string" },
                "target": { "type": "string" }
              }
            }
          }
        }
      },
      "InvestigationSummary": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "slug": { "type": ["string", "null"] },
          "title": { "type": ["string", "null"] },
          "type": { "type": ["string", "null"] },
          "category": { "type": ["string", "null"] },
          "p_value": { "type": ["number", "null"] },
          "win_rate": { "type": ["number", "null"] },
          "total_pnl": { "type": ["number", "null"] },
          "wallet_count": { "type": ["integer", "null"] },
          "created_at": { "type": ["string", "null"], "format": "date-time" }
        }
      },
      "Investigation": {
        "type": "object",
        "description": "Full investigation. Extends the summary with wallets, evidence, and methodology.",
        "properties": {
          "id": { "type": "integer" },
          "slug": { "type": ["string", "null"] },
          "title": { "type": ["string", "null"] },
          "type": { "type": ["string", "null"] },
          "category": { "type": ["string", "null"] },
          "p_value": { "type": ["number", "null"] },
          "win_rate": { "type": ["number", "null"] },
          "total_pnl": { "type": ["number", "null"] },
          "wallets": { "type": "array", "items": { "type": "object", "additionalProperties": true } },
          "evidence": { "type": "object", "additionalProperties": true },
          "created_at": { "type": ["string", "null"], "format": "date-time" }
        }
      },
      "Trade": {
        "type": "object",
        "properties": {
          "id": { "type": ["integer", "string"] },
          "tx_hash": { "type": "string" },
          "proxy_wallet": { "$ref": "#/components/schemas/Address" },
          "condition_id": { "type": ["string", "null"] },
          "market_slug": { "type": ["string", "null"] },
          "market_title": { "type": ["string", "null"] },
          "side": { "type": ["string", "null"], "enum": ["BUY", "SELL", null] },
          "outcome": { "type": ["string", "null"], "description": "What the trader bet on (e.g. 'Yes'), not WIN/LOSS." },
          "price": { "type": ["number", "null"] },
          "size": { "type": ["number", "null"] },
          "bet_value_usd": { "type": ["number", "null"] },
          "trade_timestamp": { "type": ["string", "null"], "format": "date-time" }
        }
      }
    }
  }
}
