openapi: 3.1.0
info:
  title: MarketService API
  version: 1.0.0
security:
  - WorldMonitorKey: []
  - ApiKeyHeader: []
servers:
  - url: https://api.worldmonitor.app
paths:
  /api/market/v1/list-market-quotes:
    get:
      tags:
        - MarketService
      summary: ListMarketQuotes
      description: ListMarketQuotes retrieves stock and index quotes.
      operationId: ListMarketQuotes
      parameters:
        - name: symbols
          in: query
          description: >-
            Ticker symbols to retrieve (e.g., ["AAPL", "^GSPC"]). Empty returns
            defaults.
          required: false
          style: form
          explode: true
          example:
            - AAPL
          schema:
            type: array
            items:
              type: string
        - name: jmespath
          in: query
          description: >-
            Optional JMESPath expression applied server-side to project or
            reduce the JSON response before it is returned (mirrors the MCP
            jmespath argument). Invalid expressions, expressions larger than
            1024 UTF-8 bytes, or projections that exceed the 256 KB output cap
            return HTTP 400 with a {_jmespath_error, original_keys} envelope.
            Grammar and worked examples:
            https://www.worldmonitor.app/docs/mcp-jmespath.
          required: false
          example: keys(@)
          schema:
            type: string
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              example:
                finnhubSkipped: true
                quotes:
                  - change: 1.5
                    display: example
                    name: WorldMonitor Analyst
                    price: 75.25
                    sparkline:
                      - 1.5
                    symbol: AAPL
                rateLimited: true
                skipReason: example
              schema:
                $ref: '#/components/schemas/ListMarketQuotesResponse'
        '400':
          description: Validation error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ValidationError'
                  - $ref: '#/components/schemas/JmespathProjectionError'
        '401':
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedError'
        '403':
          description: >-
            API access requires an active subscription (the API key's
            subscription is inactive or expired).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ForbiddenError'
        '429':
          description: Rate limit exceeded.
          headers:
            X-RateLimit-Limit:
              description: Maximum requests allowed in the active rate-limit window.
              schema:
                type: string
            X-RateLimit-Remaining:
              description: Requests remaining in the active rate-limit window.
              schema:
                type: string
            X-RateLimit-Reset:
              description: >-
                Unix epoch milliseconds when the active rate-limit window
                resets.
              schema:
                type: string
            Retry-After:
              description: Seconds to wait before retrying the request.
              schema:
                type: string
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/RateLimitError'
        default:
          description: Gateway or handler error response.
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/GatewayError'
  /api/market/v1/list-crypto-quotes:
    get:
      tags:
        - MarketService
      summary: ListCryptoQuotes
      description: ListCryptoQuotes retrieves cryptocurrency quotes from CoinGecko.
      operationId: ListCryptoQuotes
      parameters:
        - name: ids
          in: query
          description: >-
            Cryptocurrency IDs to retrieve (CoinGecko IDs). Empty returns
            defaults.
          required: false
          style: form
          explode: true
          example:
            - example
          schema:
            type: array
            items:
              type: string
        - name: jmespath
          in: query
          description: >-
            Optional JMESPath expression applied server-side to project or
            reduce the JSON response before it is returned (mirrors the MCP
            jmespath argument). Invalid expressions, expressions larger than
            1024 UTF-8 bytes, or projections that exceed the 256 KB output cap
            return HTTP 400 with a {_jmespath_error, original_keys} envelope.
            Grammar and worked examples:
            https://www.worldmonitor.app/docs/mcp-jmespath.
          required: false
          example: keys(@)
          schema:
            type: string
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              example:
                quotes:
                  - change: 1.5
                    change7d: 1.5
                    name: WorldMonitor Analyst
                    price: 75.25
                    sparkline:
                      - 1.5
                    symbol: AAPL
              schema:
                $ref: '#/components/schemas/ListCryptoQuotesResponse'
        '400':
          description: Validation error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ValidationError'
                  - $ref: '#/components/schemas/JmespathProjectionError'
        '401':
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedError'
        '403':
          description: >-
            API access requires an active subscription (the API key's
            subscription is inactive or expired).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ForbiddenError'
        '429':
          description: Rate limit exceeded.
          headers:
            X-RateLimit-Limit:
              description: Maximum requests allowed in the active rate-limit window.
              schema:
                type: string
            X-RateLimit-Remaining:
              description: Requests remaining in the active rate-limit window.
              schema:
                type: string
            X-RateLimit-Reset:
              description: >-
                Unix epoch milliseconds when the active rate-limit window
                resets.
              schema:
                type: string
            Retry-After:
              description: Seconds to wait before retrying the request.
              schema:
                type: string
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/RateLimitError'
        default:
          description: Gateway or handler error response.
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/GatewayError'
  /api/market/v1/list-commodity-quotes:
    get:
      tags:
        - MarketService
      summary: ListCommodityQuotes
      description: ListCommodityQuotes retrieves commodity price quotes from Yahoo Finance.
      operationId: ListCommodityQuotes
      parameters:
        - name: symbols
          in: query
          description: >-
            Commodity symbols to retrieve (Yahoo symbols). Empty returns
            defaults.
          required: false
          style: form
          explode: true
          example:
            - AAPL
          schema:
            type: array
            items:
              type: string
        - name: jmespath
          in: query
          description: >-
            Optional JMESPath expression applied server-side to project or
            reduce the JSON response before it is returned (mirrors the MCP
            jmespath argument). Invalid expressions, expressions larger than
            1024 UTF-8 bytes, or projections that exceed the 256 KB output cap
            return HTTP 400 with a {_jmespath_error, original_keys} envelope.
            Grammar and worked examples:
            https://www.worldmonitor.app/docs/mcp-jmespath.
          required: false
          example: keys(@)
          schema:
            type: string
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              example:
                quotes:
                  - change: 1.5
                    display: example
                    name: WorldMonitor Analyst
                    price: 75.25
                    sparkline:
                      - 1.5
                    symbol: AAPL
              schema:
                $ref: '#/components/schemas/ListCommodityQuotesResponse'
        '400':
          description: Validation error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ValidationError'
                  - $ref: '#/components/schemas/JmespathProjectionError'
        '401':
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedError'
        '403':
          description: >-
            API access requires an active subscription (the API key's
            subscription is inactive or expired).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ForbiddenError'
        '429':
          description: Rate limit exceeded.
          headers:
            X-RateLimit-Limit:
              description: Maximum requests allowed in the active rate-limit window.
              schema:
                type: string
            X-RateLimit-Remaining:
              description: Requests remaining in the active rate-limit window.
              schema:
                type: string
            X-RateLimit-Reset:
              description: >-
                Unix epoch milliseconds when the active rate-limit window
                resets.
              schema:
                type: string
            Retry-After:
              description: Seconds to wait before retrying the request.
              schema:
                type: string
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/RateLimitError'
        default:
          description: Gateway or handler error response.
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/GatewayError'
  /api/market/v1/get-sector-summary:
    get:
      tags:
        - MarketService
      summary: GetSectorSummary
      description: GetSectorSummary retrieves market sector performance data from Finnhub.
      operationId: GetSectorSummary
      parameters:
        - name: period
          in: query
          description: >-
            Time period for performance calculation (e.g., "1d", "1w", "1m").
            Defaults to "1d".
             Accepted but currently ignored; no-op until this handler supports the parameter.
          required: false
          example: 1d
          schema:
            type: string
        - name: jmespath
          in: query
          description: >-
            Optional JMESPath expression applied server-side to project or
            reduce the JSON response before it is returned (mirrors the MCP
            jmespath argument). Invalid expressions, expressions larger than
            1024 UTF-8 bytes, or projections that exceed the 256 KB output cap
            return HTTP 400 with a {_jmespath_error, original_keys} envelope.
            Grammar and worked examples:
            https://www.worldmonitor.app/docs/mcp-jmespath.
          required: false
          example: keys(@)
          schema:
            type: string
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              example:
                sectors:
                  - change: 1.5
                    name: WorldMonitor Analyst
                    symbol: AAPL
              schema:
                $ref: '#/components/schemas/GetSectorSummaryResponse'
        '400':
          description: Validation error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ValidationError'
                  - $ref: '#/components/schemas/JmespathProjectionError'
        '401':
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedError'
        '403':
          description: >-
            API access requires an active subscription (the API key's
            subscription is inactive or expired).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ForbiddenError'
        '429':
          description: Rate limit exceeded.
          headers:
            X-RateLimit-Limit:
              description: Maximum requests allowed in the active rate-limit window.
              schema:
                type: string
            X-RateLimit-Remaining:
              description: Requests remaining in the active rate-limit window.
              schema:
                type: string
            X-RateLimit-Reset:
              description: >-
                Unix epoch milliseconds when the active rate-limit window
                resets.
              schema:
                type: string
            Retry-After:
              description: Seconds to wait before retrying the request.
              schema:
                type: string
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/RateLimitError'
        default:
          description: Gateway or handler error response.
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/GatewayError'
  /api/market/v1/list-stablecoin-markets:
    get:
      tags:
        - MarketService
      summary: ListStablecoinMarkets
      description: >-
        ListStablecoinMarkets retrieves stablecoin peg health and market data
        from CoinGecko.
      operationId: ListStablecoinMarkets
      parameters:
        - name: coins
          in: query
          description: >-
            CoinGecko IDs to retrieve (e.g. "tether,usd-coin"). Empty returns
            defaults.
          required: false
          style: form
          explode: true
          example:
            - example
          schema:
            type: array
            items:
              type: string
        - name: jmespath
          in: query
          description: >-
            Optional JMESPath expression applied server-side to project or
            reduce the JSON response before it is returned (mirrors the MCP
            jmespath argument). Invalid expressions, expressions larger than
            1024 UTF-8 bytes, or projections that exceed the 256 KB output cap
            return HTTP 400 with a {_jmespath_error, original_keys} envelope.
            Grammar and worked examples:
            https://www.worldmonitor.app/docs/mcp-jmespath.
          required: false
          example: keys(@)
          schema:
            type: string
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              example:
                stablecoins:
                  - change24h: 1.5
                    change7d: 1.5
                    deviation: 1.5
                    id: example-id
                    image: example
                    marketCap: 1.5
                    symbol: AAPL
                summary:
                  coinCount: 1
                  depeggedCount: 1
                  healthStatus: example
                  totalMarketCap: 1
                  totalVolume24h: 1
                timestamp: '2026-01-15T12:00:00Z'
              schema:
                $ref: '#/components/schemas/ListStablecoinMarketsResponse'
        '400':
          description: Validation error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ValidationError'
                  - $ref: '#/components/schemas/JmespathProjectionError'
        '401':
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedError'
        '403':
          description: >-
            API access requires an active subscription (the API key's
            subscription is inactive or expired).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ForbiddenError'
        '429':
          description: Rate limit exceeded.
          headers:
            X-RateLimit-Limit:
              description: Maximum requests allowed in the active rate-limit window.
              schema:
                type: string
            X-RateLimit-Remaining:
              description: Requests remaining in the active rate-limit window.
              schema:
                type: string
            X-RateLimit-Reset:
              description: >-
                Unix epoch milliseconds when the active rate-limit window
                resets.
              schema:
                type: string
            Retry-After:
              description: Seconds to wait before retrying the request.
              schema:
                type: string
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/RateLimitError'
        default:
          description: Gateway or handler error response.
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/GatewayError'
  /api/market/v1/list-etf-flows:
    get:
      tags:
        - MarketService
      summary: ListEtfFlows
      description: ListEtfFlows retrieves BTC spot ETF flow estimates from Yahoo Finance.
      operationId: ListEtfFlows
      parameters:
        - name: jmespath
          in: query
          description: >-
            Optional JMESPath expression applied server-side to project or
            reduce the JSON response before it is returned (mirrors the MCP
            jmespath argument). Invalid expressions, expressions larger than
            1024 UTF-8 bytes, or projections that exceed the 256 KB output cap
            return HTTP 400 with a {_jmespath_error, original_keys} envelope.
            Grammar and worked examples:
            https://www.worldmonitor.app/docs/mcp-jmespath.
          required: false
          example: keys(@)
          schema:
            type: string
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              example:
                etfs:
                  - avgVolume: 1
                    direction: example
                    estFlow: 1
                    issuer: example
                    price: 75.25
                    ticker: AAPL
                rateLimited: true
                summary:
                  etfCount: 1
                  inflowCount: 1
                  netDirection: example
                  outflowCount: 1
                  totalEstFlow: 1
                timestamp: '2026-01-15T12:00:00Z'
              schema:
                $ref: '#/components/schemas/ListEtfFlowsResponse'
        '400':
          description: Validation error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ValidationError'
                  - $ref: '#/components/schemas/JmespathProjectionError'
        '401':
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedError'
        '403':
          description: >-
            API access requires an active subscription (the API key's
            subscription is inactive or expired).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ForbiddenError'
        '429':
          description: Rate limit exceeded.
          headers:
            X-RateLimit-Limit:
              description: Maximum requests allowed in the active rate-limit window.
              schema:
                type: string
            X-RateLimit-Remaining:
              description: Requests remaining in the active rate-limit window.
              schema:
                type: string
            X-RateLimit-Reset:
              description: >-
                Unix epoch milliseconds when the active rate-limit window
                resets.
              schema:
                type: string
            Retry-After:
              description: Seconds to wait before retrying the request.
              schema:
                type: string
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/RateLimitError'
        default:
          description: Gateway or handler error response.
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/GatewayError'
  /api/market/v1/get-country-stock-index:
    get:
      tags:
        - MarketService
      summary: GetCountryStockIndex
      description: >-
        GetCountryStockIndex retrieves the primary stock index for a country
        from Yahoo Finance.
      operationId: GetCountryStockIndex
      parameters:
        - name: country_code
          in: query
          description: ISO 3166-1 alpha-2 country code (e.g., "US", "GB", "JP").
          required: true
          example: US
          schema:
            type: string
            enum:
              - US
              - GB
              - DE
              - FR
              - JP
              - CN
              - HK
              - IN
              - KR
              - TW
              - AU
              - BR
              - CA
              - MX
              - AR
              - RU
              - ZA
              - SA
              - AE
              - IL
              - TR
              - PL
              - NL
              - CH
              - ES
              - IT
              - SE
              - 'NO'
              - SG
              - TH
              - MY
              - ID
              - PH
              - NZ
              - EG
              - CL
              - PE
              - AT
              - BE
              - FI
              - DK
              - IE
              - PT
              - CZ
              - HU
        - name: jmespath
          in: query
          description: >-
            Optional JMESPath expression applied server-side to project or
            reduce the JSON response before it is returned (mirrors the MCP
            jmespath argument). Invalid expressions, expressions larger than
            1024 UTF-8 bytes, or projections that exceed the 256 KB output cap
            return HTTP 400 with a {_jmespath_error, original_keys} envelope.
            Grammar and worked examples:
            https://www.worldmonitor.app/docs/mcp-jmespath.
          required: false
          example: keys(@)
          schema:
            type: string
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              example:
                available: true
                code: US
                currency: USD
                fetchedAt: '2026-01-15T12:00:00Z'
                indexName: WorldMonitor Analyst
              schema:
                $ref: '#/components/schemas/GetCountryStockIndexResponse'
        '400':
          description: Validation error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ValidationError'
                  - $ref: '#/components/schemas/JmespathProjectionError'
        '401':
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedError'
        '403':
          description: >-
            API access requires an active subscription (the API key's
            subscription is inactive or expired).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ForbiddenError'
        '429':
          description: Rate limit exceeded.
          headers:
            X-RateLimit-Limit:
              description: Maximum requests allowed in the active rate-limit window.
              schema:
                type: string
            X-RateLimit-Remaining:
              description: Requests remaining in the active rate-limit window.
              schema:
                type: string
            X-RateLimit-Reset:
              description: >-
                Unix epoch milliseconds when the active rate-limit window
                resets.
              schema:
                type: string
            Retry-After:
              description: Seconds to wait before retrying the request.
              schema:
                type: string
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/RateLimitError'
        default:
          description: Gateway or handler error response.
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/GatewayError'
  /api/market/v1/list-gulf-quotes:
    get:
      tags:
        - MarketService
      summary: ListGulfQuotes
      description: >-
        ListGulfQuotes retrieves Gulf region market quotes (indices, currencies,
        oil).
      operationId: ListGulfQuotes
      parameters:
        - name: jmespath
          in: query
          description: >-
            Optional JMESPath expression applied server-side to project or
            reduce the JSON response before it is returned (mirrors the MCP
            jmespath argument). Invalid expressions, expressions larger than
            1024 UTF-8 bytes, or projections that exceed the 256 KB output cap
            return HTTP 400 with a {_jmespath_error, original_keys} envelope.
            Grammar and worked examples:
            https://www.worldmonitor.app/docs/mcp-jmespath.
          required: false
          example: keys(@)
          schema:
            type: string
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              example:
                quotes:
                  - change: 1.5
                    country: US
                    flag: example
                    name: WorldMonitor Analyst
                    price: 75.25
                rateLimited: true
              schema:
                $ref: '#/components/schemas/ListGulfQuotesResponse'
        '400':
          description: Validation error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ValidationError'
                  - $ref: '#/components/schemas/JmespathProjectionError'
        '401':
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedError'
        '403':
          description: >-
            API access requires an active subscription (the API key's
            subscription is inactive or expired).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ForbiddenError'
        '429':
          description: Rate limit exceeded.
          headers:
            X-RateLimit-Limit:
              description: Maximum requests allowed in the active rate-limit window.
              schema:
                type: string
            X-RateLimit-Remaining:
              description: Requests remaining in the active rate-limit window.
              schema:
                type: string
            X-RateLimit-Reset:
              description: >-
                Unix epoch milliseconds when the active rate-limit window
                resets.
              schema:
                type: string
            Retry-After:
              description: Seconds to wait before retrying the request.
              schema:
                type: string
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/RateLimitError'
        default:
          description: Gateway or handler error response.
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/GatewayError'
  /api/market/v1/analyze-stock:
    get:
      tags:
        - MarketService
      summary: AnalyzeStock
      description: >-
        AnalyzeStock retrieves a premium stock analysis report with technicals,
        news, and AI synthesis. PRO-gated. Requires entitlement tier >= 1.
      operationId: AnalyzeStock
      security:
        - WorldMonitorKey: []
        - ApiKeyHeader: []
        - BearerAuth: []
      parameters:
        - name: symbol
          in: query
          description: Stock ticker symbol to analyze.
          required: true
          example: AAPL
          schema:
            type: string
        - name: name
          in: query
          description: Optional company display name used to disambiguate the symbol.
          required: false
          example: WorldMonitor Analyst
          schema:
            type: string
        - name: include_news
          in: query
          description: Whether to include recent news in the stock analysis.
          required: false
          example: true
          schema:
            type: boolean
        - name: jmespath
          in: query
          description: >-
            Optional JMESPath expression applied server-side to project or
            reduce the JSON response before it is returned (mirrors the MCP
            jmespath argument). Invalid expressions, expressions larger than
            1024 UTF-8 bytes, or projections that exceed the 256 KB output cap
            return HTTP 400 with a {_jmespath_error, original_keys} envelope.
            Grammar and worked examples:
            https://www.worldmonitor.app/docs/mcp-jmespath.
          required: false
          example: keys(@)
          schema:
            type: string
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              example:
                action: example
                analysisAt: 1717200000000
                analysisId: example-id
                analystConsensus:
                  buy: 1
                  hold: 1
                  period: daily
                  sell: 1
                  strongBuy: 1
                available: true
              schema:
                $ref: '#/components/schemas/AnalyzeStockResponse'
        '400':
          description: Validation error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ValidationError'
                  - $ref: '#/components/schemas/JmespathProjectionError'
        '401':
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedError'
        '403':
          description: PRO entitlement access denied.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ForbiddenError'
        '429':
          description: Rate limit exceeded.
          headers:
            X-RateLimit-Limit:
              description: Maximum requests allowed in the active rate-limit window.
              schema:
                type: string
            X-RateLimit-Remaining:
              description: Requests remaining in the active rate-limit window.
              schema:
                type: string
            X-RateLimit-Reset:
              description: >-
                Unix epoch milliseconds when the active rate-limit window
                resets.
              schema:
                type: string
            Retry-After:
              description: Seconds to wait before retrying the request.
              schema:
                type: string
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/RateLimitError'
        default:
          description: Gateway or handler error response.
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/GatewayError'
  /api/market/v1/get-stock-analysis-history:
    get:
      tags:
        - MarketService
      summary: GetStockAnalysisHistory
      description: >-
        GetStockAnalysisHistory retrieves shared premium stock analysis history
        from the backend store. PRO-gated. Requires entitlement tier >= 1.
      operationId: GetStockAnalysisHistory
      security:
        - WorldMonitorKey: []
        - ApiKeyHeader: []
        - BearerAuth: []
      parameters:
        - name: symbols
          in: query
          description: >-
            Stock ticker symbols whose stored analysis history should be
            returned.
          required: false
          style: form
          explode: true
          example:
            - AAPL
          schema:
            type: array
            items:
              type: string
        - name: limit_per_symbol
          in: query
          description: Maximum number of history snapshots to return per symbol.
          required: false
          example: 25
          schema:
            type: integer
            format: int32
        - name: include_news
          in: query
          description: Whether history snapshots should include stored news summaries.
          required: false
          example: true
          schema:
            type: boolean
        - name: jmespath
          in: query
          description: >-
            Optional JMESPath expression applied server-side to project or
            reduce the JSON response before it is returned (mirrors the MCP
            jmespath argument). Invalid expressions, expressions larger than
            1024 UTF-8 bytes, or projections that exceed the 256 KB output cap
            return HTTP 400 with a {_jmespath_error, original_keys} envelope.
            Grammar and worked examples:
            https://www.worldmonitor.app/docs/mcp-jmespath.
          required: false
          example: keys(@)
          schema:
            type: string
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              example:
                items:
                  - snapshots:
                      - action: example
                        analysisAt: 1717200000000
                        analysisId: example-id
                        analystConsensus:
                          buy: 1
                          hold: 1
                          period: daily
                          sell: 1
                          strongBuy: 1
                        available: true
                    symbol: AAPL
              schema:
                $ref: '#/components/schemas/GetStockAnalysisHistoryResponse'
        '400':
          description: Validation error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ValidationError'
                  - $ref: '#/components/schemas/JmespathProjectionError'
        '401':
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedError'
        '403':
          description: PRO entitlement access denied.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ForbiddenError'
        '429':
          description: Rate limit exceeded.
          headers:
            X-RateLimit-Limit:
              description: Maximum requests allowed in the active rate-limit window.
              schema:
                type: string
            X-RateLimit-Remaining:
              description: Requests remaining in the active rate-limit window.
              schema:
                type: string
            X-RateLimit-Reset:
              description: >-
                Unix epoch milliseconds when the active rate-limit window
                resets.
              schema:
                type: string
            Retry-After:
              description: Seconds to wait before retrying the request.
              schema:
                type: string
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/RateLimitError'
        default:
          description: Gateway or handler error response.
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/GatewayError'
  /api/market/v1/backtest-stock:
    get:
      tags:
        - MarketService
      summary: BacktestStock
      description: >-
        BacktestStock replays premium stock-analysis signals over recent price
        history. PRO-gated. Requires entitlement tier >= 1.
      operationId: BacktestStock
      security:
        - WorldMonitorKey: []
        - ApiKeyHeader: []
        - BearerAuth: []
      parameters:
        - name: symbol
          in: query
          description: Stock ticker symbol to backtest.
          required: true
          example: AAPL
          schema:
            type: string
        - name: name
          in: query
          description: Optional company display name used to disambiguate the symbol.
          required: false
          example: WorldMonitor Analyst
          schema:
            type: string
        - name: eval_window_days
          in: query
          description: Evaluation window in days for simulated backtest outcomes.
          required: false
          example: 7
          schema:
            type: integer
            format: int32
        - name: jmespath
          in: query
          description: >-
            Optional JMESPath expression applied server-side to project or
            reduce the JSON response before it is returned (mirrors the MCP
            jmespath argument). Invalid expressions, expressions larger than
            1024 UTF-8 bytes, or projections that exceed the 256 KB output cap
            return HTTP 400 with a {_jmespath_error, original_keys} envelope.
            Grammar and worked examples:
            https://www.worldmonitor.app/docs/mcp-jmespath.
          required: false
          example: keys(@)
          schema:
            type: string
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              example:
                actionableEvaluations: 1
                available: true
                avgSimulatedReturnPct: 1.5
                cumulativeSimulatedReturnPct: 1.5
                currency: USD
              schema:
                $ref: '#/components/schemas/BacktestStockResponse'
        '400':
          description: Validation error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ValidationError'
                  - $ref: '#/components/schemas/JmespathProjectionError'
        '401':
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedError'
        '403':
          description: PRO entitlement access denied.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ForbiddenError'
        '429':
          description: Rate limit exceeded.
          headers:
            X-RateLimit-Limit:
              description: Maximum requests allowed in the active rate-limit window.
              schema:
                type: string
            X-RateLimit-Remaining:
              description: Requests remaining in the active rate-limit window.
              schema:
                type: string
            X-RateLimit-Reset:
              description: >-
                Unix epoch milliseconds when the active rate-limit window
                resets.
              schema:
                type: string
            Retry-After:
              description: Seconds to wait before retrying the request.
              schema:
                type: string
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/RateLimitError'
        default:
          description: Gateway or handler error response.
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/GatewayError'
  /api/market/v1/list-stored-stock-backtests:
    get:
      tags:
        - MarketService
      summary: ListStoredStockBacktests
      description: >-
        ListStoredStockBacktests retrieves stored premium backtest snapshots
        from the backend store. PRO-gated. Requires entitlement tier >= 1.
      operationId: ListStoredStockBacktests
      security:
        - WorldMonitorKey: []
        - ApiKeyHeader: []
        - BearerAuth: []
      parameters:
        - name: symbols
          in: query
          description: Stock ticker symbols whose stored backtests should be returned.
          required: false
          style: form
          explode: true
          example:
            - AAPL
          schema:
            type: array
            items:
              type: string
        - name: eval_window_days
          in: query
          description: Evaluation window in days used by stored backtests.
          required: false
          example: 7
          schema:
            type: integer
            format: int32
        - name: jmespath
          in: query
          description: >-
            Optional JMESPath expression applied server-side to project or
            reduce the JSON response before it is returned (mirrors the MCP
            jmespath argument). Invalid expressions, expressions larger than
            1024 UTF-8 bytes, or projections that exceed the 256 KB output cap
            return HTTP 400 with a {_jmespath_error, original_keys} envelope.
            Grammar and worked examples:
            https://www.worldmonitor.app/docs/mcp-jmespath.
          required: false
          example: keys(@)
          schema:
            type: string
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              example:
                items:
                  - actionableEvaluations: 1
                    available: true
                    avgSimulatedReturnPct: 1.5
                    cumulativeSimulatedReturnPct: 1.5
                    currency: USD
              schema:
                $ref: '#/components/schemas/ListStoredStockBacktestsResponse'
        '400':
          description: Validation error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ValidationError'
                  - $ref: '#/components/schemas/JmespathProjectionError'
        '401':
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedError'
        '403':
          description: PRO entitlement access denied.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ForbiddenError'
        '429':
          description: Rate limit exceeded.
          headers:
            X-RateLimit-Limit:
              description: Maximum requests allowed in the active rate-limit window.
              schema:
                type: string
            X-RateLimit-Remaining:
              description: Requests remaining in the active rate-limit window.
              schema:
                type: string
            X-RateLimit-Reset:
              description: >-
                Unix epoch milliseconds when the active rate-limit window
                resets.
              schema:
                type: string
            Retry-After:
              description: Seconds to wait before retrying the request.
              schema:
                type: string
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/RateLimitError'
        default:
          description: Gateway or handler error response.
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/GatewayError'
  /api/market/v1/list-crypto-sectors:
    get:
      tags:
        - MarketService
      summary: ListCryptoSectors
      description: ListCryptoSectors retrieves crypto sector performance averages.
      operationId: ListCryptoSectors
      parameters:
        - name: jmespath
          in: query
          description: >-
            Optional JMESPath expression applied server-side to project or
            reduce the JSON response before it is returned (mirrors the MCP
            jmespath argument). Invalid expressions, expressions larger than
            1024 UTF-8 bytes, or projections that exceed the 256 KB output cap
            return HTTP 400 with a {_jmespath_error, original_keys} envelope.
            Grammar and worked examples:
            https://www.worldmonitor.app/docs/mcp-jmespath.
          required: false
          example: keys(@)
          schema:
            type: string
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              example:
                sectors:
                  - change: 1.5
                    id: example-id
                    name: WorldMonitor Analyst
              schema:
                $ref: '#/components/schemas/ListCryptoSectorsResponse'
        '400':
          description: Validation error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ValidationError'
                  - $ref: '#/components/schemas/JmespathProjectionError'
        '401':
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedError'
        '403':
          description: >-
            API access requires an active subscription (the API key's
            subscription is inactive or expired).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ForbiddenError'
        '429':
          description: Rate limit exceeded.
          headers:
            X-RateLimit-Limit:
              description: Maximum requests allowed in the active rate-limit window.
              schema:
                type: string
            X-RateLimit-Remaining:
              description: Requests remaining in the active rate-limit window.
              schema:
                type: string
            X-RateLimit-Reset:
              description: >-
                Unix epoch milliseconds when the active rate-limit window
                resets.
              schema:
                type: string
            Retry-After:
              description: Seconds to wait before retrying the request.
              schema:
                type: string
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/RateLimitError'
        default:
          description: Gateway or handler error response.
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/GatewayError'
  /api/market/v1/list-defi-tokens:
    get:
      tags:
        - MarketService
      summary: ListDefiTokens
      description: ListDefiTokens retrieves DeFi token prices and changes.
      operationId: ListDefiTokens
      parameters:
        - name: jmespath
          in: query
          description: >-
            Optional JMESPath expression applied server-side to project or
            reduce the JSON response before it is returned (mirrors the MCP
            jmespath argument). Invalid expressions, expressions larger than
            1024 UTF-8 bytes, or projections that exceed the 256 KB output cap
            return HTTP 400 with a {_jmespath_error, original_keys} envelope.
            Grammar and worked examples:
            https://www.worldmonitor.app/docs/mcp-jmespath.
          required: false
          example: keys(@)
          schema:
            type: string
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              example:
                tokens:
                  - change: 1.5
                    change7d: 1.5
                    name: WorldMonitor Analyst
                    price: 75.25
                    sparkline:
                      - 1.5
                    symbol: AAPL
              schema:
                $ref: '#/components/schemas/ListDefiTokensResponse'
        '400':
          description: Validation error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ValidationError'
                  - $ref: '#/components/schemas/JmespathProjectionError'
        '401':
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedError'
        '403':
          description: >-
            API access requires an active subscription (the API key's
            subscription is inactive or expired).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ForbiddenError'
        '429':
          description: Rate limit exceeded.
          headers:
            X-RateLimit-Limit:
              description: Maximum requests allowed in the active rate-limit window.
              schema:
                type: string
            X-RateLimit-Remaining:
              description: Requests remaining in the active rate-limit window.
              schema:
                type: string
            X-RateLimit-Reset:
              description: >-
                Unix epoch milliseconds when the active rate-limit window
                resets.
              schema:
                type: string
            Retry-After:
              description: Seconds to wait before retrying the request.
              schema:
                type: string
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/RateLimitError'
        default:
          description: Gateway or handler error response.
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/GatewayError'
  /api/market/v1/list-ai-tokens:
    get:
      tags:
        - MarketService
      summary: ListAiTokens
      description: ListAiTokens retrieves AI-focused crypto token prices and changes.
      operationId: ListAiTokens
      parameters:
        - name: jmespath
          in: query
          description: >-
            Optional JMESPath expression applied server-side to project or
            reduce the JSON response before it is returned (mirrors the MCP
            jmespath argument). Invalid expressions, expressions larger than
            1024 UTF-8 bytes, or projections that exceed the 256 KB output cap
            return HTTP 400 with a {_jmespath_error, original_keys} envelope.
            Grammar and worked examples:
            https://www.worldmonitor.app/docs/mcp-jmespath.
          required: false
          example: keys(@)
          schema:
            type: string
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              example:
                tokens:
                  - change: 1.5
                    change7d: 1.5
                    name: WorldMonitor Analyst
                    price: 75.25
                    sparkline:
                      - 1.5
                    symbol: AAPL
              schema:
                $ref: '#/components/schemas/ListAiTokensResponse'
        '400':
          description: Validation error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ValidationError'
                  - $ref: '#/components/schemas/JmespathProjectionError'
        '401':
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedError'
        '403':
          description: >-
            API access requires an active subscription (the API key's
            subscription is inactive or expired).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ForbiddenError'
        '429':
          description: Rate limit exceeded.
          headers:
            X-RateLimit-Limit:
              description: Maximum requests allowed in the active rate-limit window.
              schema:
                type: string
            X-RateLimit-Remaining:
              description: Requests remaining in the active rate-limit window.
              schema:
                type: string
            X-RateLimit-Reset:
              description: >-
                Unix epoch milliseconds when the active rate-limit window
                resets.
              schema:
                type: string
            Retry-After:
              description: Seconds to wait before retrying the request.
              schema:
                type: string
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/RateLimitError'
        default:
          description: Gateway or handler error response.
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/GatewayError'
  /api/market/v1/list-other-tokens:
    get:
      tags:
        - MarketService
      summary: ListOtherTokens
      description: >-
        ListOtherTokens retrieves other/trending crypto token prices and
        changes.
      operationId: ListOtherTokens
      parameters:
        - name: jmespath
          in: query
          description: >-
            Optional JMESPath expression applied server-side to project or
            reduce the JSON response before it is returned (mirrors the MCP
            jmespath argument). Invalid expressions, expressions larger than
            1024 UTF-8 bytes, or projections that exceed the 256 KB output cap
            return HTTP 400 with a {_jmespath_error, original_keys} envelope.
            Grammar and worked examples:
            https://www.worldmonitor.app/docs/mcp-jmespath.
          required: false
          example: keys(@)
          schema:
            type: string
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              example:
                tokens:
                  - change: 1.5
                    change7d: 1.5
                    name: WorldMonitor Analyst
                    price: 75.25
                    sparkline:
                      - 1.5
                    symbol: AAPL
              schema:
                $ref: '#/components/schemas/ListOtherTokensResponse'
        '400':
          description: Validation error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ValidationError'
                  - $ref: '#/components/schemas/JmespathProjectionError'
        '401':
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedError'
        '403':
          description: >-
            API access requires an active subscription (the API key's
            subscription is inactive or expired).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ForbiddenError'
        '429':
          description: Rate limit exceeded.
          headers:
            X-RateLimit-Limit:
              description: Maximum requests allowed in the active rate-limit window.
              schema:
                type: string
            X-RateLimit-Remaining:
              description: Requests remaining in the active rate-limit window.
              schema:
                type: string
            X-RateLimit-Reset:
              description: >-
                Unix epoch milliseconds when the active rate-limit window
                resets.
              schema:
                type: string
            Retry-After:
              description: Seconds to wait before retrying the request.
              schema:
                type: string
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/RateLimitError'
        default:
          description: Gateway or handler error response.
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/GatewayError'
  /api/market/v1/get-fear-greed-index:
    get:
      tags:
        - MarketService
      summary: GetFearGreedIndex
      description: GetFearGreedIndex retrieves the composite Fear & Greed sentiment index.
      operationId: GetFearGreedIndex
      parameters:
        - name: jmespath
          in: query
          description: >-
            Optional JMESPath expression applied server-side to project or
            reduce the JSON response before it is returned (mirrors the MCP
            jmespath argument). Invalid expressions, expressions larger than
            1024 UTF-8 bytes, or projections that exceed the 256 KB output cap
            return HTTP 400 with a {_jmespath_error, original_keys} envelope.
            Grammar and worked examples:
            https://www.worldmonitor.app/docs/mcp-jmespath.
          required: false
          example: keys(@)
          schema:
            type: string
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              example:
                aaiiBear: 1.5
                aaiiBull: 1.5
                breadth:
                  contribution: 1.5
                  degraded: true
                  inputsJson: example
                  score: 42.5
                  weight: 1.5
                cnnFearGreed: 1.5
                cnnLabel: example
              schema:
                $ref: '#/components/schemas/GetFearGreedIndexResponse'
        '400':
          description: Validation error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ValidationError'
                  - $ref: '#/components/schemas/JmespathProjectionError'
        '401':
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedError'
        '403':
          description: >-
            API access requires an active subscription (the API key's
            subscription is inactive or expired).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ForbiddenError'
        '429':
          description: Rate limit exceeded.
          headers:
            X-RateLimit-Limit:
              description: Maximum requests allowed in the active rate-limit window.
              schema:
                type: string
            X-RateLimit-Remaining:
              description: Requests remaining in the active rate-limit window.
              schema:
                type: string
            X-RateLimit-Reset:
              description: >-
                Unix epoch milliseconds when the active rate-limit window
                resets.
              schema:
                type: string
            Retry-After:
              description: Seconds to wait before retrying the request.
              schema:
                type: string
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/RateLimitError'
        default:
          description: Gateway or handler error response.
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/GatewayError'
  /api/market/v1/list-earnings-calendar:
    get:
      tags:
        - MarketService
      summary: ListEarningsCalendar
      description: ListEarningsCalendar retrieves upcoming and recent earnings releases.
      operationId: ListEarningsCalendar
      parameters:
        - name: fromDate
          in: query
          description: >-
            Accepted but currently ignored; no-op until this handler supports
            the parameter.
          required: false
          example: '2026-01-15'
          schema:
            type: string
        - name: toDate
          in: query
          description: >-
            Accepted but currently ignored; no-op until this handler supports
            the parameter.
          required: false
          example: '2026-01-15'
          schema:
            type: string
        - name: jmespath
          in: query
          description: >-
            Optional JMESPath expression applied server-side to project or
            reduce the JSON response before it is returned (mirrors the MCP
            jmespath argument). Invalid expressions, expressions larger than
            1024 UTF-8 bytes, or projections that exceed the 256 KB output cap
            return HTTP 400 with a {_jmespath_error, original_keys} envelope.
            Grammar and worked examples:
            https://www.worldmonitor.app/docs/mcp-jmespath.
          required: false
          example: keys(@)
          schema:
            type: string
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              example:
                earnings:
                  - company: example
                    date: '2026-01-15'
                    epsActual: 1.5
                    epsEstimate: 1.5
                    hasActuals: true
                fromDate: '2026-01-15'
                toDate: '2026-01-15'
                total: 1
                unavailable: true
              schema:
                $ref: '#/components/schemas/ListEarningsCalendarResponse'
        '400':
          description: Validation error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ValidationError'
                  - $ref: '#/components/schemas/JmespathProjectionError'
        '401':
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedError'
        '403':
          description: >-
            API access requires an active subscription (the API key's
            subscription is inactive or expired).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ForbiddenError'
        '429':
          description: Rate limit exceeded.
          headers:
            X-RateLimit-Limit:
              description: Maximum requests allowed in the active rate-limit window.
              schema:
                type: string
            X-RateLimit-Remaining:
              description: Requests remaining in the active rate-limit window.
              schema:
                type: string
            X-RateLimit-Reset:
              description: >-
                Unix epoch milliseconds when the active rate-limit window
                resets.
              schema:
                type: string
            Retry-After:
              description: Seconds to wait before retrying the request.
              schema:
                type: string
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/RateLimitError'
        default:
          description: Gateway or handler error response.
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/GatewayError'
  /api/market/v1/get-cot-positioning:
    get:
      tags:
        - MarketService
      summary: GetCotPositioning
      description: GetCotPositioning retrieves CFTC COT institutional positioning data.
      operationId: GetCotPositioning
      parameters:
        - name: jmespath
          in: query
          description: >-
            Optional JMESPath expression applied server-side to project or
            reduce the JSON response before it is returned (mirrors the MCP
            jmespath argument). Invalid expressions, expressions larger than
            1024 UTF-8 bytes, or projections that exceed the 256 KB output cap
            return HTTP 400 with a {_jmespath_error, original_keys} envelope.
            Grammar and worked examples:
            https://www.worldmonitor.app/docs/mcp-jmespath.
          required: false
          example: keys(@)
          schema:
            type: string
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              example:
                instruments:
                  - assetManagerLong: '1717200000000'
                    assetManagerShort: '1717200000000'
                    code: example
                    dealerLong: '1717200000000'
                    dealerShort: '1717200000000'
                reportDate: '2026-01-15'
                unavailable: true
              schema:
                $ref: '#/components/schemas/GetCotPositioningResponse'
        '400':
          description: Validation error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ValidationError'
                  - $ref: '#/components/schemas/JmespathProjectionError'
        '401':
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedError'
        '403':
          description: >-
            API access requires an active subscription (the API key's
            subscription is inactive or expired).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ForbiddenError'
        '429':
          description: Rate limit exceeded.
          headers:
            X-RateLimit-Limit:
              description: Maximum requests allowed in the active rate-limit window.
              schema:
                type: string
            X-RateLimit-Remaining:
              description: Requests remaining in the active rate-limit window.
              schema:
                type: string
            X-RateLimit-Reset:
              description: >-
                Unix epoch milliseconds when the active rate-limit window
                resets.
              schema:
                type: string
            Retry-After:
              description: Seconds to wait before retrying the request.
              schema:
                type: string
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/RateLimitError'
        default:
          description: Gateway or handler error response.
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/GatewayError'
  /api/market/v1/get-insider-transactions:
    get:
      tags:
        - MarketService
      summary: GetInsiderTransactions
      description: >-
        GetInsiderTransactions retrieves SEC insider buy/sell activity from
        Finnhub.
      operationId: GetInsiderTransactions
      parameters:
        - name: symbol
          in: query
          description: Stock ticker symbol for insider transaction lookup.
          required: true
          example: AAPL
          schema:
            type: string
        - name: jmespath
          in: query
          description: >-
            Optional JMESPath expression applied server-side to project or
            reduce the JSON response before it is returned (mirrors the MCP
            jmespath argument). Invalid expressions, expressions larger than
            1024 UTF-8 bytes, or projections that exceed the 256 KB output cap
            return HTTP 400 with a {_jmespath_error, original_keys} envelope.
            Grammar and worked examples:
            https://www.worldmonitor.app/docs/mcp-jmespath.
          required: false
          example: keys(@)
          schema:
            type: string
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              example:
                fetchedAt: '2026-01-15T12:00:00Z'
                netValue: 1.5
                symbol: AAPL
                totalBuys: 1
                totalSells: 1
              schema:
                $ref: '#/components/schemas/GetInsiderTransactionsResponse'
        '400':
          description: Validation error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ValidationError'
                  - $ref: '#/components/schemas/JmespathProjectionError'
        '401':
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedError'
        '403':
          description: >-
            API access requires an active subscription (the API key's
            subscription is inactive or expired).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ForbiddenError'
        '429':
          description: Rate limit exceeded.
          headers:
            X-RateLimit-Limit:
              description: Maximum requests allowed in the active rate-limit window.
              schema:
                type: string
            X-RateLimit-Remaining:
              description: Requests remaining in the active rate-limit window.
              schema:
                type: string
            X-RateLimit-Reset:
              description: >-
                Unix epoch milliseconds when the active rate-limit window
                resets.
              schema:
                type: string
            Retry-After:
              description: Seconds to wait before retrying the request.
              schema:
                type: string
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/RateLimitError'
        default:
          description: Gateway or handler error response.
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/GatewayError'
  /api/market/v1/get-market-breadth-history:
    get:
      tags:
        - MarketService
      summary: GetMarketBreadthHistory
      description: >-
        GetMarketBreadthHistory retrieves historical % of S&P 500 stocks above
        20/50/200-day SMAs.
      operationId: GetMarketBreadthHistory
      parameters:
        - name: jmespath
          in: query
          description: >-
            Optional JMESPath expression applied server-side to project or
            reduce the JSON response before it is returned (mirrors the MCP
            jmespath argument). Invalid expressions, expressions larger than
            1024 UTF-8 bytes, or projections that exceed the 256 KB output cap
            return HTTP 400 with a {_jmespath_error, original_keys} envelope.
            Grammar and worked examples:
            https://www.worldmonitor.app/docs/mcp-jmespath.
          required: false
          example: keys(@)
          schema:
            type: string
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              example:
                currentPctAbove200d: 1.5
                currentPctAbove20d: 1.5
                currentPctAbove50d: 1.5
                history:
                  - date: '2026-01-15'
                    pctAbove200d: 1.5
                    pctAbove20d: 1.5
                    pctAbove50d: 1.5
                unavailable: true
              schema:
                $ref: '#/components/schemas/GetMarketBreadthHistoryResponse'
        '400':
          description: Validation error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ValidationError'
                  - $ref: '#/components/schemas/JmespathProjectionError'
        '401':
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedError'
        '403':
          description: >-
            API access requires an active subscription (the API key's
            subscription is inactive or expired).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ForbiddenError'
        '429':
          description: Rate limit exceeded.
          headers:
            X-RateLimit-Limit:
              description: Maximum requests allowed in the active rate-limit window.
              schema:
                type: string
            X-RateLimit-Remaining:
              description: Requests remaining in the active rate-limit window.
              schema:
                type: string
            X-RateLimit-Reset:
              description: >-
                Unix epoch milliseconds when the active rate-limit window
                resets.
              schema:
                type: string
            Retry-After:
              description: Seconds to wait before retrying the request.
              schema:
                type: string
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/RateLimitError'
        default:
          description: Gateway or handler error response.
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/GatewayError'
  /api/market/v1/get-gold-intelligence:
    get:
      tags:
        - MarketService
      summary: GetGoldIntelligence
      description: >-
        GetGoldIntelligence retrieves gold pricing, cross-currency XAU, ratios,
        and CFTC positioning.
      operationId: GetGoldIntelligence
      parameters:
        - name: jmespath
          in: query
          description: >-
            Optional JMESPath expression applied server-side to project or
            reduce the JSON response before it is returned (mirrors the MCP
            jmespath argument). Invalid expressions, expressions larger than
            1024 UTF-8 bytes, or projections that exceed the 256 KB output cap
            return HTTP 400 with a {_jmespath_error, original_keys} envelope.
            Grammar and worked examples:
            https://www.worldmonitor.app/docs/mcp-jmespath.
          required: false
          example: keys(@)
          schema:
            type: string
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              example:
                cbReserves:
                  asOfMonth: example
                  topBuyers12m:
                    - deltaTonnes12m: 1.5
                      iso3: USA
                      name: WorldMonitor Analyst
                  topHolders:
                    - iso3: USA
                      name: WorldMonitor Analyst
                      pctOfReserves: 1.5
                      tonnes: 1.5
                  topSellers12m:
                    - deltaTonnes12m: 1.5
                      iso3: USA
                      name: WorldMonitor Analyst
                  totalTonnes: 1
                cot:
                  managedMoney:
                    longPositions: '1717200000000'
                    netPct: 1.5
                    oiSharePct: 1.5
                    shortPositions: '1717200000000'
                    wowNetDelta: '1717200000000'
                  nextReleaseDate: '2026-01-15'
                  openInterest: '1717200000000'
                  producerSwap:
                    longPositions: '1717200000000'
                    netPct: 1.5
                    oiSharePct: 1.5
                    shortPositions: '1717200000000'
                    wowNetDelta: '1717200000000'
                  reportDate: '2026-01-15'
                crossCurrencyPrices:
                  - currency: USD
                    flag: example
                    price: 75.25
                drivers:
                  - changePct: 1.5
                    correlation30d: 1.5
                    label: example
                    symbol: AAPL
                    value: 1.5
                etfFlows:
                  asOfDate: '2026-01-15'
                  aumUsd: 1.5
                  changeM1Pct: 1.5
                  changeM1Tonnes: 1.5
                  changeW1Pct: 1.5
              schema:
                $ref: '#/components/schemas/GetGoldIntelligenceResponse'
        '400':
          description: Validation error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ValidationError'
                  - $ref: '#/components/schemas/JmespathProjectionError'
        '401':
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedError'
        '403':
          description: >-
            API access requires an active subscription (the API key's
            subscription is inactive or expired).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ForbiddenError'
        '429':
          description: Rate limit exceeded.
          headers:
            X-RateLimit-Limit:
              description: Maximum requests allowed in the active rate-limit window.
              schema:
                type: string
            X-RateLimit-Remaining:
              description: Requests remaining in the active rate-limit window.
              schema:
                type: string
            X-RateLimit-Reset:
              description: >-
                Unix epoch milliseconds when the active rate-limit window
                resets.
              schema:
                type: string
            Retry-After:
              description: Seconds to wait before retrying the request.
              schema:
                type: string
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/RateLimitError'
        default:
          description: Gateway or handler error response.
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/GatewayError'
  /api/market/v1/get-hyperliquid-flow:
    get:
      tags:
        - MarketService
      summary: GetHyperliquidFlow
      description: >-
        GetHyperliquidFlow retrieves Hyperliquid perp positioning flow
        (funding/OI/basis composite scores).
      operationId: GetHyperliquidFlow
      parameters:
        - name: jmespath
          in: query
          description: >-
            Optional JMESPath expression applied server-side to project or
            reduce the JSON response before it is returned (mirrors the MCP
            jmespath argument). Invalid expressions, expressions larger than
            1024 UTF-8 bytes, or projections that exceed the 256 KB output cap
            return HTTP 400 with a {_jmespath_error, original_keys} envelope.
            Grammar and worked examples:
            https://www.worldmonitor.app/docs/mcp-jmespath.
          required: false
          example: keys(@)
          schema:
            type: string
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              example:
                assetCount: 1
                assets:
                  - alerts:
                      - example
                    assetClass: example
                    basisScore: 42.5
                    composite: 1.5
                    dayNotional: example
                fetchedAt: '2026-01-15T12:00:00Z'
                ts: '1717200000000'
                unavailable: true
              schema:
                $ref: '#/components/schemas/GetHyperliquidFlowResponse'
        '400':
          description: Validation error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ValidationError'
                  - $ref: '#/components/schemas/JmespathProjectionError'
        '401':
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedError'
        '403':
          description: >-
            API access requires an active subscription (the API key's
            subscription is inactive or expired).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ForbiddenError'
        '429':
          description: Rate limit exceeded.
          headers:
            X-RateLimit-Limit:
              description: Maximum requests allowed in the active rate-limit window.
              schema:
                type: string
            X-RateLimit-Remaining:
              description: Requests remaining in the active rate-limit window.
              schema:
                type: string
            X-RateLimit-Reset:
              description: >-
                Unix epoch milliseconds when the active rate-limit window
                resets.
              schema:
                type: string
            Retry-After:
              description: Seconds to wait before retrying the request.
              schema:
                type: string
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/RateLimitError'
        default:
          description: Gateway or handler error response.
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/GatewayError'
components:
  securitySchemes:
    WorldMonitorKey:
      type: apiKey
      in: header
      name: X-WorldMonitor-Key
      description: User-issued WorldMonitor API key.
    ApiKeyHeader:
      type: apiKey
      in: header
      name: X-Api-Key
      description: Alias header for the WorldMonitor API key (X-WorldMonitor-Key).
    BearerAuth:
      type: http
      scheme: bearer
      description: >-
        Bearer token: a Clerk-issued JWT for browser session flows, passed as
        Authorization: Bearer <token>.
  schemas:
    JmespathProjectionError:
      description: >-
        Returned when a REST jmespath projection is invalid or exceeds the
        expression/output byte limits.
      properties:
        _jmespath_error:
          description: Projection error discriminator and details.
          type: string
        original_keys:
          description: Top-level keys or shape of the unprojected response.
          items:
            type: string
          type: array
      required:
        - _jmespath_error
        - original_keys
      type: object
    UnauthorizedError:
      type: object
      properties:
        error:
          type: string
          description: Human-readable error message.
      required:
        - error
      description: >-
        Returned when the API key is missing, malformed, or lacks current API
        access.
    Error:
      type: object
      properties:
        message:
          type: string
          description: Error message (e.g., 'user not found', 'database connection failed')
      description: >-
        Error is returned when a handler encounters an error. It contains a
        simple error message that the developer can customize.
    InvalidRequestBodyError:
      type: object
      description: Returned when a JSON POST request body is empty or malformed.
      properties:
        message:
          type: string
          description: Invalid request body
      required:
        - message
    GatewayError:
      type: object
      description: >-
        Returned by gateway infrastructure errors before an RPC handler runs,
        such as origin, routing, method, authentication, or quota checks.
      properties:
        error:
          oneOf:
            - type: string
            - type: object
              additionalProperties: true
          description: Gateway error reason or structured gateway failure details.
      required:
        - error
    RateLimitError:
      type: object
      description: Returned when a gateway or handler rate limit rejects the request.
      properties:
        error:
          type: string
          description: Human-readable rate-limit failure reason.
      required:
        - error
    ForbiddenError:
      type: object
      properties:
        error:
          type: string
          description: Human-readable entitlement failure reason.
        requiredTier:
          type: integer
          format: int32
          description: Minimum entitlement tier required for this endpoint.
        currentTier:
          type: integer
          format: int32
          description: Caller entitlement tier when known.
        planKey:
          type: string
          description: Caller plan key when known.
      required:
        - error
      description: >-
        Returned when a PRO-gated endpoint denies access because the caller has
        no resolved authenticated user, entitlements cannot be verified, or the
        caller lacks the required entitlement tier.
    FieldViolation:
      type: object
      properties:
        field:
          type: string
          description: >-
            The field path that failed validation (e.g., 'user.email' for nested
            fields). For header validation, this will be the header name (e.g.,
            'X-API-Key')
        description:
          type: string
          description: >-
            Human-readable description of the validation violation (e.g., 'must
            be a valid email address', 'required field missing')
      required:
        - field
        - description
      description: FieldViolation describes a single validation error for a specific field.
    ValidationError:
      type: object
      properties:
        violations:
          type: array
          items:
            $ref: '#/components/schemas/FieldViolation'
          description: List of validation violations
      required:
        - violations
      description: >-
        ValidationError is returned when request validation fails. It contains a
        list of field violations describing what went wrong.
    ListMarketQuotesRequest:
      type: object
      properties:
        symbols:
          type: array
          items:
            type: string
            description: >-
              Ticker symbols to retrieve (e.g., ["AAPL", "^GSPC"]). Empty
              returns defaults.
      description: ListMarketQuotesRequest specifies which stock/index symbols to retrieve.
    ListMarketQuotesResponse:
      type: object
      properties:
        quotes:
          type: array
          items:
            $ref: '#/components/schemas/MarketQuote'
        finnhubSkipped:
          type: boolean
          description: >-
            True when the Finnhub API key is not configured and stock quotes
            were skipped.
        skipReason:
          type: string
          description: >-
            Human-readable reason when Finnhub was skipped (e.g.,
            "FINNHUB_API_KEY not configured").
        rateLimited:
          type: boolean
          description: True when the upstream API rate-limited the request.
      description: ListMarketQuotesResponse contains stock and index quotes.
    MarketQuote:
      type: object
      properties:
        symbol:
          type: string
          minLength: 1
          description: Ticker symbol (e.g., "AAPL", "^GSPC").
        name:
          type: string
          description: Human-readable name.
        display:
          type: string
          description: Display label.
        price:
          type: number
          format: double
          description: Current price.
        change:
          type: number
          format: double
          description: Percentage change from previous close.
        sparkline:
          type: array
          items:
            type: number
            format: double
            description: Sparkline data points (recent price history).
      required:
        - symbol
      description: >-
        MarketQuote represents a stock or index quote from Finnhub or Yahoo
        Finance.
    ListCryptoQuotesRequest:
      type: object
      properties:
        ids:
          type: array
          items:
            type: string
            description: >-
              Cryptocurrency IDs to retrieve (CoinGecko IDs). Empty returns
              defaults.
      description: ListCryptoQuotesRequest specifies which cryptocurrencies to retrieve.
    ListCryptoQuotesResponse:
      type: object
      properties:
        quotes:
          type: array
          items:
            $ref: '#/components/schemas/CryptoQuote'
      description: ListCryptoQuotesResponse contains cryptocurrency quotes.
    CryptoQuote:
      type: object
      properties:
        name:
          type: string
          description: Cryptocurrency name (e.g., "Bitcoin").
        symbol:
          type: string
          minLength: 1
          description: Ticker symbol (e.g., "BTC").
        price:
          type: number
          format: double
          description: Current price in USD.
        change:
          type: number
          format: double
          description: 24-hour percentage change.
        sparkline:
          type: array
          items:
            type: number
            format: double
            description: Sparkline data points (recent price history).
        change7d:
          type: number
          format: double
          description: 7-day percentage change.
      required:
        - symbol
      description: CryptoQuote represents a cryptocurrency quote from CoinGecko.
    ListCommodityQuotesRequest:
      type: object
      properties:
        symbols:
          type: array
          items:
            type: string
            description: >-
              Commodity symbols to retrieve (Yahoo symbols). Empty returns
              defaults.
      description: ListCommodityQuotesRequest specifies which commodities to retrieve.
    ListCommodityQuotesResponse:
      type: object
      properties:
        quotes:
          type: array
          items:
            $ref: '#/components/schemas/CommodityQuote'
      description: ListCommodityQuotesResponse contains commodity quotes.
    CommodityQuote:
      type: object
      properties:
        symbol:
          type: string
          minLength: 1
          description: Commodity symbol (e.g., "CL=F" for crude oil).
        name:
          type: string
          description: Human-readable name.
        display:
          type: string
          description: Display label.
        price:
          type: number
          format: double
          description: Current price.
        change:
          type: number
          format: double
          description: Percentage change from previous close.
        sparkline:
          type: array
          items:
            type: number
            format: double
            description: Sparkline data points.
      required:
        - symbol
      description: CommodityQuote represents a commodity price quote from Yahoo Finance.
    GetSectorSummaryRequest:
      type: object
      properties:
        period:
          type: string
          description: >-
            Time period for performance calculation (e.g., "1d", "1w", "1m").
            Defaults to "1d".
             Accepted but currently ignored; no-op until this handler supports the parameter.
      description: >-
        GetSectorSummaryRequest specifies parameters for retrieving sector
        performance.
    GetSectorSummaryResponse:
      type: object
      properties:
        sectors:
          type: array
          items:
            $ref: '#/components/schemas/SectorPerformance'
      description: GetSectorSummaryResponse contains sector performance data.
    SectorPerformance:
      type: object
      properties:
        symbol:
          type: string
          minLength: 1
          description: Sector symbol.
        name:
          type: string
          description: Sector name.
        change:
          type: number
          format: double
          description: Percentage change over the measured period.
      required:
        - symbol
      description: SectorPerformance represents performance data for a market sector.
    ListStablecoinMarketsRequest:
      type: object
      properties:
        coins:
          type: array
          items:
            type: string
            description: >-
              CoinGecko IDs to retrieve (e.g. "tether,usd-coin"). Empty returns
              defaults.
      description: ListStablecoinMarketsRequest specifies which stablecoins to retrieve.
    ListStablecoinMarketsResponse:
      type: object
      properties:
        timestamp:
          type: string
          description: Timestamp of the data fetch (ISO 8601).
        summary:
          $ref: '#/components/schemas/StablecoinSummary'
        stablecoins:
          type: array
          items:
            $ref: '#/components/schemas/Stablecoin'
      description: ListStablecoinMarketsResponse contains stablecoin market data.
    StablecoinSummary:
      type: object
      properties:
        totalMarketCap:
          type: number
          format: double
          description: Total market cap across all queried stablecoins.
        totalVolume24h:
          type: number
          format: double
          description: Total 24h volume across all queried stablecoins.
        coinCount:
          type: integer
          format: int32
          description: Number of stablecoins returned.
        depeggedCount:
          type: integer
          format: int32
          description: Number of stablecoins in DEPEGGED state.
        healthStatus:
          type: string
          description: 'Overall health: "HEALTHY", "CAUTION", or "WARNING".'
      description: StablecoinSummary contains aggregate stablecoin market stats.
    Stablecoin:
      type: object
      properties:
        id:
          type: string
          minLength: 1
          description: CoinGecko ID.
        symbol:
          type: string
          minLength: 1
          description: Ticker symbol (e.g. "USDT").
        name:
          type: string
          description: Human-readable name.
        price:
          type: number
          minimum: 0
          format: double
          description: Current price in USD.
        deviation:
          type: number
          format: double
          description: Deviation from $1.00 peg, as a percentage.
        pegStatus:
          type: string
          description: 'Peg status: "ON PEG", "SLIGHT DEPEG", or "DEPEGGED".'
        marketCap:
          type: number
          format: double
          description: Market capitalization in USD.
        volume24h:
          type: number
          format: double
          description: 24-hour trading volume in USD.
        change24h:
          type: number
          format: double
          description: 24-hour price change percentage.
        change7d:
          type: number
          format: double
          description: 7-day price change percentage.
        image:
          type: string
          description: Coin image URL.
      required:
        - id
        - symbol
      description: Stablecoin represents a single stablecoin with peg health data.
    ListEtfFlowsRequest:
      type: object
      description: >-
        ListEtfFlowsRequest is empty; the handler uses a fixed list of BTC spot
        ETFs.
    ListEtfFlowsResponse:
      type: object
      properties:
        timestamp:
          type: string
          description: Timestamp of the data fetch (ISO 8601).
        summary:
          $ref: '#/components/schemas/EtfFlowsSummary'
        etfs:
          type: array
          items:
            $ref: '#/components/schemas/EtfFlow'
        rateLimited:
          type: boolean
          description: True when the upstream API rate-limited the request.
      description: ListEtfFlowsResponse contains BTC spot ETF flow data.
    EtfFlowsSummary:
      type: object
      properties:
        etfCount:
          type: integer
          format: int32
          description: Number of ETFs with data.
        totalVolume:
          type: integer
          format: int64
          description: >-
            Total volume across all ETFs.. Warning: Values > 2^53 may lose
            precision in JavaScript
        totalEstFlow:
          type: integer
          format: int64
          description: >-
            Total estimated flow across all ETFs.. Warning: Values > 2^53 may
            lose precision in JavaScript
        netDirection:
          type: string
          description: 'Net direction: "NET INFLOW", "NET OUTFLOW", or "NEUTRAL".'
        inflowCount:
          type: integer
          format: int32
          description: Number of ETFs with inflow.
        outflowCount:
          type: integer
          format: int32
          description: Number of ETFs with outflow.
      description: EtfFlowsSummary contains aggregate ETF flow stats.
    EtfFlow:
      type: object
      properties:
        ticker:
          type: string
          minLength: 1
          description: Ticker symbol (e.g. "IBIT").
        issuer:
          type: string
          description: Fund issuer (e.g. "BlackRock").
        price:
          type: number
          format: double
          description: Latest closing price.
        priceChange:
          type: number
          format: double
          description: Day-over-day price change percentage.
        volume:
          type: integer
          format: int64
          description: >-
            Latest daily volume.. Warning: Values > 2^53 may lose precision in
            JavaScript
        avgVolume:
          type: integer
          format: int64
          description: >-
            Average volume over prior days.. Warning: Values > 2^53 may lose
            precision in JavaScript
        volumeRatio:
          type: number
          format: double
          description: Volume ratio (latest / average).
        direction:
          type: string
          description: 'Flow direction: "inflow", "outflow", or "neutral".'
        estFlow:
          type: integer
          format: int64
          description: >-
            Estimated dollar flow magnitude.. Warning: Values > 2^53 may lose
            precision in JavaScript
      required:
        - ticker
      description: EtfFlow represents a single ETF with estimated flow data.
    GetCountryStockIndexRequest:
      type: object
      properties:
        countryCode:
          type: string
          pattern: ^[A-Z]{2}$
          description: ISO 3166-1 alpha-2 country code (e.g., "US", "GB", "JP").
      required:
        - countryCode
      description: >-
        GetCountryStockIndexRequest specifies which country's stock index to
        retrieve.
    GetCountryStockIndexResponse:
      type: object
      properties:
        available:
          type: boolean
          description: Whether stock index data is available for this country.
        code:
          type: string
          description: ISO 3166-1 alpha-2 country code.
        symbol:
          type: string
          description: Ticker symbol (e.g., "^GSPC").
        indexName:
          type: string
          description: Index name (e.g., "S&P 500").
        price:
          type: number
          format: double
          description: Latest closing price.
        weekChangePercent:
          type: number
          format: double
          description: Weekly change percentage.
        currency:
          type: string
          description: Currency of the index.
        fetchedAt:
          type: string
          description: When the data was fetched (ISO 8601).
      description: >-
        GetCountryStockIndexResponse contains the country's primary stock index
        data.
    ListGulfQuotesRequest:
      type: object
    ListGulfQuotesResponse:
      type: object
      properties:
        quotes:
          type: array
          items:
            $ref: '#/components/schemas/GulfQuote'
        rateLimited:
          type: boolean
    GulfQuote:
      type: object
      properties:
        symbol:
          type: string
        name:
          type: string
        flag:
          type: string
        country:
          type: string
        type:
          type: string
        price:
          type: number
          format: double
        change:
          type: number
          format: double
        sparkline:
          type: array
          items:
            type: number
            format: double
      description: >-
        GulfQuote represents a Gulf region market quote (index, currency, or
        oil).
    AnalyzeStockRequest:
      type: object
      properties:
        symbol:
          type: string
          maxLength: 32
          minLength: 1
          description: Stock ticker symbol to analyze.
        name:
          type: string
          maxLength: 120
          description: Optional company display name used to disambiguate the symbol.
        includeNews:
          type: boolean
          description: Whether to include recent news in the stock analysis.
      required:
        - symbol
    AnalyzeStockResponse:
      type: object
      properties:
        available:
          type: boolean
        symbol:
          type: string
        name:
          type: string
        display:
          type: string
        currency:
          type: string
        currentPrice:
          type: number
          format: double
        changePercent:
          type: number
          format: double
        signalScore:
          type: number
          format: double
        signal:
          type: string
        trendStatus:
          type: string
        volumeStatus:
          type: string
        macdStatus:
          type: string
        rsiStatus:
          type: string
        summary:
          type: string
        action:
          type: string
        confidence:
          type: string
        technicalSummary:
          type: string
        newsSummary:
          type: string
        whyNow:
          type: string
        bullishFactors:
          type: array
          items:
            type: string
        riskFactors:
          type: array
          items:
            type: string
        supportLevels:
          type: array
          items:
            type: number
            format: double
        resistanceLevels:
          type: array
          items:
            type: number
            format: double
        headlines:
          type: array
          items:
            $ref: '#/components/schemas/StockAnalysisHeadline'
        ma5:
          type: number
          format: double
        ma10:
          type: number
          format: double
        ma20:
          type: number
          format: double
        ma60:
          type: number
          format: double
        biasMa5:
          type: number
          format: double
        biasMa10:
          type: number
          format: double
        biasMa20:
          type: number
          format: double
        volumeRatio5d:
          type: number
          format: double
        rsi12:
          type: number
          format: double
        macdDif:
          type: number
          format: double
        macdDea:
          type: number
          format: double
        macdBar:
          type: number
          format: double
        provider:
          type: string
        model:
          type: string
        fallback:
          type: boolean
        newsSearched:
          type: boolean
        generatedAt:
          type: string
        analysisId:
          type: string
        analysisAt:
          type: integer
          format: int64
          description: 'Warning: Values > 2^53 may lose precision in JavaScript'
        stopLoss:
          type: number
          format: double
        takeProfit:
          type: number
          format: double
        engineVersion:
          type: string
        analystConsensus:
          $ref: '#/components/schemas/AnalystConsensus'
        priceTarget:
          $ref: '#/components/schemas/PriceTarget'
        recentUpgrades:
          type: array
          items:
            $ref: '#/components/schemas/UpgradeDowngrade'
        dividendYield:
          type: number
          format: double
        trailingAnnualDividendRate:
          type: number
          format: double
        exDividendDate:
          type: integer
          format: int64
          description: 'Warning: Values > 2^53 may lose precision in JavaScript'
        payoutRatio:
          type: number
          format: double
        dividendFrequency:
          type: string
        dividendCagr:
          type: number
          format: double
        marketSession:
          type: string
          description: >-
            US-equity trading session at analysis time: "regular", "pre", "post"
            or
             "closed". Empty when session detection does not apply (non-US symbols).
        extendedPrice:
          type: number
          format: double
          description: >-
            Latest pre/post-market price from Yahoo extended-hours candles. Only
            set
             when market_session is "pre" or "post" and extended data is available.
        extendedChangePercent:
          type: number
          format: double
          description: >-
            Extended-hours change % vs the last regular-session close. Only set
            when
             extended_price is set.
        fundamentals:
          $ref: '#/components/schemas/Fundamentals'
        nextEarningsDate:
          type: string
          description: >-
            Next scheduled earnings date (YYYY-MM-DD) plus consensus EPS /
            revenue for
             the symbol, joined from the market:earnings-calendar:v1 seed. Unset when the
             symbol has no upcoming (not-yet-reported) entry in the seed's ~2-week window.
             (61-62 are taken by a concurrent PR; using 63-65 to avoid a field collision.)
        consensusEps:
          type: number
          format: double
        consensusRevenue:
          type: number
          format: double
    StockAnalysisHeadline:
      type: object
      properties:
        title:
          type: string
        source:
          type: string
        link:
          type: string
        publishedAt:
          type: integer
          format: int64
          description: 'Warning: Values > 2^53 may lose precision in JavaScript'
    AnalystConsensus:
      type: object
      properties:
        strongBuy:
          type: integer
          format: int32
        buy:
          type: integer
          format: int32
        hold:
          type: integer
          format: int32
        sell:
          type: integer
          format: int32
        strongSell:
          type: integer
          format: int32
        total:
          type: integer
          format: int32
        period:
          type: string
    PriceTarget:
      type: object
      properties:
        high:
          type: number
          format: double
        low:
          type: number
          format: double
        mean:
          type: number
          format: double
        median:
          type: number
          format: double
        current:
          type: number
          format: double
        numberOfAnalysts:
          type: integer
          format: int32
    UpgradeDowngrade:
      type: object
      properties:
        firm:
          type: string
        toGrade:
          type: string
        fromGrade:
          type: string
        action:
          type: string
        epochGradeDate:
          type: integer
          format: int64
          description: 'Warning: Values > 2^53 may lose precision in JavaScript'
    Fundamentals:
      type: object
      properties:
        profitMargin:
          type: number
          format: double
          description: Fractional ratio where 0.25 means 25%.
        grossMargin:
          type: number
          format: double
          description: Fractional ratio where 0.25 means 25%.
        operatingMargin:
          type: number
          format: double
          description: Fractional ratio where 0.25 means 25%.
        returnOnEquity:
          type: number
          format: double
          description: Fractional ratio where 0.25 means 25%.
        returnOnAssets:
          type: number
          format: double
          description: Fractional ratio where 0.25 means 25%.
        revenueGrowth:
          type: number
          format: double
          description: Fractional ratio where 0.25 means 25%.
        earningsGrowth:
          type: number
          format: double
          description: Fractional ratio where 0.25 means 25%.
        debtToEquity:
          type: number
          format: double
          description: Normalized debt/equity ratio where 1.5 means debt is 1.5x equity.
        totalCash:
          type: number
          format: double
          description: Latest Yahoo financialData value denominated in financial_currency.
        totalDebt:
          type: number
          format: double
          description: Latest Yahoo financialData value denominated in financial_currency.
        freeCashflow:
          type: number
          format: double
          description: Latest Yahoo financialData value denominated in financial_currency.
        ebitda:
          type: number
          format: double
          description: Latest Yahoo financialData value denominated in financial_currency.
        financialCurrency:
          type: string
          description: >-
            ISO 4217 currency used by the company's financial statements. This
            can
             differ from AnalyzeStockResponse.currency for ADRs and cross-listings.
    GetStockAnalysisHistoryRequest:
      type: object
      properties:
        symbols:
          type: array
          items:
            type: string
            description: >-
              Stock ticker symbols whose stored analysis history should be
              returned.
        limitPerSymbol:
          type: integer
          maximum: 32
          minimum: 1
          format: int32
          description: Maximum number of history snapshots to return per symbol.
        includeNews:
          type: boolean
          description: Whether history snapshots should include stored news summaries.
    GetStockAnalysisHistoryResponse:
      type: object
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/StockAnalysisHistoryItem'
    StockAnalysisHistoryItem:
      type: object
      properties:
        symbol:
          type: string
        snapshots:
          type: array
          items:
            $ref: '#/components/schemas/AnalyzeStockResponse'
    BacktestStockRequest:
      type: object
      properties:
        symbol:
          type: string
          maxLength: 32
          minLength: 1
          description: Stock ticker symbol to backtest.
        name:
          type: string
          maxLength: 120
          description: Optional company display name used to disambiguate the symbol.
        evalWindowDays:
          type: integer
          maximum: 30
          minimum: 3
          format: int32
          description: Evaluation window in days for simulated backtest outcomes.
      required:
        - symbol
    BacktestStockResponse:
      type: object
      properties:
        available:
          type: boolean
        symbol:
          type: string
        name:
          type: string
        display:
          type: string
        currency:
          type: string
        evalWindowDays:
          type: integer
          format: int32
        evaluationsRun:
          type: integer
          format: int32
        actionableEvaluations:
          type: integer
          format: int32
        winRate:
          type: number
          format: double
        directionAccuracy:
          type: number
          format: double
        avgSimulatedReturnPct:
          type: number
          format: double
        cumulativeSimulatedReturnPct:
          type: number
          format: double
        latestSignal:
          type: string
        latestSignalScore:
          type: number
          format: double
        summary:
          type: string
        generatedAt:
          type: string
        evaluations:
          type: array
          items:
            $ref: '#/components/schemas/BacktestStockEvaluation'
        engineVersion:
          type: string
    BacktestStockEvaluation:
      type: object
      properties:
        analysisAt:
          type: integer
          format: int64
          description: 'Warning: Values > 2^53 may lose precision in JavaScript'
        signal:
          type: string
        signalScore:
          type: number
          format: double
        entryPrice:
          type: number
          format: double
        exitPrice:
          type: number
          format: double
        simulatedReturnPct:
          type: number
          format: double
        directionCorrect:
          type: boolean
        outcome:
          type: string
        stopLoss:
          type: number
          format: double
        takeProfit:
          type: number
          format: double
        analysisId:
          type: string
    ListStoredStockBacktestsRequest:
      type: object
      properties:
        symbols:
          type: array
          items:
            type: string
            description: Stock ticker symbols whose stored backtests should be returned.
        evalWindowDays:
          type: integer
          maximum: 30
          minimum: 3
          format: int32
          description: Evaluation window in days used by stored backtests.
    ListStoredStockBacktestsResponse:
      type: object
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/BacktestStockResponse'
    ListCryptoSectorsRequest:
      type: object
      description: ListCryptoSectorsRequest retrieves crypto sector performance.
    ListCryptoSectorsResponse:
      type: object
      properties:
        sectors:
          type: array
          items:
            $ref: '#/components/schemas/CryptoSector'
      description: ListCryptoSectorsResponse contains crypto sector performance data.
    CryptoSector:
      type: object
      properties:
        id:
          type: string
          description: Sector identifier.
        name:
          type: string
          description: Sector display name.
        change:
          type: number
          format: double
          description: Average 24h percentage change across sector tokens.
      description: CryptoSector represents performance data for a crypto market sector.
    ListDefiTokensRequest:
      type: object
      description: ListDefiTokensRequest retrieves DeFi token prices.
    ListDefiTokensResponse:
      type: object
      properties:
        tokens:
          type: array
          items:
            $ref: '#/components/schemas/CryptoQuote'
      description: ListDefiTokensResponse contains DeFi token price data.
    ListAiTokensRequest:
      type: object
      description: ListAiTokensRequest retrieves AI crypto token prices.
    ListAiTokensResponse:
      type: object
      properties:
        tokens:
          type: array
          items:
            $ref: '#/components/schemas/CryptoQuote'
      description: ListAiTokensResponse contains AI token price data.
    ListOtherTokensRequest:
      type: object
      description: ListOtherTokensRequest retrieves other/trending crypto token prices.
    ListOtherTokensResponse:
      type: object
      properties:
        tokens:
          type: array
          items:
            $ref: '#/components/schemas/CryptoQuote'
      description: ListOtherTokensResponse contains other token price data.
    GetFearGreedIndexRequest:
      type: object
    GetFearGreedIndexResponse:
      type: object
      properties:
        compositeScore:
          type: number
          format: double
        compositeLabel:
          type: string
        previousScore:
          type: number
          format: double
        seededAt:
          type: string
        sentiment:
          $ref: '#/components/schemas/FearGreedCategory'
        volatility:
          $ref: '#/components/schemas/FearGreedCategory'
        positioning:
          $ref: '#/components/schemas/FearGreedCategory'
        trend:
          $ref: '#/components/schemas/FearGreedCategory'
        breadth:
          $ref: '#/components/schemas/FearGreedCategory'
        momentum:
          $ref: '#/components/schemas/FearGreedCategory'
        liquidity:
          $ref: '#/components/schemas/FearGreedCategory'
        credit:
          $ref: '#/components/schemas/FearGreedCategory'
        macro:
          $ref: '#/components/schemas/FearGreedCategory'
        crossAsset:
          $ref: '#/components/schemas/FearGreedCategory'
        vix:
          type: number
          format: double
        hySpread:
          type: number
          format: double
        yield10y:
          type: number
          format: double
        putCallRatio:
          type: number
          format: double
        pctAbove200d:
          type: number
          format: double
        cnnFearGreed:
          type: number
          format: double
        cnnLabel:
          type: string
        aaiiBull:
          type: number
          format: double
        aaiiBear:
          type: number
          format: double
        fedRate:
          type: string
        unavailable:
          type: boolean
          description: >-
            True when the upstream or seed-backed variant is unavailable; empty
            payload fields
             are graceful degradation, not confirmed zero data.
        fsiValue:
          type: number
          format: double
          description: >-
            Bespoke Fear & Greed header stress ratio, not the KCFSI/ECB FSI
            panel
             composite. Formula: (HYG / TLT) / (VIX * HY OAS / 100).
        fsiLabel:
          type: string
          description: |-
            Label for fsi_value: Low Stress (>=1.5), Moderate Stress (>=0.8),
             Elevated Stress (>=0.3), otherwise High Stress.
        hygPrice:
          type: number
          format: double
          description: Latest HYG ETF price used in the Fear & Greed header stress ratio.
        tltPrice:
          type: number
          format: double
          description: Latest TLT ETF price used in the Fear & Greed header stress ratio.
        sectorPerformance:
          type: array
          items:
            $ref: '#/components/schemas/FearGreedSectorPerformance'
    FearGreedCategory:
      type: object
      properties:
        score:
          type: number
          format: double
        weight:
          type: number
          format: double
        contribution:
          type: number
          format: double
        degraded:
          type: boolean
        inputsJson:
          type: string
    FearGreedSectorPerformance:
      type: object
      properties:
        symbol:
          type: string
        name:
          type: string
        change1d:
          type: number
          format: double
    ListEarningsCalendarRequest:
      type: object
      properties:
        fromDate:
          type: string
          description: >-
            Accepted but currently ignored; no-op until this handler supports
            the parameter.
        toDate:
          type: string
          description: >-
            Accepted but currently ignored; no-op until this handler supports
            the parameter.
    ListEarningsCalendarResponse:
      type: object
      properties:
        earnings:
          type: array
          items:
            $ref: '#/components/schemas/EarningsEntry'
        fromDate:
          type: string
        toDate:
          type: string
        total:
          type: integer
          format: int32
        unavailable:
          type: boolean
          description: >-
            True when the upstream or seed-backed variant is unavailable; empty
            payload fields
             are graceful degradation, not confirmed zero data.
    EarningsEntry:
      type: object
      properties:
        symbol:
          type: string
        company:
          type: string
        date:
          type: string
        hour:
          type: string
        epsEstimate:
          type: number
          format: double
        revenueEstimate:
          type: number
          format: double
        epsActual:
          type: number
          format: double
        revenueActual:
          type: number
          format: double
        hasActuals:
          type: boolean
        surpriseDirection:
          type: string
    GetCotPositioningRequest:
      type: object
    GetCotPositioningResponse:
      type: object
      properties:
        instruments:
          type: array
          items:
            $ref: '#/components/schemas/CotInstrument'
        reportDate:
          type: string
        unavailable:
          type: boolean
          description: >-
            True when the upstream or seed-backed variant is unavailable; empty
            payload fields
             are graceful degradation, not confirmed zero data.
    CotInstrument:
      type: object
      properties:
        name:
          type: string
        code:
          type: string
        reportDate:
          type: string
        assetManagerLong:
          type: string
          format: int64
        assetManagerShort:
          type: string
          format: int64
        leveragedFundsLong:
          type: string
          format: int64
        leveragedFundsShort:
          type: string
          format: int64
        dealerLong:
          type: string
          format: int64
        dealerShort:
          type: string
          format: int64
        netPct:
          type: number
          format: double
    GetInsiderTransactionsRequest:
      type: object
      properties:
        symbol:
          type: string
          maxLength: 32
          minLength: 1
          description: Stock ticker symbol for insider transaction lookup.
      required:
        - symbol
    GetInsiderTransactionsResponse:
      type: object
      properties:
        unavailable:
          type: boolean
          description: >-
            True when the upstream or seed-backed variant is unavailable; empty
            payload fields
             are graceful degradation, not confirmed zero data.
        symbol:
          type: string
        totalBuys:
          type: number
          format: double
        totalSells:
          type: number
          format: double
        netValue:
          type: number
          format: double
        transactions:
          type: array
          items:
            $ref: '#/components/schemas/InsiderTransaction'
        fetchedAt:
          type: string
    InsiderTransaction:
      type: object
      properties:
        name:
          type: string
        shares:
          type: integer
          format: int64
          description: 'Warning: Values > 2^53 may lose precision in JavaScript'
        value:
          type: number
          format: double
        transactionCode:
          type: string
        transactionDate:
          type: string
    GetMarketBreadthHistoryRequest:
      type: object
    GetMarketBreadthHistoryResponse:
      type: object
      properties:
        currentPctAbove20d:
          type: number
          format: double
        currentPctAbove50d:
          type: number
          format: double
        currentPctAbove200d:
          type: number
          format: double
        updatedAt:
          type: string
        history:
          type: array
          items:
            $ref: '#/components/schemas/BreadthSnapshot'
        unavailable:
          type: boolean
          description: >-
            True when the upstream or seed-backed variant is unavailable; empty
            payload fields
             are graceful degradation, not confirmed zero data.
    BreadthSnapshot:
      type: object
      properties:
        date:
          type: string
        pctAbove20d:
          type: number
          format: double
          description: >-
            Optional so a missing/failed Barchart reading serializes as JSON
            null
             instead of collapsing to 0, which would render identically to a real 0%
             reading (severe market dislocation with no S&P stocks above SMA).
        pctAbove50d:
          type: number
          format: double
        pctAbove200d:
          type: number
          format: double
    GetGoldIntelligenceRequest:
      type: object
    GetGoldIntelligenceResponse:
      type: object
      properties:
        goldPrice:
          type: number
          format: double
        goldChangePct:
          type: number
          format: double
        goldSparkline:
          type: array
          items:
            type: number
            format: double
        silverPrice:
          type: number
          format: double
        platinumPrice:
          type: number
          format: double
        palladiumPrice:
          type: number
          format: double
        goldSilverRatio:
          type: number
          format: double
        goldPlatinumPremiumPct:
          type: number
          format: double
        crossCurrencyPrices:
          type: array
          items:
            $ref: '#/components/schemas/GoldCrossCurrencyPrice'
        cot:
          $ref: '#/components/schemas/GoldCotPositioning'
        updatedAt:
          type: string
        unavailable:
          type: boolean
          description: >-
            True when the upstream or seed-backed variant is unavailable; empty
            payload fields
             are graceful degradation, not confirmed zero data.
        session:
          $ref: '#/components/schemas/GoldSessionRange'
        returns:
          $ref: '#/components/schemas/GoldReturns'
        range52w:
          $ref: '#/components/schemas/GoldRange52w'
        drivers:
          type: array
          items:
            $ref: '#/components/schemas/GoldDriver'
        etfFlows:
          $ref: '#/components/schemas/GoldEtfFlows'
        cbReserves:
          $ref: '#/components/schemas/GoldCbReserves'
    GoldCrossCurrencyPrice:
      type: object
      properties:
        currency:
          type: string
        flag:
          type: string
        price:
          type: number
          format: double
    GoldCotPositioning:
      type: object
      properties:
        reportDate:
          type: string
        nextReleaseDate:
          type: string
        openInterest:
          type: string
          format: int64
        managedMoney:
          $ref: '#/components/schemas/GoldCotCategory'
        producerSwap:
          $ref: '#/components/schemas/GoldCotCategory'
    GoldCotCategory:
      type: object
      properties:
        longPositions:
          type: string
          format: int64
        shortPositions:
          type: string
          format: int64
        netPct:
          type: number
          format: double
        oiSharePct:
          type: number
          format: double
        wowNetDelta:
          type: string
          format: int64
    GoldSessionRange:
      type: object
      properties:
        dayHigh:
          type: number
          format: double
        dayLow:
          type: number
          format: double
        prevClose:
          type: number
          format: double
    GoldReturns:
      type: object
      properties:
        w1:
          type: number
          format: double
        m1:
          type: number
          format: double
        ytd:
          type: number
          format: double
        y1:
          type: number
          format: double
    GoldRange52w:
      type: object
      properties:
        hi:
          type: number
          format: double
        lo:
          type: number
          format: double
        positionPct:
          type: number
          format: double
    GoldDriver:
      type: object
      properties:
        symbol:
          type: string
        label:
          type: string
        value:
          type: number
          format: double
        changePct:
          type: number
          format: double
        correlation30d:
          type: number
          format: double
    GoldEtfFlows:
      type: object
      properties:
        asOfDate:
          type: string
        tonnes:
          type: number
          format: double
        aumUsd:
          type: number
          format: double
        nav:
          type: number
          format: double
        changeW1Tonnes:
          type: number
          format: double
        changeM1Tonnes:
          type: number
          format: double
        changeY1Tonnes:
          type: number
          format: double
        changeW1Pct:
          type: number
          format: double
        changeM1Pct:
          type: number
          format: double
        changeY1Pct:
          type: number
          format: double
        sparkline90d:
          type: array
          items:
            type: number
            format: double
    GoldCbReserves:
      type: object
      properties:
        asOfMonth:
          type: string
        totalTonnes:
          type: number
          format: double
        topHolders:
          type: array
          items:
            $ref: '#/components/schemas/GoldCbHolder'
        topBuyers12m:
          type: array
          items:
            $ref: '#/components/schemas/GoldCbMover'
        topSellers12m:
          type: array
          items:
            $ref: '#/components/schemas/GoldCbMover'
    GoldCbHolder:
      type: object
      properties:
        iso3:
          type: string
        name:
          type: string
        tonnes:
          type: number
          format: double
        pctOfReserves:
          type: number
          format: double
    GoldCbMover:
      type: object
      properties:
        iso3:
          type: string
        name:
          type: string
        deltaTonnes12m:
          type: number
          format: double
    GetHyperliquidFlowRequest:
      type: object
    GetHyperliquidFlowResponse:
      type: object
      properties:
        ts:
          type: string
          format: int64
        fetchedAt:
          type: string
        warmup:
          type: boolean
        assetCount:
          type: integer
          format: int32
        assets:
          type: array
          items:
            $ref: '#/components/schemas/HyperliquidAssetFlow'
        unavailable:
          type: boolean
          description: >-
            True when the upstream or seed-backed variant is unavailable; empty
            payload fields
             are graceful degradation, not confirmed zero data.
    HyperliquidAssetFlow:
      type: object
      properties:
        symbol:
          type: string
        display:
          type: string
        assetClass:
          type: string
        group:
          type: string
        funding:
          type: string
          description: >-
            Raw metrics (nullable as strings to preserve precision; "" =
            unavailable)
        openInterest:
          type: string
        markPx:
          type: string
        oraclePx:
          type: string
        dayNotional:
          type: string
        fundingScore:
          type: number
          format: double
          description: Component scores 0-100
        volumeScore:
          type: number
          format: double
        oiScore:
          type: number
          format: double
        basisScore:
          type: number
          format: double
        composite:
          type: number
          format: double
        sparkFunding:
          type: array
          items:
            type: number
            format: double
            description: Sparkline arrays (most recent last); up to 60 samples (5h @ 5min)
        sparkOi:
          type: array
          items:
            type: number
            format: double
        sparkScore:
          type: array
          items:
            type: number
            format: double
        warmup:
          type: boolean
          description: State flags
        stale:
          type: boolean
        staleSince:
          type: string
          format: int64
        missingPolls:
          type: integer
          format: int32
        alerts:
          type: array
          items:
            type: string
