openapi: 3.0.3
info:
  title: "InsiderCat API"
  version: 1.0.0
  description: "Official OpenAPI specification for InsiderCat API endpoints. The API is versioned in the URL path (/api/v1); see https://insidercat.com/api-mcp/versioning for the versioning and deprecation policy, including the Deprecation/Sunset headers used to signal a retiring endpoint."
servers:
  - url: https://insidercat.com
    description: Production
tags:
  - name: discovery
    description: "Public discovery endpoints for agents and integration tooling"
  - name: health
    description: "Service status"
  - name: trades
    description: "Insider and politician trades"
  - name: sentiment
    description: "Aggregated buy/sell activity by ticker"
  - name: portfolio
    description: "Estimated live portfolios of politicians"
  - name: stock
    description: "Stock-level ownership views"
  - name: mentions
    description: "Stock tickers mentioned by Donald Trump"
paths:
  /api/v1:
    get:
      operationId: getPublicApiHealth
      tags:
        - health
      summary: "Health check"
      description: "Returns a simple status object confirming the API is operational. No authentication required."
      x-codeSamples:
        curl: "curl \"https://insidercat.com/api/v1\""
        python: "import requests\n\nresponse = requests.get(\"https://insidercat.com/api/v1\")\nprint(response.json())"
        typescript: "const response = await fetch(\"https://insidercat.com/api/v1\");\nconst data = await response.json();\nconsole.log(data);"
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/HealthEnvelope"
              examples:
                default:
                  value:
                    data:
                      status: ok
                      service: insidercat-public-api
                      version: v1
                      timestamp: 2026-03-19T12:00:00.000Z
  /api/v1/public/capabilities:
    get:
      operationId: getPublicCapabilities
      tags:
        - discovery
      summary: "Public capabilities"
      description: "Returns unauthenticated discovery metadata for InsiderCat API, OpenAPI, MCP, llms.txt, and recommended agent integration use cases."
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/PublicCapabilitiesEnvelope"
  /api/v1/trades/politician:
    get:
      operationId: listPoliticianTrades
      tags:
        - trades
      security:
        - bearerAuth:
[]
      summary: "Politician trades"
      description: "Returns a paginated list of congressional trade disclosures with party, ticker, and value filters."
      x-codeSamples:
        curl: "curl \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  \"https://insidercat.com/api/v1/trades/politician?party=Democrat&ticker=AAPL&trade_type=BUY&min_value=250000&sort_by=reported_date&sort_dir=desc&limit=1\""
        python: "import requests\n\nAPI_KEY = \"YOUR_API_KEY\"\nresponse = requests.get(\n    \"https://insidercat.com/api/v1/trades/politician\",\n    headers={\"Authorization\": f\"Bearer {API_KEY}\"},\n    params={\"party\": \"Democrat\", \"ticker\": \"AAPL\", \"trade_type\": \"BUY\", \"min_value\": 250000, \"sort_by\": \"reported_date\", \"sort_dir\": \"desc\", \"limit\": 1},\n)\nprint(response.json())"
        typescript: "const API_KEY = \"YOUR_API_KEY\";\nconst params = new URLSearchParams({\n  party: \"Democrat\",\n  ticker: \"AAPL\",\n  trade_type: \"BUY\",\n  min_value: \"250000\",\n  sort_by: \"reported_date\",\n  sort_dir: \"desc\",\n  limit: \"1\",\n});\nconst response = await fetch(`https://insidercat.com/api/v1/trades/politician?${params}`, {\n  headers: { Authorization: `Bearer ${API_KEY}` },\n});\nconsole.log(await response.json());"
      parameters:
        - "$ref": "#/components/parameters/party"
        - "$ref": "#/components/parameters/trade_type"
        - "$ref": "#/components/parameters/tickerQuery"
        - "$ref": "#/components/parameters/politicianBioguideIdQuery"
        - "$ref": "#/components/parameters/min_value_number"
        - "$ref": "#/components/parameters/min_traded_date"
        - "$ref": "#/components/parameters/max_traded_date"
        - "$ref": "#/components/parameters/min_reported_date"
        - "$ref": "#/components/parameters/max_reported_date"
        - name: sort_by
          in: query
          required: false
          schema:
            type: string
            enum:
              - reported_date
              - traded_date
              - days_filed_after
              - size_lower
            default: reported_date
        - "$ref": "#/components/parameters/sort_dir"
        - "$ref": "#/components/parameters/limit"
        - "$ref": "#/components/parameters/cursor"
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  "$ref": "#/components/schemas/PoliticianTrade"
              examples:
                default:
                  value:
                    data:
                      - ticker: WBD
                        company_name: "Warner Bros. Discovery, Inc."
                        traded_date: 2026-02-10
                        reported_date: 2026-03-19
                        trade_type: SELL
                        size_lower: 1000
                        size_upper: 15000
                        price_adj_close_traded: 11.23
                        price_adj_close_reported: 10.87
                        politician_bioguide_id: P000048
                        politician_full_name: "August Pfluger"
                        politician_party: Republican
                        politician_chamber: House
                        politician_state: TX
        401:
          description: Unauthorized
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        403:
          description: Forbidden
          headers:
            RateLimit-Limit:
              description: "Requests allowed per rolling 60s window for this API key."
              schema:
                type: integer
            RateLimit-Remaining:
              description: "Requests remaining in the current window."
              schema:
                type: integer
            RateLimit-Reset:
              description: "Seconds until the window resets."
              schema:
                type: integer
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        429:
          description: "Rate limited. Every authenticated /api/v1 response (2xx and error) carries RateLimit-Limit/Remaining/Reset headers (plus legacy X-RateLimit-* aliases) so clients can self-throttle; a 429 additionally carries Retry-After."
          headers:
            RateLimit-Limit:
              description: "Requests allowed per rolling 60s window for this API key."
              schema:
                type: integer
            RateLimit-Remaining:
              description: "Requests remaining in the current window."
              schema:
                type: integer
            RateLimit-Reset:
              description: "Seconds until the window resets."
              schema:
                type: integer
            Retry-After:
              description: "Seconds to wait before retrying."
              schema:
                type: integer
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        500:
          description: "Internal server error"
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
  /api/v1/trades/insider:
    get:
      operationId: listInsiderTrades
      tags:
        - trades
      security:
        - bearerAuth:
[]
      summary: "Insider trades"
      description: "Returns a paginated list of insider trade filings from officers, directors, and major shareholders."
      x-codeSamples:
        curl: "curl \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  \"https://insidercat.com/api/v1/trades/insider?ticker=AAPL&trade_type=BUY&min_value=50000&sort_by=value&sort_dir=desc&limit=1\""
        python: "import requests\n\nAPI_KEY = \"YOUR_API_KEY\"\nresponse = requests.get(\n    \"https://insidercat.com/api/v1/trades/insider\",\n    headers={\"Authorization\": f\"Bearer {API_KEY}\"},\n    params={\"ticker\": \"AAPL\", \"trade_type\": \"BUY\", \"min_value\": 50000, \"sort_by\": \"value\", \"sort_dir\": \"desc\", \"limit\": 1},\n)\nprint(response.json())"
        typescript: "const API_KEY = \"YOUR_API_KEY\";\n  const params = new URLSearchParams({\n  ticker: \"AAPL\",\n  trade_type: \"BUY\",\n  min_value: \"50000\",\n  sort_by: \"value\",\n  sort_dir: \"desc\",\n  limit: \"1\",\n});\nconst response = await fetch(`https://insidercat.com/api/v1/trades/insider?${params}`, {\n  headers: { Authorization: `Bearer ${API_KEY}` },\n});\nconsole.log(await response.json());"
      parameters:
        - "$ref": "#/components/parameters/trade_type"
        - "$ref": "#/components/parameters/tickerQuery"
        - "$ref": "#/components/parameters/min_value_number"
        - "$ref": "#/components/parameters/min_traded_date"
        - "$ref": "#/components/parameters/max_traded_date"
        - "$ref": "#/components/parameters/min_reported_date"
        - "$ref": "#/components/parameters/max_reported_date"
        - name: sort_by
          in: query
          required: false
          schema:
            type: string
            enum:
              - traded_date
              - price
              - value
            default: traded_date
        - "$ref": "#/components/parameters/sort_dir"
        - "$ref": "#/components/parameters/limit"
        - "$ref": "#/components/parameters/cursor"
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  "$ref": "#/components/schemas/InsiderTrade"
              examples:
                default:
                  value:
                    data:
                      - ticker: GCBC
                        company_name: "GREENE COUNTY BANCORP INC"
                        traded_date: 2026-03-18
                        reported_date: 2026-03-18
                        trade_type: BUY
                        owner_name: "Hada Tejraj S"
                        owner_title: Director
                        amount: 4000
                        price: 21.95
                        value: 87800
        401:
          description: Unauthorized
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        403:
          description: Forbidden
          headers:
            RateLimit-Limit:
              description: "Requests allowed per rolling 60s window for this API key."
              schema:
                type: integer
            RateLimit-Remaining:
              description: "Requests remaining in the current window."
              schema:
                type: integer
            RateLimit-Reset:
              description: "Seconds until the window resets."
              schema:
                type: integer
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        429:
          description: "Rate limited. Every authenticated /api/v1 response (2xx and error) carries RateLimit-Limit/Remaining/Reset headers (plus legacy X-RateLimit-* aliases) so clients can self-throttle; a 429 additionally carries Retry-After."
          headers:
            RateLimit-Limit:
              description: "Requests allowed per rolling 60s window for this API key."
              schema:
                type: integer
            RateLimit-Remaining:
              description: "Requests remaining in the current window."
              schema:
                type: integer
            RateLimit-Reset:
              description: "Seconds until the window resets."
              schema:
                type: integer
            Retry-After:
              description: "Seconds to wait before retrying."
              schema:
                type: integer
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        500:
          description: "Internal server error"
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
  /api/v1/sentiment/politician:
    get:
      operationId: listPoliticianSentiment
      tags:
        - sentiment
      security:
        - bearerAuth:
[]
      summary: "Politician sentiment"
      description: "Returns aggregated buy/sell activity by ticker for politicians."
      x-codeSamples:
        curl: "curl \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  \"https://insidercat.com/api/v1/sentiment/politician?party=All&sort_by=net_volume&sort_dir=desc&limit=1\""
        python: "import requests\n\nAPI_KEY = \"YOUR_API_KEY\"\nresponse = requests.get(\n    \"https://insidercat.com/api/v1/sentiment/politician\",\n    headers={\"Authorization\": f\"Bearer {API_KEY}\"},\n    params={\"party\": \"All\", \"sort_by\": \"net_volume\", \"sort_dir\": \"desc\", \"limit\": 1},\n)\nprint(response.json())"
        typescript: "const API_KEY = \"YOUR_API_KEY\";\nconst params = new URLSearchParams({\n  party: \"All\",\n  sort_by: \"net_volume\",\n  sort_dir: \"desc\",\n  limit: \"1\",\n});\nconst response = await fetch(`https://insidercat.com/api/v1/sentiment/politician?${params}`, {\n  headers: { Authorization: `Bearer ${API_KEY}` },\n});\nconsole.log(await response.json());"
      parameters:
        - "$ref": "#/components/parameters/party"
        - "$ref": "#/components/parameters/min_traded_date"
        - "$ref": "#/components/parameters/max_traded_date"
        - "$ref": "#/components/parameters/min_reported_date"
        - "$ref": "#/components/parameters/max_reported_date"
        - name: sort_by
          in: query
          required: false
          schema:
            type: string
            enum:
              - num_buying
              - num_selling
              - total_bought
              - total_sold
              - net_volume
        - "$ref": "#/components/parameters/sort_dir"
        - "$ref": "#/components/parameters/limit"
        - "$ref": "#/components/parameters/cursor"
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  "$ref": "#/components/schemas/PoliticianSentimentRow"
              examples:
                default:
                  value:
                    data:
                      - ticker: AAPL
                        company_name: "Apple Inc."
                        num_republicans_buying: 3
                        num_republicans_selling: 8
                        num_democrats_buying: 2
                        num_democrats_selling: 5
                        total_bought: 1236500
                        total_sold: 30600500
                        total_volume: 31837000
                        net_volume: -29364000
        401:
          description: Unauthorized
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        403:
          description: Forbidden
          headers:
            RateLimit-Limit:
              description: "Requests allowed per rolling 60s window for this API key."
              schema:
                type: integer
            RateLimit-Remaining:
              description: "Requests remaining in the current window."
              schema:
                type: integer
            RateLimit-Reset:
              description: "Seconds until the window resets."
              schema:
                type: integer
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        429:
          description: "Rate limited. Every authenticated /api/v1 response (2xx and error) carries RateLimit-Limit/Remaining/Reset headers (plus legacy X-RateLimit-* aliases) so clients can self-throttle; a 429 additionally carries Retry-After."
          headers:
            RateLimit-Limit:
              description: "Requests allowed per rolling 60s window for this API key."
              schema:
                type: integer
            RateLimit-Remaining:
              description: "Requests remaining in the current window."
              schema:
                type: integer
            RateLimit-Reset:
              description: "Seconds until the window resets."
              schema:
                type: integer
            Retry-After:
              description: "Seconds to wait before retrying."
              schema:
                type: integer
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        500:
          description: "Internal server error"
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
  /api/v1/sentiment/insider:
    get:
      operationId: listInsiderSentiment
      tags:
        - sentiment
      security:
        - bearerAuth:
[]
      summary: "Insider sentiment"
      description: "Returns aggregated buy/sell activity by ticker for insiders."
      x-codeSamples:
        curl: "curl \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  \"https://insidercat.com/api/v1/sentiment/insider?sort_by=total_bought&sort_dir=desc&limit=1\""
        python: "import requests\n\nAPI_KEY = \"YOUR_API_KEY\"\nresponse = requests.get(\n    \"https://insidercat.com/api/v1/sentiment/insider\",\n    headers={\"Authorization\": f\"Bearer {API_KEY}\"},\n    params={\"sort_by\": \"total_bought\", \"sort_dir\": \"desc\", \"limit\": 1},\n)\nprint(response.json())"
        typescript: "const API_KEY = \"YOUR_API_KEY\";\nconst params = new URLSearchParams({\n  sort_by: \"total_bought\",\n  sort_dir: \"desc\",\n  limit: \"1\",\n});\nconst response = await fetch(`https://insidercat.com/api/v1/sentiment/insider?${params}`, {\n  headers: { Authorization: `Bearer ${API_KEY}` },\n});\nconsole.log(await response.json());"
      parameters:
        - "$ref": "#/components/parameters/min_traded_date"
        - "$ref": "#/components/parameters/max_traded_date"
        - "$ref": "#/components/parameters/min_reported_date"
        - "$ref": "#/components/parameters/max_reported_date"
        - name: sort_by
          in: query
          required: false
          schema:
            type: string
            enum:
              - num_buying
              - num_selling
              - total_bought
              - total_sold
              - net_volume
        - "$ref": "#/components/parameters/sort_dir"
        - "$ref": "#/components/parameters/limit"
        - "$ref": "#/components/parameters/cursor"
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  "$ref": "#/components/schemas/InsiderSentimentRow"
              examples:
                default:
                  value:
                    data:
                      - ticker: AAPL
                        company_name: "Apple Inc."
                        num_insiders_buy: 12
                        num_insiders_sell: 34
                        total_bought: 1236500
                        total_sold: 30600500
                        total_volume: 31837000
                        net_volume: -29364000
        401:
          description: Unauthorized
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        403:
          description: Forbidden
          headers:
            RateLimit-Limit:
              description: "Requests allowed per rolling 60s window for this API key."
              schema:
                type: integer
            RateLimit-Remaining:
              description: "Requests remaining in the current window."
              schema:
                type: integer
            RateLimit-Reset:
              description: "Seconds until the window resets."
              schema:
                type: integer
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        429:
          description: "Rate limited. Every authenticated /api/v1 response (2xx and error) carries RateLimit-Limit/Remaining/Reset headers (plus legacy X-RateLimit-* aliases) so clients can self-throttle; a 429 additionally carries Retry-After."
          headers:
            RateLimit-Limit:
              description: "Requests allowed per rolling 60s window for this API key."
              schema:
                type: integer
            RateLimit-Remaining:
              description: "Requests remaining in the current window."
              schema:
                type: integer
            RateLimit-Reset:
              description: "Seconds until the window resets."
              schema:
                type: integer
            Retry-After:
              description: "Seconds to wait before retrying."
              schema:
                type: integer
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        500:
          description: "Internal server error"
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
  /api/v1/portfolio/congress-ranking:
    get:
      operationId: listCongressRanking
      tags:
        - portfolio
      security:
        - bearerAuth:
[]
      summary: "Congress portfolio ranking"
      description: "Returns ranked congressional portfolio performance."
      x-codeSamples:
        curl: "curl \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  \"https://insidercat.com/api/v1/portfolio/congress-ranking?period=6M&party=All&sort_by=perf_score&sort_dir=desc&limit=1\""
        python: "import requests\n\nAPI_KEY = \"YOUR_API_KEY\"\nresponse = requests.get(\n    \"https://insidercat.com/api/v1/portfolio/congress-ranking\",\n    headers={\"Authorization\": f\"Bearer {API_KEY}\"},\n    params={\"period\": \"6M\", \"party\": \"All\", \"sort_by\": \"perf_score\", \"sort_dir\": \"desc\", \"limit\": 1},\n)\nprint(response.json())"
        typescript: "const API_KEY = \"YOUR_API_KEY\";\nconst params = new URLSearchParams({\n  period: \"6M\",\n  party: \"All\",\n  sort_by: \"perf_score\",\n  sort_dir: \"desc\",\n  limit: \"1\",\n});\nconst response = await fetch(`https://insidercat.com/api/v1/portfolio/congress-ranking?${params}`, {\n  headers: { Authorization: `Bearer ${API_KEY}` },\n});\nconsole.log(await response.json());"
      parameters:
        - "$ref": "#/components/parameters/period"
        - "$ref": "#/components/parameters/party"
        - "$ref": "#/components/parameters/min_portfolio_value"
        - name: sort_by
          in: query
          required: false
          schema:
            type: string
            enum:
              - position_size
              - daily_return
              - total_return
              - perf_score
        - "$ref": "#/components/parameters/sort_dir"
        - "$ref": "#/components/parameters/limit"
        - "$ref": "#/components/parameters/cursor"
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  "$ref": "#/components/schemas/CongressRankingRow"
              examples:
                default:
                  value:
                    data:
                      - politician_bioguide_id: W000797
                        date: 2026-03-19
                        politician_full_name: "Debbie Wasserman Schultz"
                        politician_party: Democrat
                        politician_state: FL
                        politician_chamber: House
                        position_size: 185770.29
                        daily_return: -0.0029
                        daily_return_money: -558.28
                        total_return: 0.557
                        total_return_money: 66459.88
                        delay_adjusted_total_return: 0.6575
                        delay_adjusted_total_return_money: 66727.93
        401:
          description: Unauthorized
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        403:
          description: Forbidden
          headers:
            RateLimit-Limit:
              description: "Requests allowed per rolling 60s window for this API key."
              schema:
                type: integer
            RateLimit-Remaining:
              description: "Requests remaining in the current window."
              schema:
                type: integer
            RateLimit-Reset:
              description: "Seconds until the window resets."
              schema:
                type: integer
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        429:
          description: "Rate limited. Every authenticated /api/v1 response (2xx and error) carries RateLimit-Limit/Remaining/Reset headers (plus legacy X-RateLimit-* aliases) so clients can self-throttle; a 429 additionally carries Retry-After."
          headers:
            RateLimit-Limit:
              description: "Requests allowed per rolling 60s window for this API key."
              schema:
                type: integer
            RateLimit-Remaining:
              description: "Requests remaining in the current window."
              schema:
                type: integer
            RateLimit-Reset:
              description: "Seconds until the window resets."
              schema:
                type: integer
            Retry-After:
              description: "Seconds to wait before retrying."
              schema:
                type: integer
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        500:
          description: "Internal server error"
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
  "/api/v1/portfolio/{politician_bioguide_id}/performance":
    get:
      operationId: getPoliticianPortfolioPerformance
      tags:
        - portfolio
      security:
        - bearerAuth:
[]
      summary: "Politician portfolio performance"
      description: "Returns head-to-head day-by-day performance for a specific politician or portfolio group versus the S&P 500. politician_bioguide_id supports Bioguide IDs and group IDs: all-politicians, democrats, republicans."
      x-codeSamples:
        curl: "curl \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  \"https://insidercat.com/api/v1/portfolio/P000197/performance?roi_mode=original&min_date=2026-01-01&max_date=2026-03-19\""
        python: "import requests\n\nAPI_KEY = \"YOUR_API_KEY\"\nresponse = requests.get(\n    \"https://insidercat.com/api/v1/portfolio/P000197/performance\",\n    headers={\"Authorization\": f\"Bearer {API_KEY}\"},\n    params={\"roi_mode\": \"original\", \"min_date\": \"2026-01-01\", \"max_date\": \"2026-03-19\"},\n)\nprint(response.json())"
        typescript: "const API_KEY = \"YOUR_API_KEY\";\nconst params = new URLSearchParams({\n  roi_mode: \"original\",\n  min_date: \"2026-01-01\",\n  max_date: \"2026-03-19\",\n});\nconst response = await fetch(`https://insidercat.com/api/v1/portfolio/P000197/performance?${params}`, {\n  headers: { Authorization: `Bearer ${API_KEY}` },\n});\nconsole.log(await response.json());"
      parameters:
        - "$ref": "#/components/parameters/politicianBioguideIdPath"
        - "$ref": "#/components/parameters/roi_mode"
        - "$ref": "#/components/parameters/min_date"
        - "$ref": "#/components/parameters/max_date"
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  "$ref": "#/components/schemas/PoliticianPortfolioPerformanceRow"
              examples:
                default:
                  value:
                    data:
                      - date: 2026-03-19
                        politician_bioguide_id: P000197
                        daily_return: 0.0029
                        sp500_daily_return: 0.0021
                        cumulative_return: 0.2382
                        sp500_return: 0.0912
        401:
          description: Unauthorized
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        403:
          description: Forbidden
          headers:
            RateLimit-Limit:
              description: "Requests allowed per rolling 60s window for this API key."
              schema:
                type: integer
            RateLimit-Remaining:
              description: "Requests remaining in the current window."
              schema:
                type: integer
            RateLimit-Reset:
              description: "Seconds until the window resets."
              schema:
                type: integer
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        429:
          description: "Rate limited. Every authenticated /api/v1 response (2xx and error) carries RateLimit-Limit/Remaining/Reset headers (plus legacy X-RateLimit-* aliases) so clients can self-throttle; a 429 additionally carries Retry-After."
          headers:
            RateLimit-Limit:
              description: "Requests allowed per rolling 60s window for this API key."
              schema:
                type: integer
            RateLimit-Remaining:
              description: "Requests remaining in the current window."
              schema:
                type: integer
            RateLimit-Reset:
              description: "Seconds until the window resets."
              schema:
                type: integer
            Retry-After:
              description: "Seconds to wait before retrying."
              schema:
                type: integer
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        500:
          description: "Internal server error"
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
  "/api/v1/portfolio/{politician_bioguide_id}/holdings":
    get:
      operationId: listPoliticianPortfolioHoldings
      tags:
        - portfolio
      security:
        - bearerAuth:
[]
      summary: "Politician live portfolio holdings"
      description: "Returns live holdings for a specific politician or portfolio group. politician_bioguide_id supports Bioguide IDs and group IDs: all-politicians, democrats, republicans."
      x-codeSamples:
        curl: "curl \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  \"https://insidercat.com/api/v1/portfolio/all-politicians/holdings?roi_mode=delay-adjusted&min_date=2026-01-01&max_date=2026-03-19&sort_by=position_size&sort_dir=desc&limit=1\""
        python: "import requests\n\nAPI_KEY = \"YOUR_API_KEY\"\nresponse = requests.get(\n    \"https://insidercat.com/api/v1/portfolio/all-politicians/holdings\",\n    headers={\"Authorization\": f\"Bearer {API_KEY}\"},\n    params={\"roi_mode\": \"delay-adjusted\", \"min_date\": \"2026-01-01\", \"max_date\": \"2026-03-19\", \"sort_by\": \"position_size\", \"sort_dir\": \"desc\", \"limit\": 1},\n)\nprint(response.json())"
        typescript: "const API_KEY = \"YOUR_API_KEY\";\nconst params = new URLSearchParams({\n  roi_mode: \"delay-adjusted\",\n  min_date: \"2026-01-01\",\n  max_date: \"2026-03-19\",\n  sort_by: \"position_size\",\n  sort_dir: \"desc\",\n  limit: \"1\",\n});\nconst response = await fetch(`https://insidercat.com/api/v1/portfolio/all-politicians/holdings?${params}`, {\n  headers: { Authorization: `Bearer ${API_KEY}` },\n});\nconsole.log(await response.json());"
      parameters:
        - "$ref": "#/components/parameters/politicianBioguideIdPath"
        - "$ref": "#/components/parameters/roi_mode"
        - "$ref": "#/components/parameters/min_date"
        - "$ref": "#/components/parameters/max_date"
        - name: sort_by
          in: query
          required: false
          schema:
            type: string
            enum:
              - portfolio_weight
              - position_size
              - daily_return
              - total_return
            default: portfolio_weight
        - "$ref": "#/components/parameters/sort_dir"
        - "$ref": "#/components/parameters/limit"
        - "$ref": "#/components/parameters/cursor"
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  "$ref": "#/components/schemas/PoliticianPortfolioHoldingRow"
              examples:
                default:
                  value:
                    data:
                      - date: 2026-03-19
                        politician_bioguide_id: all-politicians
                        ticker: AAPL
                        company_name: "Apple Inc."
                        avg_price: 198.12
                        current_price: 212.45
                        position_size: 9240000
                        portfolio_weight: 0.0805
                        daily_return: 0.0062
                        daily_return_money: 57150
                        total_return: 0.0723
                        total_return_money: 620910
        401:
          description: Unauthorized
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        403:
          description: Forbidden
          headers:
            RateLimit-Limit:
              description: "Requests allowed per rolling 60s window for this API key."
              schema:
                type: integer
            RateLimit-Remaining:
              description: "Requests remaining in the current window."
              schema:
                type: integer
            RateLimit-Reset:
              description: "Seconds until the window resets."
              schema:
                type: integer
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        429:
          description: "Rate limited. Every authenticated /api/v1 response (2xx and error) carries RateLimit-Limit/Remaining/Reset headers (plus legacy X-RateLimit-* aliases) so clients can self-throttle; a 429 additionally carries Retry-After."
          headers:
            RateLimit-Limit:
              description: "Requests allowed per rolling 60s window for this API key."
              schema:
                type: integer
            RateLimit-Remaining:
              description: "Requests remaining in the current window."
              schema:
                type: integer
            RateLimit-Reset:
              description: "Seconds until the window resets."
              schema:
                type: integer
            Retry-After:
              description: "Seconds to wait before retrying."
              schema:
                type: integer
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        500:
          description: "Internal server error"
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
  /api/v1/portfolio/trump/performance:
    get:
      operationId: listTrumpPortfolioPerformance
      tags:
        - portfolio
      security:
        - bearerAuth:
[]
      summary: "Trump portfolio performance"
      description: "Returns head-to-head day-by-day performance for the Trump portfolio versus benchmarks. Returns are Time-Weighted Returns (TWR), the industry-standard method for measuring stock-picking performance independent of cash flows. When min_date/max_date are used, rows are filtered by date but cumulative/total returns are not rebased or rescaled."
      x-codeSamples:
        curl: "curl \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  \"https://insidercat.com/api/v1/portfolio/trump/performance?min_date=2026-01-01&max_date=2026-03-19\""
        python: "import requests\n\nAPI_KEY = \"YOUR_API_KEY\"\nresponse = requests.get(\n    \"https://insidercat.com/api/v1/portfolio/trump/performance\",\n    headers={\"Authorization\": f\"Bearer {API_KEY}\"},\n    params={\"min_date\": \"2026-01-01\", \"max_date\": \"2026-03-19\"},\n)\nprint(response.json())"
        typescript: "const API_KEY = \"YOUR_API_KEY\";\nconst params = new URLSearchParams({\n  min_date: \"2026-01-01\",\n  max_date: \"2026-03-19\",\n});\nconst response = await fetch(`https://insidercat.com/api/v1/portfolio/trump/performance?${params}`, {\n  headers: { Authorization: `Bearer ${API_KEY}` },\n});\nconsole.log(await response.json());"
      parameters:
        - "$ref": "#/components/parameters/min_date"
        - "$ref": "#/components/parameters/max_date"
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  "$ref": "#/components/schemas/TrumpPortfolioPerformanceRow"
              examples:
                default:
                  value:
                    data:
                      - date: 2026-03-19
                        total_value: 152430000
                        bond_value: 37650000
                        position_size: 114780000
                        daily_return: 0.0041
                        cumulative_return: 0.2388
                        sp500_return: 0.0912
                        all_equity_return: 0.2614
        401:
          description: Unauthorized
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        403:
          description: Forbidden
          headers:
            RateLimit-Limit:
              description: "Requests allowed per rolling 60s window for this API key."
              schema:
                type: integer
            RateLimit-Remaining:
              description: "Requests remaining in the current window."
              schema:
                type: integer
            RateLimit-Reset:
              description: "Seconds until the window resets."
              schema:
                type: integer
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        429:
          description: "Rate limited. Every authenticated /api/v1 response (2xx and error) carries RateLimit-Limit/Remaining/Reset headers (plus legacy X-RateLimit-* aliases) so clients can self-throttle; a 429 additionally carries Retry-After."
          headers:
            RateLimit-Limit:
              description: "Requests allowed per rolling 60s window for this API key."
              schema:
                type: integer
            RateLimit-Remaining:
              description: "Requests remaining in the current window."
              schema:
                type: integer
            RateLimit-Reset:
              description: "Seconds until the window resets."
              schema:
                type: integer
            Retry-After:
              description: "Seconds to wait before retrying."
              schema:
                type: integer
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        500:
          description: "Internal server error"
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
  /api/v1/portfolio/trump/holdings:
    get:
      operationId: listTrumpPortfolioHoldings
      tags:
        - portfolio
      security:
        - bearerAuth:
[]
      summary: "Trump live portfolio holdings"
      description: "Returns the latest live holdings for the Trump portfolio."
      x-codeSamples:
        curl: "curl \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  \"https://insidercat.com/api/v1/portfolio/trump/holdings?sort_by=total_value&sort_dir=desc&limit=1\""
        python: "import requests\n\nAPI_KEY = \"YOUR_API_KEY\"\nresponse = requests.get(\n    \"https://insidercat.com/api/v1/portfolio/trump/holdings\",\n    headers={\"Authorization\": f\"Bearer {API_KEY}\"},\n    params={\"sort_by\": \"total_value\", \"sort_dir\": \"desc\", \"limit\": 1},\n)\nprint(response.json())"
        typescript: "const API_KEY = \"YOUR_API_KEY\";\nconst params = new URLSearchParams({\n  sort_by: \"total_value\",\n  sort_dir: \"desc\",\n  limit: \"1\",\n});\nconst response = await fetch(`https://insidercat.com/api/v1/portfolio/trump/holdings?${params}`, {\n  headers: { Authorization: `Bearer ${API_KEY}` },\n});\nconsole.log(await response.json());"
      parameters:
        - name: sort_by
          in: query
          required: false
          schema:
            type: string
            enum:
              - portfolio_weight
              - total_value
              - stock_value
              - bond_value
              - daily_return
              - total_return
              - total_return_money
            default: total_value
        - "$ref": "#/components/parameters/sort_dir"
        - "$ref": "#/components/parameters/limit"
        - "$ref": "#/components/parameters/cursor"
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  "$ref": "#/components/schemas/PortfolioHoldingRow"
              examples:
                default:
                  value:
                    data:
                      - ticker: AAPL
                        company_name: "Apple Inc."
                        date: 2026-03-19
                        avg_price: 198.12
                        current_price: 212.45
                        stock_value: 9240000
                        bond_value: 0
                        total_value: 9240000
                        portfolio_weight: 0.0805
                        daily_return: 0.0062
                        daily_return_money: 57150
                        total_return: 0.0723
                        total_return_money: 620910
        401:
          description: Unauthorized
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        403:
          description: Forbidden
          headers:
            RateLimit-Limit:
              description: "Requests allowed per rolling 60s window for this API key."
              schema:
                type: integer
            RateLimit-Remaining:
              description: "Requests remaining in the current window."
              schema:
                type: integer
            RateLimit-Reset:
              description: "Seconds until the window resets."
              schema:
                type: integer
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        429:
          description: "Rate limited. Every authenticated /api/v1 response (2xx and error) carries RateLimit-Limit/Remaining/Reset headers (plus legacy X-RateLimit-* aliases) so clients can self-throttle; a 429 additionally carries Retry-After."
          headers:
            RateLimit-Limit:
              description: "Requests allowed per rolling 60s window for this API key."
              schema:
                type: integer
            RateLimit-Remaining:
              description: "Requests remaining in the current window."
              schema:
                type: integer
            RateLimit-Reset:
              description: "Seconds until the window resets."
              schema:
                type: integer
            Retry-After:
              description: "Seconds to wait before retrying."
              schema:
                type: integer
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        500:
          description: "Internal server error"
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
  /api/v1/portfolio/trump-admin/performance:
    get:
      operationId: listTrumpAdminPortfolioPerformance
      tags:
        - portfolio
      security:
        - bearerAuth:
[]
      summary: "Trump admin portfolio performance"
      description: "Returns head-to-head day-by-day performance for the Trump administration portfolio versus benchmarks. Returns are Time-Weighted Returns (TWR), the industry-standard method for measuring stock-picking performance independent of cash flows. When min_date/max_date are used, rows are filtered by date but cumulative/total returns are not rebased or rescaled."
      x-codeSamples:
        curl: "curl \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  \"https://insidercat.com/api/v1/portfolio/trump-admin/performance?min_date=2026-01-01&max_date=2026-03-19\""
        python: "import requests\n\nAPI_KEY = \"YOUR_API_KEY\"\nresponse = requests.get(\n    \"https://insidercat.com/api/v1/portfolio/trump-admin/performance\",\n    headers={\"Authorization\": f\"Bearer {API_KEY}\"},\n    params={\"min_date\": \"2026-01-01\", \"max_date\": \"2026-03-19\"},\n)\nprint(response.json())"
        typescript: "const API_KEY = \"YOUR_API_KEY\";\nconst params = new URLSearchParams({\n  min_date: \"2026-01-01\",\n  max_date: \"2026-03-19\",\n});\nconst response = await fetch(`https://insidercat.com/api/v1/portfolio/trump-admin/performance?${params}`, {\n  headers: { Authorization: `Bearer ${API_KEY}` },\n});\nconsole.log(await response.json());"
      parameters:
        - "$ref": "#/components/parameters/min_date"
        - "$ref": "#/components/parameters/max_date"
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  "$ref": "#/components/schemas/TrumpAdminPortfolioPerformanceRow"
              examples:
                default:
                  value:
                    data:
                      - date: 2026-03-19
                        position_size: 483200000
                        cash_flow: 0
                        daily_return: 0.0036
                        cumulative_return: 0.1499
                        sp500_daily_return: 0.0021
                        sp500_return: 0.0912
        401:
          description: Unauthorized
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        403:
          description: Forbidden
          headers:
            RateLimit-Limit:
              description: "Requests allowed per rolling 60s window for this API key."
              schema:
                type: integer
            RateLimit-Remaining:
              description: "Requests remaining in the current window."
              schema:
                type: integer
            RateLimit-Reset:
              description: "Seconds until the window resets."
              schema:
                type: integer
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        429:
          description: "Rate limited. Every authenticated /api/v1 response (2xx and error) carries RateLimit-Limit/Remaining/Reset headers (plus legacy X-RateLimit-* aliases) so clients can self-throttle; a 429 additionally carries Retry-After."
          headers:
            RateLimit-Limit:
              description: "Requests allowed per rolling 60s window for this API key."
              schema:
                type: integer
            RateLimit-Remaining:
              description: "Requests remaining in the current window."
              schema:
                type: integer
            RateLimit-Reset:
              description: "Seconds until the window resets."
              schema:
                type: integer
            Retry-After:
              description: "Seconds to wait before retrying."
              schema:
                type: integer
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        500:
          description: "Internal server error"
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
  /api/v1/portfolio/trump-admin/holdings:
    get:
      operationId: listTrumpAdminPortfolioHoldings
      tags:
        - portfolio
      security:
        - bearerAuth:
[]
      summary: "Trump admin live portfolio holdings"
      description: "Returns the latest live holdings for the Trump administration portfolio."
      x-codeSamples:
        curl: "curl \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  \"https://insidercat.com/api/v1/portfolio/trump-admin/holdings?sort_by=total_value&sort_dir=desc&limit=1\""
        python: "import requests\n\nAPI_KEY = \"YOUR_API_KEY\"\nresponse = requests.get(\n    \"https://insidercat.com/api/v1/portfolio/trump-admin/holdings\",\n    headers={\"Authorization\": f\"Bearer {API_KEY}\"},\n    params={\"sort_by\": \"total_value\", \"sort_dir\": \"desc\", \"limit\": 1},\n)\nprint(response.json())"
        typescript: "const API_KEY = \"YOUR_API_KEY\";\nconst params = new URLSearchParams({\n  sort_by: \"total_value\",\n  sort_dir: \"desc\",\n  limit: \"1\",\n});\nconst response = await fetch(`https://insidercat.com/api/v1/portfolio/trump-admin/holdings?${params}`, {\n  headers: { Authorization: `Bearer ${API_KEY}` },\n});\nconsole.log(await response.json());"
      parameters:
        - name: sort_by
          in: query
          required: false
          schema:
            type: string
            enum:
              - portfolio_weight
              - total_value
              - stock_value
              - bond_value
              - daily_return
              - total_return
              - total_return_money
            default: total_value
        - "$ref": "#/components/parameters/sort_dir"
        - "$ref": "#/components/parameters/limit"
        - "$ref": "#/components/parameters/cursor"
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  "$ref": "#/components/schemas/PortfolioHoldingRow"
              examples:
                default:
                  value:
                    data:
                      - ticker: LMT
                        company_name: "Lockheed Martin Corporation"
                        date: 2026-03-19
                        avg_price: 481.2
                        current_price: 499.1
                        stock_value: 14650000
                        bond_value: 0
                        total_value: 14650000
                        portfolio_weight: 0.0303
                        daily_return: 0.0028
                        daily_return_money: 41020
                        total_return: 0.0975
                        total_return_money: 1302975
        401:
          description: Unauthorized
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        403:
          description: Forbidden
          headers:
            RateLimit-Limit:
              description: "Requests allowed per rolling 60s window for this API key."
              schema:
                type: integer
            RateLimit-Remaining:
              description: "Requests remaining in the current window."
              schema:
                type: integer
            RateLimit-Reset:
              description: "Seconds until the window resets."
              schema:
                type: integer
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        429:
          description: "Rate limited. Every authenticated /api/v1 response (2xx and error) carries RateLimit-Limit/Remaining/Reset headers (plus legacy X-RateLimit-* aliases) so clients can self-throttle; a 429 additionally carries Retry-After."
          headers:
            RateLimit-Limit:
              description: "Requests allowed per rolling 60s window for this API key."
              schema:
                type: integer
            RateLimit-Remaining:
              description: "Requests remaining in the current window."
              schema:
                type: integer
            RateLimit-Reset:
              description: "Seconds until the window resets."
              schema:
                type: integer
            Retry-After:
              description: "Seconds to wait before retrying."
              schema:
                type: integer
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        500:
          description: "Internal server error"
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
  /api/v1/mentions/trump:
    get:
      operationId: listTrumpMentions
      tags:
        - mentions
      security:
        - bearerAuth:
[]
      summary: "Trump stock mentions"
      description: "Returns a paginated list of stock tickers mentioned by Donald Trump, with sentiment and ROI since the mention."
      x-codeSamples:
        curl: "curl \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  \"https://insidercat.com/api/v1/mentions/trump?sentiment=bullish&sort_by=mention_date&sort_dir=desc&limit=1\""
        python: "import requests\n\nAPI_KEY = \"YOUR_API_KEY\"\nresponse = requests.get(\n    \"https://insidercat.com/api/v1/mentions/trump\",\n    headers={\"Authorization\": f\"Bearer {API_KEY}\"},\n    params={\"sentiment\": \"bullish\", \"sort_by\": \"mention_date\", \"sort_dir\": \"desc\", \"limit\": 1},\n)\nprint(response.json())"
        typescript: "const API_KEY = \"YOUR_API_KEY\";\nconst params = new URLSearchParams({\n  sentiment: \"bullish\",\n  sort_by: \"mention_date\",\n  sort_dir: \"desc\",\n  limit: \"1\",\n});\nconst response = await fetch(`https://insidercat.com/api/v1/mentions/trump?${params}`, {\n  headers: { Authorization: `Bearer ${API_KEY}` },\n});\nconsole.log(await response.json());"
      parameters:
        - "$ref": "#/components/parameters/mention_sentiment"
        - "$ref": "#/components/parameters/mention_search"
        - name: sort_by
          in: query
          required: false
          schema:
            type: string
            enum:
              - mention_date
              - daily_roi
              - roi_1m
              - roi_since
            default: mention_date
        - "$ref": "#/components/parameters/sort_dir"
        - "$ref": "#/components/parameters/limit"
        - "$ref": "#/components/parameters/cursor"
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/PaginatedTrumpMentions"
              examples:
                default:
                  value:
                    data:
                      - ticker: NVDA
                        sentiment: bullish
                        mention_date: 2026-03-18
                        mention_price: 187.32
                        current_price: 212.45
                        daily_roi: 0.0124
                        roi_1m: 0.0871
                        roi_since: 0.1342
                        title: "Trump touts AI chip leadership in Oval Office remarks"
                        quote: "Nvidia is doing incredible, incredible things for this country."
                        source: https://example.com/news/trump-nvidia-remarks
                        doc_id: truth-social-2026-03-18-0091
        401:
          description: Unauthorized
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        403:
          description: Forbidden
          headers:
            RateLimit-Limit:
              description: "Requests allowed per rolling 60s window for this API key."
              schema:
                type: integer
            RateLimit-Remaining:
              description: "Requests remaining in the current window."
              schema:
                type: integer
            RateLimit-Reset:
              description: "Seconds until the window resets."
              schema:
                type: integer
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        429:
          description: "Rate limited. Every authenticated /api/v1 response (2xx and error) carries RateLimit-Limit/Remaining/Reset headers (plus legacy X-RateLimit-* aliases) so clients can self-throttle; a 429 additionally carries Retry-After."
          headers:
            RateLimit-Limit:
              description: "Requests allowed per rolling 60s window for this API key."
              schema:
                type: integer
            RateLimit-Remaining:
              description: "Requests remaining in the current window."
              schema:
                type: integer
            RateLimit-Reset:
              description: "Seconds until the window resets."
              schema:
                type: integer
            Retry-After:
              description: "Seconds to wait before retrying."
              schema:
                type: integer
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        500:
          description: "Internal server error"
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
  /api/v1/portfolio/trump-mentions/performance:
    get:
      operationId: listTrumpMentionsPortfolioPerformance
      tags:
        - portfolio
      security:
        - bearerAuth:
[]
      summary: "Trump mentions portfolio performance"
      description: "Returns head-to-head day-by-day performance for a portfolio tracking stocks mentioned by Donald Trump, versus the S&P 500. Returns are Time-Weighted Returns (TWR), the industry-standard method for measuring stock-picking performance independent of cash flows. When min_date/max_date are used, rows are filtered by date but cumulative/total returns are not rebased or rescaled."
      x-codeSamples:
        curl: "curl \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  \"https://insidercat.com/api/v1/portfolio/trump-mentions/performance?min_date=2026-01-01&max_date=2026-03-19\""
        python: "import requests\n\nAPI_KEY = \"YOUR_API_KEY\"\nresponse = requests.get(\n    \"https://insidercat.com/api/v1/portfolio/trump-mentions/performance\",\n    headers={\"Authorization\": f\"Bearer {API_KEY}\"},\n    params={\"min_date\": \"2026-01-01\", \"max_date\": \"2026-03-19\"},\n)\nprint(response.json())"
        typescript: "const API_KEY = \"YOUR_API_KEY\";\nconst params = new URLSearchParams({\n  min_date: \"2026-01-01\",\n  max_date: \"2026-03-19\",\n});\nconst response = await fetch(`https://insidercat.com/api/v1/portfolio/trump-mentions/performance?${params}`, {\n  headers: { Authorization: `Bearer ${API_KEY}` },\n});\nconsole.log(await response.json());"
      parameters:
        - "$ref": "#/components/parameters/min_date"
        - "$ref": "#/components/parameters/max_date"
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  "$ref": "#/components/schemas/TrumpMentionsPortfolioPerformanceRow"
              examples:
                default:
                  value:
                    data:
                      - date: 2026-03-19
                        position_size: 48250000
                        cash_flow: 0
                        daily_return: 0.0052
                        cumulative_return: 0.1836
                        sp500_daily_return: 0.0021
                        sp500_return: 0.0912
        401:
          description: Unauthorized
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        403:
          description: Forbidden
          headers:
            RateLimit-Limit:
              description: "Requests allowed per rolling 60s window for this API key."
              schema:
                type: integer
            RateLimit-Remaining:
              description: "Requests remaining in the current window."
              schema:
                type: integer
            RateLimit-Reset:
              description: "Seconds until the window resets."
              schema:
                type: integer
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        429:
          description: "Rate limited. Every authenticated /api/v1 response (2xx and error) carries RateLimit-Limit/Remaining/Reset headers (plus legacy X-RateLimit-* aliases) so clients can self-throttle; a 429 additionally carries Retry-After."
          headers:
            RateLimit-Limit:
              description: "Requests allowed per rolling 60s window for this API key."
              schema:
                type: integer
            RateLimit-Remaining:
              description: "Requests remaining in the current window."
              schema:
                type: integer
            RateLimit-Reset:
              description: "Seconds until the window resets."
              schema:
                type: integer
            Retry-After:
              description: "Seconds to wait before retrying."
              schema:
                type: integer
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        500:
          description: "Internal server error"
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
  /api/v1/portfolio/trump-mentions/holdings:
    get:
      operationId: listTrumpMentionsPortfolioHoldings
      tags:
        - portfolio
      security:
        - bearerAuth:
[]
      summary: "Trump mentions live portfolio holdings"
      description: "Returns the latest live holdings for a portfolio tracking stocks mentioned by Donald Trump."
      x-codeSamples:
        curl: "curl \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  \"https://insidercat.com/api/v1/portfolio/trump-mentions/holdings?sort_by=total_value&sort_dir=desc&limit=1\""
        python: "import requests\n\nAPI_KEY = \"YOUR_API_KEY\"\nresponse = requests.get(\n    \"https://insidercat.com/api/v1/portfolio/trump-mentions/holdings\",\n    headers={\"Authorization\": f\"Bearer {API_KEY}\"},\n    params={\"sort_by\": \"total_value\", \"sort_dir\": \"desc\", \"limit\": 1},\n)\nprint(response.json())"
        typescript: "const API_KEY = \"YOUR_API_KEY\";\nconst params = new URLSearchParams({\n  sort_by: \"total_value\",\n  sort_dir: \"desc\",\n  limit: \"1\",\n});\nconst response = await fetch(`https://insidercat.com/api/v1/portfolio/trump-mentions/holdings?${params}`, {\n  headers: { Authorization: `Bearer ${API_KEY}` },\n});\nconsole.log(await response.json());"
      parameters:
        - name: sort_by
          in: query
          required: false
          schema:
            type: string
            enum:
              - portfolio_weight
              - total_value
              - stock_value
              - bond_value
              - daily_return
              - total_return
              - total_return_money
            default: total_value
        - "$ref": "#/components/parameters/sort_dir"
        - "$ref": "#/components/parameters/limit"
        - "$ref": "#/components/parameters/cursor"
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  "$ref": "#/components/schemas/PortfolioHoldingRow"
              examples:
                default:
                  value:
                    data:
                      - ticker: NVDA
                        company_name: "NVIDIA Corporation"
                        date: 2026-03-19
                        avg_price: 165.4
                        current_price: 212.45
                        stock_value: 6120000
                        bond_value: 0
                        total_value: 6120000
                        portfolio_weight: 0.1269
                        daily_return: 0.0071
                        daily_return_money: 43450
                        total_return: 0.2844
                        total_return_money: 1354830
        401:
          description: Unauthorized
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        403:
          description: Forbidden
          headers:
            RateLimit-Limit:
              description: "Requests allowed per rolling 60s window for this API key."
              schema:
                type: integer
            RateLimit-Remaining:
              description: "Requests remaining in the current window."
              schema:
                type: integer
            RateLimit-Reset:
              description: "Seconds until the window resets."
              schema:
                type: integer
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        429:
          description: "Rate limited. Every authenticated /api/v1 response (2xx and error) carries RateLimit-Limit/Remaining/Reset headers (plus legacy X-RateLimit-* aliases) so clients can self-throttle; a 429 additionally carries Retry-After."
          headers:
            RateLimit-Limit:
              description: "Requests allowed per rolling 60s window for this API key."
              schema:
                type: integer
            RateLimit-Remaining:
              description: "Requests remaining in the current window."
              schema:
                type: integer
            RateLimit-Reset:
              description: "Seconds until the window resets."
              schema:
                type: integer
            Retry-After:
              description: "Seconds to wait before retrying."
              schema:
                type: integer
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        500:
          description: "Internal server error"
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
  /api/v1/portfolio/defense/performance:
    get:
      operationId: listDefensePortfolioPerformance
      tags:
        - portfolio
      security:
        - bearerAuth:
[]
      summary: "Defense portfolio performance"
      description: "Returns head-to-head day-by-day performance for the defense portfolio versus S&P 500 and party subgroups. Returns are Time-Weighted Returns (TWR), the industry-standard method for measuring stock-picking performance independent of cash flows. When min_date/max_date are used, rows are filtered by date but cumulative/total returns are not rebased or rescaled."
      x-codeSamples:
        curl: "curl \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  \"https://insidercat.com/api/v1/portfolio/defense/performance?roi_mode=original&min_date=2026-01-01&max_date=2026-03-19\""
        python: "import requests\n\nAPI_KEY = \"YOUR_API_KEY\"\nresponse = requests.get(\n    \"https://insidercat.com/api/v1/portfolio/defense/performance\",\n    headers={\"Authorization\": f\"Bearer {API_KEY}\"},\n    params={\"roi_mode\": \"original\", \"min_date\": \"2026-01-01\", \"max_date\": \"2026-03-19\"},\n)\nprint(response.json())"
        typescript: "const API_KEY = \"YOUR_API_KEY\";\nconst params = new URLSearchParams({\n  roi_mode: \"original\",\n  min_date: \"2026-01-01\",\n  max_date: \"2026-03-19\",\n});\nconst response = await fetch(`https://insidercat.com/api/v1/portfolio/defense/performance?${params}`, {\n  headers: { Authorization: `Bearer ${API_KEY}` },\n});\nconsole.log(await response.json());"
      parameters:
        - "$ref": "#/components/parameters/roi_mode"
        - "$ref": "#/components/parameters/min_date"
        - "$ref": "#/components/parameters/max_date"
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  "$ref": "#/components/schemas/DefensePortfolioPerformanceRow"
              examples:
                default:
                  value:
                    data:
                      - date: 2026-03-19
                        position_size: 619500000
                        cash_flow: 0
                        daily_return: 0.0031
                        cumulative_return: 0.1214
                        sp500_daily_return: 0.0021
                        sp500_return: 0.0912
                        democrat_return: 0.1044
                        republican_return: 0.1368
        401:
          description: Unauthorized
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        403:
          description: Forbidden
          headers:
            RateLimit-Limit:
              description: "Requests allowed per rolling 60s window for this API key."
              schema:
                type: integer
            RateLimit-Remaining:
              description: "Requests remaining in the current window."
              schema:
                type: integer
            RateLimit-Reset:
              description: "Seconds until the window resets."
              schema:
                type: integer
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        429:
          description: "Rate limited. Every authenticated /api/v1 response (2xx and error) carries RateLimit-Limit/Remaining/Reset headers (plus legacy X-RateLimit-* aliases) so clients can self-throttle; a 429 additionally carries Retry-After."
          headers:
            RateLimit-Limit:
              description: "Requests allowed per rolling 60s window for this API key."
              schema:
                type: integer
            RateLimit-Remaining:
              description: "Requests remaining in the current window."
              schema:
                type: integer
            RateLimit-Reset:
              description: "Seconds until the window resets."
              schema:
                type: integer
            Retry-After:
              description: "Seconds to wait before retrying."
              schema:
                type: integer
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        500:
          description: "Internal server error"
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
  /api/v1/portfolio/defense/holdings:
    get:
      operationId: listDefensePortfolioHoldings
      tags:
        - portfolio
      security:
        - bearerAuth:
[]
      summary: "Defense live portfolio holdings"
      description: "Returns the latest live holdings for the defense portfolio."
      x-codeSamples:
        curl: "curl \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  \"https://insidercat.com/api/v1/portfolio/defense/holdings?roi_mode=delay-adjusted&sort_by=total_value&sort_dir=desc&limit=1\""
        python: "import requests\n\nAPI_KEY = \"YOUR_API_KEY\"\nresponse = requests.get(\n    \"https://insidercat.com/api/v1/portfolio/defense/holdings\",\n    headers={\"Authorization\": f\"Bearer {API_KEY}\"},\n    params={\"roi_mode\": \"delay-adjusted\", \"sort_by\": \"total_value\", \"sort_dir\": \"desc\", \"limit\": 1},\n)\nprint(response.json())"
        typescript: "const API_KEY = \"YOUR_API_KEY\";\nconst params = new URLSearchParams({\n  roi_mode: \"delay-adjusted\",\n  sort_by: \"total_value\",\n  sort_dir: \"desc\",\n  limit: \"1\",\n});\nconst response = await fetch(`https://insidercat.com/api/v1/portfolio/defense/holdings?${params}`, {\n  headers: { Authorization: `Bearer ${API_KEY}` },\n});\nconsole.log(await response.json());"
      parameters:
        - "$ref": "#/components/parameters/roi_mode"
        - name: sort_by
          in: query
          required: false
          schema:
            type: string
            enum:
              - portfolio_weight
              - total_value
              - stock_value
              - bond_value
              - daily_return
              - total_return
              - total_return_money
            default: total_value
        - "$ref": "#/components/parameters/sort_dir"
        - "$ref": "#/components/parameters/limit"
        - "$ref": "#/components/parameters/cursor"
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  "$ref": "#/components/schemas/PortfolioHoldingRow"
              examples:
                default:
                  value:
                    data:
                      - ticker: RTX
                        company_name: "RTX Corporation"
                        date: 2026-03-19
                        avg_price: 104.7
                        current_price: 115.2
                        stock_value: 18200000
                        bond_value: 0
                        total_value: 18200000
                        portfolio_weight: 0.0294
                        daily_return: 0.0035
                        daily_return_money: 63607.37
                        total_return: 0.1003
                        total_return_money: 1660276.11
        401:
          description: Unauthorized
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        403:
          description: Forbidden
          headers:
            RateLimit-Limit:
              description: "Requests allowed per rolling 60s window for this API key."
              schema:
                type: integer
            RateLimit-Remaining:
              description: "Requests remaining in the current window."
              schema:
                type: integer
            RateLimit-Reset:
              description: "Seconds until the window resets."
              schema:
                type: integer
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        429:
          description: "Rate limited. Every authenticated /api/v1 response (2xx and error) carries RateLimit-Limit/Remaining/Reset headers (plus legacy X-RateLimit-* aliases) so clients can self-throttle; a 429 additionally carries Retry-After."
          headers:
            RateLimit-Limit:
              description: "Requests allowed per rolling 60s window for this API key."
              schema:
                type: integer
            RateLimit-Remaining:
              description: "Requests remaining in the current window."
              schema:
                type: integer
            RateLimit-Reset:
              description: "Seconds until the window resets."
              schema:
                type: integer
            Retry-After:
              description: "Seconds to wait before retrying."
              schema:
                type: integer
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        500:
          description: "Internal server error"
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
  "/api/v1/stock/{ticker}/ownership":
    get:
      operationId: getStockOwnership
      tags:
        - stock
      security:
        - bearerAuth:
[]
      summary: "Stock ownership by ticker"
      description: "Returns live ownership positions for a ticker."
      x-codeSamples:
        curl: "curl \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  \"https://insidercat.com/api/v1/stock/NVDA/ownership?sort_by=position_size&sort_dir=desc&limit=1\""
        python: "import requests\n\nAPI_KEY = \"YOUR_API_KEY\"\nresponse = requests.get(\n    \"https://insidercat.com/api/v1/stock/NVDA/ownership\",\n    headers={\"Authorization\": f\"Bearer {API_KEY}\"},\n    params={\"sort_by\": \"position_size\", \"sort_dir\": \"desc\", \"limit\": 1},\n)\nprint(response.json())"
        typescript: "const API_KEY = \"YOUR_API_KEY\";\n  const params = new URLSearchParams({\n  sort_by: \"position_size\",\n  sort_dir: \"desc\",\n  limit: \"1\",\n});\nconst response = await fetch(`https://insidercat.com/api/v1/stock/NVDA/ownership?${params}`, {\n  headers: { Authorization: `Bearer ${API_KEY}` },\n});\nconsole.log(await response.json());"
      parameters:
        - "$ref": "#/components/parameters/tickerPath"
        - name: sort_by
          in: query
          required: false
          schema:
            type: string
            enum:
              - position_size
              - portfolio_weight
              - avg_price
              - current_price
              - daily_return
              - total_return
              - delay_adjusted_total_return
            default: position_size
        - "$ref": "#/components/parameters/sort_dir"
        - "$ref": "#/components/parameters/limit"
        - "$ref": "#/components/parameters/cursor"
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  "$ref": "#/components/schemas/StockOwnershipRow"
              examples:
                default:
                  value:
                    data:
                      - politician_bioguide_id: F000110
                        politician_full_name: "Cleo Fields"
                        politician_party: Democrat
                        politician_chamber: House
                        politician_state: LA
                        position_size: 2041937.19
                        portfolio_weight: 0.0925
                        avg_price: 224.39
                        current_price: 248.84
                        daily_return: -0.0043
                        daily_return_money: -9013.21
                        total_return: 0.1089
                        total_return_money: 200582.5
                        delay_adjusted_total_return: 0.1089
                        delay_adjusted_total_return_money: 200582.5
        401:
          description: Unauthorized
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        403:
          description: Forbidden
          headers:
            RateLimit-Limit:
              description: "Requests allowed per rolling 60s window for this API key."
              schema:
                type: integer
            RateLimit-Remaining:
              description: "Requests remaining in the current window."
              schema:
                type: integer
            RateLimit-Reset:
              description: "Seconds until the window resets."
              schema:
                type: integer
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        429:
          description: "Rate limited. Every authenticated /api/v1 response (2xx and error) carries RateLimit-Limit/Remaining/Reset headers (plus legacy X-RateLimit-* aliases) so clients can self-throttle; a 429 additionally carries Retry-After."
          headers:
            RateLimit-Limit:
              description: "Requests allowed per rolling 60s window for this API key."
              schema:
                type: integer
            RateLimit-Remaining:
              description: "Requests remaining in the current window."
              schema:
                type: integer
            RateLimit-Reset:
              description: "Seconds until the window resets."
              schema:
                type: integer
            Retry-After:
              description: "Seconds to wait before retrying."
              schema:
                type: integer
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
        500:
          description: "Internal server error"
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorEnvelope"
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: "API Key"
      description: "Use Authorization: Bearer <API_KEY>"
  parameters:
    tickerPath:
      name: ticker
      in: path
      required: true
      description: "Ticker symbol, e.g. AAPL"
      schema:
        type: string
        minLength: 1
    politicianBioguideIdPath:
      name: politician_bioguide_id
      in: path
      required: true
      description: "Official congressional Bioguide ID (for example P000197). For portfolio endpoints, group IDs are also supported: all-politicians, democrats, republicans."
      schema:
        type: string
        minLength: 1
    trade_type:
      name: trade_type
      in: query
      required: false
      schema:
        type: string
        enum:
          - ALL
          - BUY
          - SELL
        default: ALL
    tickerQuery:
      name: ticker
      in: query
      required: false
      description: "Case-insensitive exact ticker filter"
      schema:
        type: string
    politicianBioguideIdQuery:
      name: politician_bioguide_id
      in: query
      required: false
      description: "Filter by a specific member of Congress using their official Bioguide ID (for example, P000197 for Nancy Pelosi). Matching is case-insensitive and exact."
      schema:
        type: string
    min_value_number:
      name: min_value
      in: query
      required: false
      description: "Minimum reported trade lower bound in USD"
      schema:
        type: number
        minimum: 0
        default: 0
    min_portfolio_value:
      name: min_portfolio_value
      in: query
      required: false
      description: "Minimum portfolio value lower bound in USD"
      schema:
        type: number
        minimum: 0
        default: 0
    period:
      name: period
      in: query
      required: false
      schema:
        type: string
        enum:
          - 1M
          - 3M
          - 6M
          - 1Y
          - 3Y
        default: 6M
    party:
      name: party
      in: query
      required: false
      schema:
        type: string
        enum:
          - All
          - Democrat
          - Republican
          - Independent
        default: All
    min_traded_date:
      name: min_traded_date
      in: query
      required: false
      schema:
        type: string
      description: "YYYY-MM-DD inclusive lower bound"
    max_traded_date:
      name: max_traded_date
      in: query
      required: false
      schema:
        type: string
      description: "YYYY-MM-DD inclusive upper bound"
    min_reported_date:
      name: min_reported_date
      in: query
      required: false
      schema:
        type: string
      description: "YYYY-MM-DD inclusive lower bound"
    max_reported_date:
      name: max_reported_date
      in: query
      required: false
      schema:
        type: string
      description: "YYYY-MM-DD inclusive upper bound"
    min_date:
      name: min_date
      in: query
      required: false
      schema:
        type: string
      description: "YYYY-MM-DD inclusive lower bound on portfolio snapshot date"
    max_date:
      name: max_date
      in: query
      required: false
      schema:
        type: string
      description: "YYYY-MM-DD inclusive upper bound on portfolio snapshot date"
    sort_dir:
      name: sort_dir
      in: query
      required: false
      schema:
        type: string
        enum:
          - asc
          - desc
        default: desc
    limit:
      name: limit
      in: query
      required: false
      description: "Number of records to return per page."
      schema:
        type: integer
        minimum: 1
        maximum: 50
        default: 25
    cursor:
      name: cursor
      in: query
      required: false
      description: "Offset cursor; use next_cursor from previous response"
      schema:
        type: integer
        minimum: 0
        default: 0
    roi_mode:
      name: roi_mode
      in: query
      required: false
      description: "Return mode for ROI calculations."
      schema:
        type: string
        enum:
          - original
          - delay-adjusted
        default: original
    mention_sentiment:
      name: sentiment
      in: query
      required: false
      description: "Filter by mention sentiment."
      schema:
        type: string
        enum:
          - All
          - bullish
          - bearish
          - neutral
        default: All
    mention_search:
      name: search
      in: query
      required: false
      description: "Case-insensitive search over the mention's ticker."
      schema:
        type: string
  schemas:
    ErrorEnvelope:
      type: object
      properties:
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
              enum:
                - unauthorized
                - forbidden
                - rate_limited
                - invalid_request
                - not_found
                - internal_error
            message:
              type: string
            limit:
              type: number
            resetAt:
              type: string
              format: date-time
          additionalProperties: true
      required:
        - error
      additionalProperties: false
    HealthData:
      type: object
      required:
        - status
        - service
        - version
        - timestamp
      properties:
        status:
          type: string
          example: ok
        service:
          type: string
          example: insidercat-public-api
        version:
          type: string
          example: v1
        timestamp:
          type: string
          format: date-time
      additionalProperties: false
    PublicCapabilitiesData:
      type: object
      required:
        - service
        - version
        - base_url
        - openapi_url
        - developer_portal_url
        - api_reference_url
        - versioning_policy_url
        - llms_txt_url
        - mcp_manifest_url
        - mcp_streamable_http_url
        - authentication
        - datasets
        - best_for
      properties:
        service:
          type: string
          example: insidercat-public-capabilities
        version:
          type: string
          example: v1
        base_url:
          type: string
          format: uri
        openapi_url:
          type: string
          format: uri
        developer_portal_url:
          type: string
          format: uri
        api_reference_url:
          type: string
          format: uri
        versioning_policy_url:
          type: string
          format: uri
        llms_txt_url:
          type: string
          format: uri
        mcp_manifest_url:
          type: string
          format: uri
        mcp_streamable_http_url:
          type: string
          format: uri
        authentication:
          type: object
          required:
            - type
            - header
            - notes
          properties:
            type:
              type: string
              enum:
                - bearer
            header:
              type: string
              example: Authorization
            notes:
              type: string
          additionalProperties: false
        datasets:
          type: array
          items:
            type: string
          description: "InsiderCat dataset families available through documented API or MCP tools."
        best_for:
          type: array
          items:
            type: string
          description: "Recommended integration use cases for agents and developers."
      additionalProperties: false
    InsiderTrade:
      type: object
      properties:
        ticker:
          type: string
          description: "Stock ticker symbol in uppercase."
        company_name:
          type: string
          description: "Company name associated with the ticker."
        traded_date:
          type: string
          description: "Execution date of the trade (YYYY-MM-DD)."
        reported_date:
          type: string
          description: "Filing/report date of the trade (YYYY-MM-DD)."
        trade_type:
          type: string
          enum:
            - BUY
            - SELL
          description: "Direction of the transaction."
        owner_name:
          type: string
          description: "Name of the insider who reported the trade."
        owner_title:
          type: string
          description: "Role of the insider (for example Director or Officer)."
        amount:
          type: number
          description: "Estimated number of shares traded."
        price:
          type: number
          description: "Estimated per-share price in USD."
        value:
          type: number
          description: "Estimated total trade value in USD."
      required:
        - ticker
        - company_name
        - traded_date
        - reported_date
        - trade_type
      additionalProperties: true
    PoliticianTrade:
      type: object
      properties:
        ticker:
          type: string
          description: "Stock ticker symbol in uppercase."
        company_name:
          type: string
          description: "Company name associated with the ticker."
        traded_date:
          type: string
          description: "Execution date of the disclosed trade (YYYY-MM-DD)."
        reported_date:
          type: string
          description: "Filing/report date of the disclosure (YYYY-MM-DD)."
        trade_type:
          type: string
          enum:
            - BUY
            - SELL
          description: "Direction of the transaction."
        size_lower:
          type: number
          description: "Lower bound of the disclosed trade-size range in USD."
        size_upper:
          type: number
          description: "Upper bound of the disclosed trade-size range in USD."
        price_adj_close_traded:
          type: number
          nullable: true
          description: "Adjusted closing price on (or nearest trading day before) the traded date, in USD."
        price_adj_close_reported:
          type: number
          nullable: true
          description: "Adjusted closing price on (or nearest trading day before) the reported date, in USD."
        politician_bioguide_id:
          type: string
          description: "Official congressional Bioguide identifier (for example P000197)."
        politician_full_name:
          type: string
          description: "Full name of the filing member."
        politician_party:
          type: string
          description: "Political party at filing time."
        politician_chamber:
          type: string
          description: "Congress chamber (House or Senate)."
        politician_state:
          type: string
          description: "Two-letter state or territory code."
      required:
        - ticker
        - company_name
        - traded_date
        - reported_date
        - trade_type
      additionalProperties: true
    PoliticianSentimentRow:
      type: object
      properties:
        ticker:
          type: string
          description: "Stock ticker symbol in uppercase."
        company_name:
          type: string
          description: "Company name associated with the ticker."
        num_republicans_buying:
          type: integer
          description: "Distinct Republican members with buy disclosures."
        num_republicans_selling:
          type: integer
          description: "Distinct Republican members with sell disclosures."
        num_democrats_buying:
          type: integer
          description: "Distinct Democratic members with buy disclosures."
        num_democrats_selling:
          type: integer
          description: "Distinct Democratic members with sell disclosures."
        total_bought:
          type: number
          description: "Estimated aggregate disclosed buy value in USD."
        total_sold:
          type: number
          description: "Estimated aggregate disclosed sell value in USD."
        total_volume:
          type: number
          description: "Estimated aggregate disclosed buy+sell value in USD."
        net_volume:
          type: number
          description: "Estimated net flow in USD (`total_bought - total_sold`)."
      required:
        - ticker
        - company_name
      additionalProperties: true
    InsiderSentimentRow:
      type: object
      properties:
        ticker:
          type: string
          description: "Stock ticker symbol in uppercase."
        company_name:
          type: string
          description: "Company name associated with the ticker."
        num_insiders_buy:
          type: integer
          description: "Distinct insiders with buy filings."
        num_insiders_sell:
          type: integer
          description: "Distinct insiders with sell filings."
        total_bought:
          type: number
          description: "Estimated aggregate filed buy value in USD."
        total_sold:
          type: number
          description: "Estimated aggregate filed sell value in USD."
        total_volume:
          type: number
          description: "Estimated aggregate buy+sell value in USD."
        net_volume:
          type: number
          description: "Estimated net flow in USD (`total_bought - total_sold`)."
      required:
        - ticker
        - company_name
      additionalProperties: true
    CongressRankingRow:
      type: object
      properties:
        politician_bioguide_id:
          type: string
          description: "Official congressional Bioguide identifier."
        date:
          type: string
          description: "As-of date for all metrics (YYYY-MM-DD)."
        politician_full_name:
          type: string
          description: "Full name of the member."
        politician_party:
          type: string
          description: "Political party at as-of date."
        politician_state:
          type: string
          description: "Two-letter state or territory code."
        politician_chamber:
          type: string
          description: "Congress chamber (House or Senate)."
        position_size:
          type: number
          description: "Estimated current portfolio market value in USD."
        daily_return:
          type: number
          description: "Estimated daily portfolio return ratio (for example 0.01 = +1%)."
        daily_return_money:
          type: number
          description: "Estimated daily portfolio return in USD."
        total_return:
          type: number
          description: "Estimated cumulative return ratio over the selected period."
        total_return_money:
          type: number
          description: "Estimated cumulative return in USD over the selected period."
        delay_adjusted_total_return:
          type: number
          description: "Estimated cumulative return ratio adjusted for filing-delay effects."
        delay_adjusted_total_return_money:
          type: number
          description: "Estimated cumulative return in USD adjusted for filing-delay effects."
      required:
        - politician_bioguide_id
        - date
        - politician_full_name
      additionalProperties: true
    StockOwnershipRow:
      type: object
      properties:
        politician_bioguide_id:
          type: string
          description: "Official congressional Bioguide identifier."
        politician_full_name:
          type: string
          description: "Full name of the member."
        politician_party:
          type: string
          description: "Political party at as-of date."
        politician_chamber:
          type: string
          description: "Congress chamber (House or Senate)."
        politician_state:
          type: string
          description: "Two-letter state or territory code."
        position_size:
          type: number
          description: "Estimated market value of this ticker position in USD."
        portfolio_weight:
          type: number
          description: "Estimated portfolio allocation weight for this ticker (0-1)."
        avg_price:
          type: number
          description: "Estimated weighted-average acquisition price in USD."
        current_price:
          type: number
          description: "Latest market price used for valuation in USD."
        daily_return:
          type: number
          description: "Estimated daily return ratio for this ticker position."
        daily_return_money:
          type: number
          description: "Estimated daily return in USD for this ticker position."
        total_return:
          type: number
          description: "Estimated cumulative return ratio for this ticker position."
        total_return_money:
          type: number
          description: "Estimated cumulative return in USD for this ticker position."
        delay_adjusted_total_return:
          type: number
          description: "Estimated cumulative return ratio adjusted for disclosure delays."
        delay_adjusted_total_return_money:
          type: number
          description: "Estimated cumulative return in USD adjusted for disclosure delays."
      required:
        - politician_bioguide_id
        - politician_full_name
        - position_size
      additionalProperties: true
    TrumpPortfolioPerformanceRow:
      type: object
      properties:
        date:
          type: string
          description: "Portfolio snapshot date at end of day (YYYY-MM-DD)."
        position_size:
          type: number
          description: "Estimated total equity portfolio value in USD."
        cash_flow:
          type: number
          description: "Estimated net daily cash flow in USD when available."
        bond_value:
          type: number
          description: "Estimated bond allocation value in USD when available."
        total_value:
          type: number
          description: "Estimated total portfolio value in USD when available."
        daily_return:
          type: number
          description: "Portfolio daily Time-Weighted Return (TWR)."
        cumulative_return:
          type: number
          description: "Portfolio cumulative Time-Weighted Return (TWR) from series start."
        sp500_daily_return:
          type: number
          description: "S&P 500 daily Time-Weighted Return (TWR)."
        sp500_return:
          type: number
          description: "S&P 500 cumulative Time-Weighted Return (TWR) from series start."
        all_equity_return:
          type: number
          description: "Trump portfolio cumulative return under all-equity assumption."
      required:
        - date
        - daily_return
      additionalProperties: true
    TrumpAdminPortfolioPerformanceRow:
      type: object
      properties:
        date:
          type: string
          description: "Portfolio snapshot date at end of day (YYYY-MM-DD)."
        position_size:
          type: number
          description: "Estimated total equity portfolio value in USD."
        cash_flow:
          type: number
          description: "Estimated net daily cash flow in USD when available."
        bond_value:
          type: number
          description: "Estimated bond allocation value in USD when available."
        total_value:
          type: number
          description: "Estimated total portfolio value in USD when available."
        daily_return:
          type: number
          description: "Portfolio daily Time-Weighted Return (TWR)."
        cumulative_return:
          type: number
          description: "Portfolio cumulative Time-Weighted Return (TWR) from series start."
        sp500_daily_return:
          type: number
          description: "S&P 500 daily Time-Weighted Return (TWR)."
        sp500_return:
          type: number
          description: "S&P 500 cumulative Time-Weighted Return (TWR) from series start."
      required:
        - date
        - daily_return
      additionalProperties: true
    TrumpMentionsPortfolioPerformanceRow:
      type: object
      properties:
        date:
          type: string
          description: "Portfolio snapshot date at end of day (YYYY-MM-DD)."
        position_size:
          type: number
          description: "Estimated total equity portfolio value in USD."
        cash_flow:
          type: number
          description: "Estimated net daily cash flow in USD when available."
        daily_return:
          type: number
          description: "Portfolio daily Time-Weighted Return (TWR)."
        cumulative_return:
          type: number
          description: "Portfolio cumulative Time-Weighted Return (TWR) from series start."
        sp500_daily_return:
          type: number
          description: "S&P 500 daily Time-Weighted Return (TWR)."
        sp500_return:
          type: number
          description: "S&P 500 cumulative Time-Weighted Return (TWR) from series start."
      required:
        - date
        - daily_return
      additionalProperties: true
    DefensePortfolioPerformanceRow:
      type: object
      properties:
        date:
          type: string
          description: "Portfolio snapshot date at end of day (YYYY-MM-DD)."
        position_size:
          type: number
          description: "Estimated total equity portfolio value in USD."
        cash_flow:
          type: number
          description: "Estimated net daily cash flow in USD when available."
        bond_value:
          type: number
          description: "Estimated bond allocation value in USD when available."
        total_value:
          type: number
          description: "Estimated total portfolio value in USD when available."
        daily_return:
          type: number
          description: "Portfolio daily Time-Weighted Return (TWR)."
        cumulative_return:
          type: number
          description: "Portfolio cumulative Time-Weighted Return (TWR) from series start."
        sp500_daily_return:
          type: number
          description: "S&P 500 daily Time-Weighted Return (TWR)."
        sp500_return:
          type: number
          description: "S&P 500 cumulative Time-Weighted Return (TWR) from series start."
        democrat_return:
          type: number
          description: "Democrat subgroup cumulative return ratio (defense endpoint)."
        republican_return:
          type: number
          description: "Republican subgroup cumulative return ratio (defense endpoint)."
      required:
        - date
        - daily_return
      additionalProperties: true
    PoliticianPortfolioPerformanceRow:
      type: object
      properties:
        date:
          type: string
          description: "Portfolio snapshot date at end of day (YYYY-MM-DD)."
        politician_bioguide_id:
          type: string
          description: "Official congressional Bioguide identifier or group ID."
        daily_return:
          type: number
          description: "Portfolio daily Time-Weighted Return (TWR)."
        sp500_daily_return:
          type: number
          description: "S&P 500 daily Time-Weighted Return (TWR)."
        cumulative_return:
          type: number
          description: "Portfolio cumulative Time-Weighted Return (TWR) from series start."
        sp500_return:
          type: number
          description: "S&P 500 cumulative Time-Weighted Return (TWR) from series start."
      required:
        - date
        - politician_bioguide_id
        - daily_return
      additionalProperties: true
    PoliticianPortfolioHoldingRow:
      type: object
      properties:
        date:
          type: string
          description: "Portfolio snapshot date at end of day (YYYY-MM-DD)."
        politician_bioguide_id:
          type: string
          description: "Official congressional Bioguide identifier or group ID."
        ticker:
          type: string
          description: "Stock ticker symbol in uppercase."
        company_name:
          type: string
          description: "Company name associated with the ticker."
        avg_price:
          type: number
          description: "Estimated weighted-average acquisition price in USD."
        current_price:
          type: number
          description: "Latest market price used for valuation in USD."
        position_size:
          type: number
          description: "Estimated position value in USD."
        portfolio_weight:
          type: number
          description: "Estimated portfolio allocation weight for this ticker (0-1)."
        daily_return:
          type: number
          description: "Estimated daily return ratio for this position."
        daily_return_money:
          type: number
          description: "Estimated daily return in USD for this position."
        total_return:
          type: number
          description: "Estimated cumulative return ratio for this position."
        total_return_money:
          type: number
          description: "Estimated cumulative return in USD for this position."
      required:
        - date
        - politician_bioguide_id
        - ticker
        - company_name
        - position_size
      additionalProperties: true
    PortfolioHoldingRow:
      type: object
      properties:
        ticker:
          type: string
          description: "Stock ticker symbol in uppercase."
        company_name:
          type: string
          description: "Company name associated with the ticker."
        date:
          type: string
          description: "Portfolio snapshot date at end of day (YYYY-MM-DD)."
        avg_price:
          type: number
          description: "Estimated weighted-average acquisition price in USD."
        current_price:
          type: number
          description: "Latest market price used for valuation in USD."
        stock_value:
          type: number
          description: "Estimated equity value in USD."
        bond_value:
          type: number
          description: "Estimated bond value in USD."
        total_value:
          type: number
          description: "Estimated total position value in USD."
        portfolio_weight:
          type: number
          description: "Estimated portfolio allocation weight for this ticker (0-1)."
        daily_return:
          type: number
          description: "Estimated daily return ratio for this position."
        daily_return_money:
          type: number
          description: "Estimated daily return in USD for this position."
        total_return:
          type: number
          description: "Estimated cumulative return ratio for this position."
        total_return_money:
          type: number
          description: "Estimated cumulative return in USD for this position."
      required:
        - ticker
        - company_name
        - date
        - total_value
      additionalProperties: true
    PaginatedPortfolioHoldings:
      type: object
      required:
        - data
        - total_count
        - next_cursor
      properties:
        data:
          type: array
          description: "Page of holdings rows for the requested portfolio."
          items:
            "$ref": "#/components/schemas/PortfolioHoldingRow"
        total_count:
          type: integer
          description: "Total number of records available for the query."
        next_cursor:
          type:
            - integer
            - null
          description: "Cursor value for the next page; `null` when no more pages exist."
      additionalProperties: false
    TrumpMentionRow:
      type: object
      properties:
        ticker:
          type: string
          description: "Stock ticker symbol in uppercase."
        sentiment:
          type: string
          description: "Sentiment of the mention (bullish, bearish, or neutral)."
        mention_date:
          type: string
          description: "Date the mention occurred (YYYY-MM-DD)."
        mention_price:
          type:
            - number
            - null
          description: "Closing price on the mention date, when available."
        current_price:
          type:
            - number
            - null
          description: "Latest known market price, when available."
        daily_roi:
          type:
            - number
            - null
          description: "Return ratio for the trading day of the mention."
        roi_1m:
          type:
            - number
            - null
          description: "Return ratio one month after the mention."
        roi_since:
          type:
            - number
            - null
          description: "Cumulative return ratio since the mention date."
        title:
          type: string
          description: "Headline or title of the source document."
        quote:
          type:
            - string
            - null
          description: "Excerpt containing the mention."
        source:
          type:
            - string
            - null
          description: "Name or URL of the source."
        doc_id:
          type: string
          description: "Identifier of the source document."
      required:
        - ticker
        - sentiment
        - mention_date
        - title
        - doc_id
      additionalProperties: true
    PaginatedTrumpMentions:
      type: object
      required:
        - data
        - total_count
        - next_cursor
      properties:
        data:
          type: array
          description: "Page of Trump mention rows matching request filters and sort order."
          items:
            "$ref": "#/components/schemas/TrumpMentionRow"
        total_count:
          type: integer
          description: "Total number of records available for the query."
        next_cursor:
          type:
            - integer
            - null
          description: "Cursor value for the next page; `null` when no more pages exist."
      additionalProperties: false
    PaginatedPoliticianPortfolioHoldings:
      type: object
      required:
        - data
        - total_count
        - next_cursor
      properties:
        data:
          type: array
          description: "Page of holdings rows for the requested politician or group."
          items:
            "$ref": "#/components/schemas/PoliticianPortfolioHoldingRow"
        total_count:
          type: integer
          description: "Total number of records available for the query."
        next_cursor:
          type:
            - integer
            - null
          description: "Cursor value for the next page; `null` when no more pages exist."
      additionalProperties: false
    PaginatedInsiderTrades:
      type: object
      required:
        - data
        - total_count
        - next_cursor
      properties:
        data:
          type: array
          description: "Page of insider trades matching request filters and sort order."
          items:
            "$ref": "#/components/schemas/InsiderTrade"
        total_count:
          type: integer
          description: "Total number of records available for the query."
        next_cursor:
          type:
            - integer
            - null
          description: "Cursor value for the next page; `null` when no more pages exist."
      additionalProperties: false
    PaginatedPoliticianTrades:
      type: object
      required:
        - data
        - total_count
        - next_cursor
      properties:
        data:
          type: array
          description: "Page of politician trades matching request filters and sort order."
          items:
            "$ref": "#/components/schemas/PoliticianTrade"
        total_count:
          type: integer
          description: "Total number of records available for the query."
        next_cursor:
          type:
            - integer
            - null
          description: "Cursor value for the next page; `null` when no more pages exist."
      additionalProperties: false
    PaginatedPoliticianSentiment:
      type: object
      required:
        - data
        - total_count
        - next_cursor
      properties:
        data:
          type: array
          description: "Page of politician sentiment aggregates by ticker."
          items:
            "$ref": "#/components/schemas/PoliticianSentimentRow"
        total_count:
          type: integer
          description: "Total number of records available for the query."
        next_cursor:
          type:
            - integer
            - null
          description: "Cursor value for the next page; `null` when no more pages exist."
      additionalProperties: false
    PaginatedInsiderSentiment:
      type: object
      required:
        - data
        - total_count
        - next_cursor
      properties:
        data:
          type: array
          description: "Page of insider sentiment aggregates by ticker."
          items:
            "$ref": "#/components/schemas/InsiderSentimentRow"
        total_count:
          type: integer
          description: "Total number of records available for the query."
        next_cursor:
          type:
            - integer
            - null
          description: "Cursor value for the next page; `null` when no more pages exist."
      additionalProperties: false
    PaginatedCongressRanking:
      type: object
      required:
        - data
        - total_count
        - next_cursor
      properties:
        data:
          type: array
          description: "Page of ranked congressional portfolio rows."
          items:
            "$ref": "#/components/schemas/CongressRankingRow"
        total_count:
          type: integer
          description: "Total number of records available for the query."
        next_cursor:
          type:
            - integer
            - null
          description: "Cursor value for the next page; `null` when no more pages exist."
      additionalProperties: false
    PaginatedStockOwnership:
      type: object
      required:
        - data
        - total_count
        - next_cursor
      properties:
        data:
          type: array
          description: "Page of ownership rows for the requested stock ticker."
          items:
            "$ref": "#/components/schemas/StockOwnershipRow"
        total_count:
          type: integer
          description: "Total number of records available for the query."
        next_cursor:
          type:
            - integer
            - null
          description: "Cursor value for the next page; `null` when no more pages exist."
      additionalProperties: false
    HealthEnvelope:
      type: object
      required:
        - data
      properties:
        data:
          "$ref": "#/components/schemas/HealthData"
      additionalProperties: false
    PublicCapabilitiesEnvelope:
      type: object
      required:
        - data
      properties:
        data:
          "$ref": "#/components/schemas/PublicCapabilitiesData"
      additionalProperties: false
    InsiderTradesEnvelope:
      type: object
      required:
        - data
      properties:
        data:
          "$ref": "#/components/schemas/PaginatedInsiderTrades"
          description: "Paginated insider-trade payload."
      additionalProperties: false
    PoliticianTradesEnvelope:
      type: object
      required:
        - data
      properties:
        data:
          "$ref": "#/components/schemas/PaginatedPoliticianTrades"
          description: "Paginated politician-trade payload."
      additionalProperties: false
    PoliticianSentimentEnvelope:
      type: object
      required:
        - data
      properties:
        data:
          "$ref": "#/components/schemas/PaginatedPoliticianSentiment"
          description: "Paginated politician sentiment payload."
      additionalProperties: false
    InsiderSentimentEnvelope:
      type: object
      required:
        - data
      properties:
        data:
          "$ref": "#/components/schemas/PaginatedInsiderSentiment"
          description: "Paginated insider sentiment payload."
      additionalProperties: false
    CongressRankingEnvelope:
      type: object
      required:
        - data
      properties:
        data:
          "$ref": "#/components/schemas/PaginatedCongressRanking"
          description: "Paginated congress ranking payload."
      additionalProperties: false
    StockOwnershipEnvelope:
      type: object
      required:
        - data
      properties:
        data:
          "$ref": "#/components/schemas/PaginatedStockOwnership"
          description: "Paginated stock ownership payload."
      additionalProperties: false
    PortfolioPerformanceEnvelope:
      type: object
      required:
        - data
      properties:
        data:
          type: array
          items:
            oneOf:
              - "$ref": "#/components/schemas/TrumpPortfolioPerformanceRow"
              - "$ref": "#/components/schemas/TrumpAdminPortfolioPerformanceRow"
              - "$ref": "#/components/schemas/DefensePortfolioPerformanceRow"
              - "$ref": "#/components/schemas/PoliticianPortfolioPerformanceRow"
      additionalProperties: false
    PortfolioHoldingsEnvelope:
      type: object
      required:
        - data
      properties:
        data:
          "$ref": "#/components/schemas/PaginatedPortfolioHoldings"
          description: "Paginated portfolio holdings payload."
      additionalProperties: false
    PoliticianPortfolioHoldingsEnvelope:
      type: object
      required:
        - data
      properties:
        data:
          "$ref": "#/components/schemas/PaginatedPoliticianPortfolioHoldings"
          description: "Paginated politician portfolio holdings payload."
      additionalProperties: false
