openapi: 3.1.0
info:
  title: EconomicService API
  version: 1.0.0
security:
  - WorldMonitorKey: []
  - ApiKeyHeader: []
servers:
  - url: https://api.worldmonitor.app
paths:
  /api/economic/v1/get-fred-series:
    get:
      tags:
        - EconomicService
      summary: GetFredSeries
      description: >-
        GetFredSeries retrieves time series data from the Federal Reserve
        Economic Data.
      operationId: GetFredSeries
      parameters:
        - name: series_id
          in: query
          description: FRED series ID (e.g., "GDP", "UNRATE", "CPIAUCSL").
          required: true
          example: GDP
          schema:
            type: string
        - name: limit
          in: query
          description: Maximum number of observations to return. Defaults to 120.
          required: false
          example: 25
          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:
                series:
                  frequency: example
                  observations:
                    - date: '2026-01-15'
                      value: 1.5
                  seriesId: GDP
                  title: example
                  units: example
              schema:
                $ref: '#/components/schemas/GetFredSeriesResponse'
        '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/economic/v1/list-world-bank-indicators:
    get:
      tags:
        - EconomicService
      summary: ListWorldBankIndicators
      description: >-
        ListWorldBankIndicators retrieves development indicator data from the
        World Bank.
      operationId: ListWorldBankIndicators
      parameters:
        - name: indicator_code
          in: query
          description: World Bank indicator code (e.g., "NY.GDP.MKTP.CD").
          required: true
          example: NY.GDP.MKTP.CD
          schema:
            type: string
        - name: country_code
          in: query
          description: Optional country filter (ISO 3166-1 alpha-2).
          required: false
          example: US
          schema:
            type: string
        - name: year
          in: query
          description: Optional year filter. Defaults to latest available.
          required: false
          example: 1
          schema:
            type: integer
            format: int32
        - name: page_size
          in: query
          description: |-
            Maximum items per page.
             Accepted but currently ignored; no-op until this handler supports the parameter.
          required: false
          example: 25
          schema:
            type: integer
            format: int32
        - name: cursor
          in: query
          description: |-
            Cursor for next page.
             Accepted but currently ignored; no-op until this handler supports the parameter.
          required: false
          example: next-page-token
          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:
                data:
                  - countryCode: US
                    countryName: US
                    indicatorCode: NY.GDP.MKTP.CD
                    indicatorName: WorldMonitor Analyst
                    value: 1.5
                    year: 1
                pagination:
                  nextCursor: next-page-token
                  totalCount: 1
              schema:
                $ref: '#/components/schemas/ListWorldBankIndicatorsResponse'
        '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/economic/v1/get-energy-prices:
    get:
      tags:
        - EconomicService
      summary: GetEnergyPrices
      description: GetEnergyPrices retrieves current energy commodity prices from EIA.
      operationId: GetEnergyPrices
      parameters:
        - name: commodities
          in: query
          description: Optional commodity filter. Empty returns all tracked commodities.
          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:
                prices:
                  - change: 1.5
                    commodity: example
                    name: WorldMonitor Analyst
                    price: 75.25
                    priceAt: 1717200000000
                    unit: example
              schema:
                $ref: '#/components/schemas/GetEnergyPricesResponse'
        '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/economic/v1/get-macro-signals:
    get:
      tags:
        - EconomicService
      summary: GetMacroSignals
      description: >-
        GetMacroSignals computes 7 macro signals from 6 upstream sources with
        BUY/CASH verdict.
      operationId: GetMacroSignals
      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:
                bullishCount: 1
                meta:
                  qqqSparkline:
                    - 1.5
                signals:
                  fearGreed:
                    history:
                      - date: '2026-01-15'
                        value: 1
                    status: example
                    value: 1
                  flowStructure:
                    btcReturn5: 1.5
                    qqqReturn5: 1.5
                    status: example
                  hashRate:
                    change30d: 1.5
                    status: example
                  liquidity:
                    sparkline:
                      - 1.5
                    status: example
                    value: 1.5
                  macroRegime:
                    qqqRoc20: 1.5
                    status: example
                    xlpRoc20: 1.5
                timestamp: '2026-01-15T12:00:00Z'
                totalCount: 1
              schema:
                $ref: '#/components/schemas/GetMacroSignalsResponse'
        '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/economic/v1/get-china-macro-snapshot:
    get:
      tags:
        - EconomicService
      summary: GetChinaMacroSnapshot
      description: >-
        GetChinaMacroSnapshot reads the normalized China macro and official
        release
         calendar seeds. It never fans out to upstream providers on a cache miss.
      operationId: GetChinaMacroSnapshot
      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:
                contentObservationDate: '2026-01-15'
                countryCode: US
                generatedAt: '2026-01-15T12:00:00Z'
                indicators:
                  - category: cs.AI
                    comparisonBasis: example
                    comparisonValue: 1.5
                    contextOnly: true
                    direction: example
                latestObservationDate: '40.7128'
              schema:
                $ref: '#/components/schemas/GetChinaMacroSnapshotResponse'
        '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/economic/v1/get-china-activity-nowcast:
    get:
      tags:
        - EconomicService
      summary: GetChinaActivityNowcast
      description: |-
        GetChinaActivityNowcast compares the revision-aware official macro pulse
         with reviewed proxy families using a deterministic, no-lookahead method.
      operationId: GetChinaActivityNowcast
      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:
                comparisonState: example
                generatedAt: '2026-01-15T12:00:00Z'
                methodVersion: example
                payloadJson: example
                upstreamUnavailable: true
              schema:
                $ref: '#/components/schemas/GetChinaActivityNowcastResponse'
        '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/economic/v1/get-energy-capacity:
    get:
      tags:
        - EconomicService
      summary: GetEnergyCapacity
      description: >-
        GetEnergyCapacity retrieves installed capacity data (solar, wind, coal)
        from EIA.
      operationId: GetEnergyCapacity
      parameters:
        - name: energy_sources
          in: query
          description: |-
            Energy source codes to query (e.g., "SUN", "WND", "COL").
             Empty returns all tracked sources (SUN, WND, COL).
          required: false
          style: form
          explode: true
          example:
            - example
          schema:
            type: array
            items:
              type: string
        - name: years
          in: query
          description: |-
            Number of years of historical data. Default 20 if not set.
             Accepted but currently ignored; no-op until this handler supports the parameter.
          required: false
          example: 1
          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:
                series:
                  - data:
                      - capacityMw: 1.5
                        year: 1
                    energySource: example
                    name: WorldMonitor Analyst
              schema:
                $ref: '#/components/schemas/GetEnergyCapacityResponse'
        '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/economic/v1/get-bis-policy-rates:
    get:
      tags:
        - EconomicService
      summary: GetBisPolicyRates
      description: GetBisPolicyRates retrieves central bank policy rates from BIS.
      operationId: GetBisPolicyRates
      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:
                rates:
                  - centralBank: example
                    countryCode: US
                    countryName: US
                    date: '2026-01-15'
                    previousRate: 75.25
              schema:
                $ref: '#/components/schemas/GetBisPolicyRatesResponse'
        '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/economic/v1/get-bis-exchange-rates:
    get:
      tags:
        - EconomicService
      summary: GetBisExchangeRates
      description: GetBisExchangeRates retrieves effective exchange rates from BIS.
      operationId: GetBisExchangeRates
      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:
                rates:
                  - countryCode: US
                    countryName: US
                    date: '2026-01-15'
                    nominalEer: 1.5
                    realChange: 1.5
              schema:
                $ref: '#/components/schemas/GetBisExchangeRatesResponse'
        '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/economic/v1/get-bis-credit:
    get:
      tags:
        - EconomicService
      summary: GetBisCredit
      description: GetBisCredit retrieves credit-to-GDP ratio data from BIS.
      operationId: GetBisCredit
      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:
                entries:
                  - countryCode: US
                    countryName: US
                    creditGdpRatio: 42.5
                    date: '2026-01-15'
                    previousRatio: 42.5
              schema:
                $ref: '#/components/schemas/GetBisCreditResponse'
        '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/economic/v1/get-fred-series-batch:
    post:
      parameters:
        - name: Idempotency-Key
          in: header
          description: >-
            Optional client-generated idempotency key. Retrying a POST with the
            same key and an identical request body replays the original response
            (only the status, body, and Content-Type are reproduced) instead of
            re-executing; reusing the key with a different body is rejected with
            422. For mutations this avoids duplicating the side effect, while
            for batch-read POSTs it replays a cached snapshot that can be up to
            24 hours stale. Keys are scoped per authenticated caller (falling
            back to the source IP for unauthenticated endpoints) and retained
            for 24 hours.
          required: false
          example: 4f8b9c2e-1a3d-4b6f-8e0a-2c5d7f9b1e34
          schema:
            type: string
            minLength: 1
            maxLength: 255
            pattern: ^[\x21-\x7E]{1,255}$
      tags:
        - EconomicService
      summary: GetFredSeriesBatch
      description: GetFredSeriesBatch retrieves multiple FRED series in a single call.
      operationId: GetFredSeriesBatch
      requestBody:
        content:
          application/json:
            example:
              limit: 25
              seriesIds:
                - GDP
            schema:
              $ref: '#/components/schemas/GetFredSeriesBatchRequest'
        required: true
      responses:
        '200':
          description: Successful response
          headers:
            Idempotency-Key:
              schema:
                type: string
              description: >-
                The idempotency key echoed from the request. Present only when
                the client opted into idempotency.
            Idempotent-Replayed:
              schema:
                type: boolean
              description: >-
                true when this response was replayed from an earlier request
                with the same key, false on the first (original) request.
                Present only when the client opted into idempotency.
          content:
            application/json:
              example:
                fetched: 1
                requested: 1
                results:
                  exampleKey:
                    frequency: example
                    observations:
                      - date: '2026-01-15'
                        value: 1.5
                    seriesId: GDP
                    title: example
                    units: example
              schema:
                $ref: '#/components/schemas/GetFredSeriesBatchResponse'
        '400':
          description: >-
            Validation error, invalid Idempotency-Key header, or malformed JSON
            request body
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ValidationError'
                  - type: object
                    required:
                      - error
                      - message
                    properties:
                      error:
                        type: string
                      message:
                        type: string
                  - $ref: '#/components/schemas/InvalidRequestBodyError'
        '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'
        '409':
          description: A request with this Idempotency-Key is still being processed
          headers:
            Idempotency-Key:
              schema:
                type: string
              description: The idempotency key supplied by the client.
            Retry-After:
              schema:
                type: string
              description: Seconds to wait before retrying the in-flight request.
          content:
            application/json:
              schema:
                type: object
                required:
                  - error
                  - message
                properties:
                  error:
                    type: string
                  message:
                    type: string
        '422':
          description: The Idempotency-Key was already used with a different request body
          headers:
            Idempotency-Key:
              schema:
                type: string
              description: The idempotency key supplied by the client.
          content:
            application/json:
              schema:
                type: object
                required:
                  - error
                  - message
                properties:
                  error:
                    type: string
                  message:
                    type: string
        '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/economic/v1/list-grocery-basket-prices:
    get:
      tags:
        - EconomicService
      summary: ListGroceryBasketPrices
      description: >-
        ListGroceryBasketPrices retrieves grocery basket price comparison across
        24 countries worldwide.
      operationId: ListGroceryBasketPrices
      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:
                cheapestCountry: US
                countries:
                  - code: example
                    currency: USD
                    flag: example
                    fxRate: 75.25
                    items:
                      - available: true
                        currency: USD
                        itemId: example-id
                        itemName: WorldMonitor Analyst
                        localPrice: 75.25
                fetchedAt: '2026-01-15T12:00:00Z'
                mostExpensiveCountry: US
                prevFetchedAt: '2026-01-15T12:00:00Z'
              schema:
                $ref: '#/components/schemas/ListGroceryBasketPricesResponse'
        '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/economic/v1/list-bigmac-prices:
    get:
      tags:
        - EconomicService
      summary: ListBigMacPrices
      description: >-
        ListBigMacPrices retrieves Big Mac Index prices across Middle East
        countries.
      operationId: ListBigMacPrices
      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:
                cheapestCountry: US
                countries:
                  - available: true
                    code: example
                    currency: USD
                    flag: example
                    fxRate: 75.25
                fetchedAt: '2026-01-15T12:00:00Z'
                mostExpensiveCountry: US
                prevFetchedAt: '2026-01-15T12:00:00Z'
              schema:
                $ref: '#/components/schemas/ListBigMacPricesResponse'
        '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/economic/v1/get-national-debt:
    get:
      tags:
        - EconomicService
      summary: GetNationalDebt
      description: >-
        GetNationalDebt retrieves national debt clock data for all countries.
        PRO-gated. Requires an active Pro subscription.
      operationId: GetNationalDebt
      security:
        - WorldMonitorKey: []
        - ApiKeyHeader: []
        - BearerAuth: []
      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:
                entries:
                  - annualGrowth: 1.5
                    baselineTs: '1717200000000'
                    debtToGdp: 1.5
                    debtUsd: 1.5
                    gdpUsd: 1.5
                seededAt: '2026-01-15T12:00:00Z'
                unavailable: true
              schema:
                $ref: '#/components/schemas/GetNationalDebtResponse'
        '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 subscription required.
          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/economic/v1/list-fuel-prices:
    get:
      tags:
        - EconomicService
      summary: ListFuelPrices
      description: >-
        ListFuelPrices retrieves retail gasoline and diesel prices across 30+
        countries.
      operationId: ListFuelPrices
      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:
                cheapestDiesel: example
                cheapestGasoline: example
                countries:
                  - code: example
                    currency: USD
                    diesel:
                      available: true
                      grade: example
                      localPrice: 75.25
                      observedAt: '2026-01-15T12:00:00Z'
                      source: example
                    flag: example
                    fxRate: 75.25
                countryCount: 1
                fetchedAt: '2026-01-15T12:00:00Z'
              schema:
                $ref: '#/components/schemas/ListFuelPricesResponse'
        '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/economic/v1/get-bls-series:
    get:
      tags:
        - EconomicService
      summary: GetBlsSeries
      description: >-
        GetBlsSeries retrieves BLS-only series not available on FRED (CES,
        LAUMT, CIU).
      operationId: GetBlsSeries
      parameters:
        - name: series_id
          in: query
          description: 'BLS/FRED-backed series ID. Supported values: "USPRIV", "ECIALLCIV".'
          required: false
          example: USPRIV
          schema:
            type: string
            enum:
              - USPRIV
              - ECIALLCIV
        - name: limit
          in: query
          description: Maximum number of observations to return. Defaults to 60.
          required: false
          example: 25
          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:
                series:
                  observations:
                    - period: daily
                      periodName: daily
                      value: example
                      year: example
                  seriesId: example-id
                  title: example
                  units: example
              schema:
                $ref: '#/components/schemas/GetBlsSeriesResponse'
        '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/economic/v1/get-economic-calendar:
    get:
      tags:
        - EconomicService
      summary: GetEconomicCalendar
      description: >-
        GetEconomicCalendar retrieves upcoming major economic events (FOMC, CPI,
        NFP, etc).
      operationId: GetEconomicCalendar
      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:
                events:
                  - actual: example
                    country: US
                    date: '2026-01-15'
                    estimate: example
                    event: example
                fromDate: '2026-01-15'
                toDate: '2026-01-15'
                total: 1
                unavailable: true
              schema:
                $ref: '#/components/schemas/GetEconomicCalendarResponse'
        '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/economic/v1/get-crude-inventories:
    get:
      tags:
        - EconomicService
      summary: GetCrudeInventories
      description: >-
        GetCrudeInventories retrieves the 8 most recent weeks of US crude oil
        stockpile data from EIA (WCRSTUS1).
      operationId: GetCrudeInventories
      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:
                latestPeriod: '40.7128'
                weeks:
                  - period: daily
                    stocksMb: 1.5
                    weeklyChangeMb: 1.5
              schema:
                $ref: '#/components/schemas/GetCrudeInventoriesResponse'
        '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/economic/v1/get-nat-gas-storage:
    get:
      tags:
        - EconomicService
      summary: GetNatGasStorage
      description: >-
        GetNatGasStorage retrieves the 8 most recent weeks of US natural gas
        working gas storage from EIA (NW2_EPG0_SWO_R48_BCF).
      operationId: GetNatGasStorage
      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:
                latestPeriod: '40.7128'
                weeks:
                  - period: daily
                    storBcf: 1.5
                    weeklyChangeBcf: 1.5
              schema:
                $ref: '#/components/schemas/GetNatGasStorageResponse'
        '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/economic/v1/get-ecb-fx-rates:
    get:
      tags:
        - EconomicService
      summary: GetEcbFxRates
      description: >-
        GetEcbFxRates retrieves daily ECB official reference rates for EUR/major
        currency pairs.
      operationId: GetEcbFxRates
      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:
                rates:
                  - change1d: 1.5
                    date: '2026-01-15'
                    pair: example
                    rate: 75.25
                seededAt: '1717200000000'
                unavailable: true
                updatedAt: '2026-01-15'
              schema:
                $ref: '#/components/schemas/GetEcbFxRatesResponse'
        '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/economic/v1/get-eurostat-country-data:
    get:
      tags:
        - EconomicService
      summary: GetEurostatCountryData
      description: >-
        GetEurostatCountryData retrieves per-country CPI, unemployment, and GDP
        growth for 10 EU member states.
      operationId: GetEurostatCountryData
      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:
                countries:
                  exampleKey:
                    cpi:
                      date: '2026-01-15'
                      hasPrior: true
                      priorValue: 1.5
                      unit: example
                      value: 1.5
                    gdpGrowth:
                      date: '2026-01-15'
                      hasPrior: true
                      priorValue: 1.5
                      unit: example
                      value: 1.5
                    unemployment:
                      date: '2026-01-15'
                      hasPrior: true
                      priorValue: 1.5
                      unit: example
                      value: 1.5
                seededAt: '1717200000000'
                unavailable: true
              schema:
                $ref: '#/components/schemas/GetEurostatCountryDataResponse'
        '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/economic/v1/get-eu-gas-storage:
    get:
      tags:
        - EconomicService
      summary: GetEuGasStorage
      description: >-
        GetEuGasStorage retrieves EU aggregate natural gas storage fill % from
        GIE AGSI+.
      operationId: GetEuGasStorage
      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:
                fillPct: 1.5
                fillPctChange1d: 1.5
                gasDaysConsumption: 7
                history:
                  - date: '2026-01-15'
                    fillPct: 1.5
                    gasTwh: 1.5
                seededAt: '1717200000000'
              schema:
                $ref: '#/components/schemas/GetEuGasStorageResponse'
        '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/economic/v1/get-eu-yield-curve:
    get:
      tags:
        - EconomicService
      summary: GetEuYieldCurve
      description: >-
        GetEuYieldCurve retrieves the ECB Euro Area AAA sovereign yield curve
        (Svensson model spot rates).
      operationId: GetEuYieldCurve
      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:
                data:
                  date: '2026-01-15'
                  rates:
                    exampleKey: 1.5
                  source: example
                  updatedAt: '2026-01-15'
                unavailable: true
              schema:
                $ref: '#/components/schemas/GetEuYieldCurveResponse'
        '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/economic/v1/get-eu-fsi:
    get:
      tags:
        - EconomicService
      summary: GetEuFsi
      description: >-
        GetEuFsi retrieves the ECB CISS (Composite Indicator of Systemic Stress)
        for the Euro area.
      operationId: GetEuFsi
      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:
                history:
                  - date: '2026-01-15'
                    value: 1.5
                label: example
                latestDate: '40.7128'
                latestValue: 1.5
                seededAt: '2026-01-15T12:00:00Z'
              schema:
                $ref: '#/components/schemas/GetEuFsiResponse'
        '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/economic/v1/get-economic-stress:
    get:
      tags:
        - EconomicService
      summary: GetEconomicStress
      description: >-
        GetEconomicStress retrieves the composite Economic Stress Index (0-100)
        from 6 FRED series.
      operationId: GetEconomicStress
      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:
                components:
                  - id: example-id
                    label: example
                    missing: true
                    rawValue: 1.5
                    score: 42.5
                compositeScore: 42.5
                label: example
                seededAt: '2026-01-15T12:00:00Z'
                unavailable: true
              schema:
                $ref: '#/components/schemas/GetEconomicStressResponse'
        '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/economic/v1/get-fao-food-price-index:
    get:
      tags:
        - EconomicService
      summary: GetFaoFoodPriceIndex
      description: >-
        GetFaoFoodPriceIndex retrieves the FAO Food Price Index for the past 12
        months.
      operationId: GetFaoFoodPriceIndex
      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:
                currentFfpi: 1.5
                fetchedAt: '2026-01-15T12:00:00Z'
                momPct: 1.5
                points:
                  - cereals: 1.5
                    dairy: 1.5
                    date: '2026-01-15'
                    ffpi: 1.5
                    meat: 1717200000000
                yoyPct: 1.5
              schema:
                $ref: '#/components/schemas/GetFaoFoodPriceIndexResponse'
        '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/economic/v1/get-oil-stocks-analysis:
    get:
      tags:
        - EconomicService
      summary: GetOilStocksAnalysis
      description: >-
        GetOilStocksAnalysis retrieves the IEA oil stocks days-of-cover ranking
        and regional summary.
      operationId: GetOilStocksAnalysis
      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:
                belowObligation:
                  - example
                dataMonth: example
                ieaMembers:
                  - belowObligation: true
                    daysOfCover: 7
                    iso2: US
                    netExporter: true
                    obligationMet: true
                regionalSummary:
                  asiaPacific:
                    avgDays: 7
                    countBelowObligation: 1
                    minDays: 7
                  europe:
                    avgDays: 7
                    countBelowObligation: 1
                    minDays: 7
                  northAmerica:
                    avgDays: 7
                    netExporters: 1
                unavailable: true
              schema:
                $ref: '#/components/schemas/GetOilStocksAnalysisResponse'
        '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/economic/v1/get-oil-inventories:
    get:
      tags:
        - EconomicService
      summary: GetOilInventories
      description: >-
        GetOilInventories returns recent oil-inventory series: US crude weeks,
        the SPR snapshot, natural-gas weeks, EU gas storage, and IEA stocks.
      operationId: GetOilInventories
      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:
                crudeWeeks:
                  - period: daily
                    stocksMb: 1.5
                    weeklyChangeMb: 1.5
                euGas:
                  fillPct: 1.5
                  fillPctChange1d: 1.5
                  history:
                    - date: '2026-01-15'
                      fillPct: 1.5
                  trend: example
                ieaStocks:
                  asiaPacific:
                    avgDays: 7
                    countBelowObligation: 1
                    minDays: 7
                  dataMonth: example
                  europe:
                    avgDays: 7
                    countBelowObligation: 1
                    minDays: 7
                  members:
                    - belowObligation: true
                      daysOfCover: 7
                      iso2: US
                      netExporter: true
                  northAmerica:
                    avgDays: 7
                    countBelowObligation: 1
                    minDays: 7
                natGasWeeks:
                  - period: daily
                    storBcf: 1.5
                    weeklyChangeBcf: 1.5
                refinery:
                  inputsMbpd: 1.5
                  period: daily
              schema:
                $ref: '#/components/schemas/GetOilInventoriesResponse'
        '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/economic/v1/get-energy-crisis-policies:
    get:
      tags:
        - EconomicService
      summary: GetEnergyCrisisPolicies
      description: >-
        GetEnergyCrisisPolicies retrieves government policy responses to the
        2026 energy crisis from the IEA tracker.
      operationId: GetEnergyCrisisPolicies
      parameters:
        - name: country_code
          in: query
          description: Optional ISO-2 country code filter.
          required: false
          example: US
          schema:
            type: string
        - name: category
          in: query
          description: 'Optional category filter: "conservation" or "consumer_support".'
          required: false
          example: cs.AI
          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:
                context: example
                policies:
                  - category: cs.AI
                    country: US
                    countryCode: US
                    dateAnnounced: '2026-01-15'
                    measure: example
                source: example
                sourceUrl: https://example.com/worldmonitor
                unavailable: true
              schema:
                $ref: '#/components/schemas/GetEnergyCrisisPoliciesResponse'
        '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/economic/v1/list-global-tenders:
    get:
      tags:
        - EconomicService
      summary: ListGlobalTenders
      description: >-
        ListGlobalTenders returns the Pro-gated, paginated, seed-backed
        canonical procurement feed. Requires entitlement tier >= 1.
      operationId: ListGlobalTenders
      security:
        - WorldMonitorKey: []
        - ApiKeyHeader: []
        - BearerAuth: []
      parameters:
        - name: country
          in: query
          description: ISO 3166-1 alpha-2 country code to match.
          required: false
          example: US
          schema:
            type: string
        - name: countries
          in: query
          description: One or more ISO 3166-1 alpha-2 country codes to match.
          required: false
          style: form
          explode: true
          example:
            - US
          schema:
            type: array
            items:
              type: string
        - name: region
          in: query
          description: Geographic region label to match, such as Europe or North America.
          required: false
          example: example
          schema:
            type: string
        - name: source
          in: query
          description: >-
            Source adapter identifier: sam, ted, contracts-finder, canada-buys,
            gets, or world-bank.
          required: false
          example: example
          schema:
            type: string
        - name: status
          in: query
          description: Source-provided tender status to match, such as open or published.
          required: false
          example: example
          schema:
            type: string
        - name: deadline_from
          in: query
          description: >-
            Include opportunities whose deadline is on or after this ISO-8601
            timestamp.
          required: false
          example: example
          schema:
            type: string
        - name: deadline_to
          in: query
          description: >-
            Include opportunities whose deadline is on or before this ISO-8601
            timestamp.
          required: false
          example: example
          schema:
            type: string
        - name: min_value
          in: query
          description: >-
            Include opportunities with a stated estimated value at or above this
            amount.
          required: false
          example: 1.5
          schema:
            type: number
            format: double
        - name: max_value
          in: query
          description: >-
            Include opportunities with a stated estimated value at or below this
            amount.
          required: false
          example: 1.5
          schema:
            type: number
            format: double
        - name: currency
          in: query
          description: ISO 4217 currency code used with min_value and max_value.
          required: false
          example: USD
          schema:
            type: string
        - name: category
          in: query
          description: Procurement category or classification code to match.
          required: false
          example: cs.AI
          schema:
            type: string
        - name: query
          in: query
          description: >-
            Case-insensitive search text matched against tender titles and
            descriptions.
          required: false
          example: supply chain risk
          schema:
            type: string
        - name: page_size
          in: query
          description: Maximum number of tenders to return per page; capped at 100.
          required: false
          example: 25
          schema:
            type: integer
            format: int32
        - name: cursor
          in: query
          description: Opaque cursor from a previous response's next_cursor field.
          required: false
          example: next-page-token
          schema:
            type: string
        - name: sort
          in: query
          description: >-
            Result ordering: newest, closing_soon, estimated_value, or
            relevance.
          required: false
          example: example
          schema:
            type: string
        - name: buyer
          in: query
          description: Case-insensitive buyer or contracting-authority text to match.
          required: false
          example: example
          schema:
            type: string
        - name: published_from
          in: query
          description: Include opportunities published on or after this ISO-8601 timestamp.
          required: false
          example: example
          schema:
            type: string
        - name: published_to
          in: query
          description: >-
            Include opportunities published on or before this ISO-8601
            timestamp.
          required: false
          example: example
          schema:
            type: string
        - name: min_automation_score
          in: query
          description: >-
            Include only opportunities whose keyword-based automation_fit score
            is at
             or above this integer value (1-100; values above 100 are clamped, and
             non-integer or non-positive values disable the filter). Disabled when 0
             or unset, which preserves the default all-open-opportunities behavior.
             This is an evidence-backed text-relevance threshold only; it does not
             assert that any party is eligible to bid.
          required: false
          example: 42
          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:
                appliedFilters:
                  - example
                availability: example
                countryCoverage: US
                dataAvailable: true
                fetchedAt: '2026-01-15T12:00:00Z'
              schema:
                $ref: '#/components/schemas/ListGlobalTendersResponse'
        '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'
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.
    GetFredSeriesRequest:
      type: object
      properties:
        seriesId:
          type: string
          minLength: 1
          description: FRED series ID (e.g., "GDP", "UNRATE", "CPIAUCSL").
        limit:
          type: integer
          format: int32
          description: Maximum number of observations to return. Defaults to 120.
      required:
        - seriesId
      description: GetFredSeriesRequest specifies which FRED series to retrieve.
    GetFredSeriesResponse:
      type: object
      properties:
        series:
          $ref: '#/components/schemas/FredSeries'
      description: GetFredSeriesResponse contains the requested FRED series data.
    FredSeries:
      type: object
      properties:
        seriesId:
          type: string
          minLength: 1
          description: Series identifier (e.g., "GDP", "UNRATE", "CPIAUCSL").
        title:
          type: string
          description: Series title.
        units:
          type: string
          description: Unit of measurement.
        frequency:
          type: string
          description: Data frequency (e.g., "Monthly", "Quarterly").
        observations:
          type: array
          items:
            $ref: '#/components/schemas/FredObservation'
      required:
        - seriesId
      description: FredSeries represents a FRED time series with metadata.
    FredObservation:
      type: object
      properties:
        date:
          type: string
          description: Observation date as YYYY-MM-DD string.
        value:
          type: number
          format: double
          description: Observation value.
      description: >-
        FredObservation represents a single data point from a FRED economic
        series.
    ListWorldBankIndicatorsRequest:
      type: object
      properties:
        indicatorCode:
          type: string
          minLength: 1
          description: World Bank indicator code (e.g., "NY.GDP.MKTP.CD").
        countryCode:
          type: string
          description: Optional country filter (ISO 3166-1 alpha-2).
        year:
          type: integer
          format: int32
          description: Optional year filter. Defaults to latest available.
        pageSize:
          type: integer
          format: int32
          description: |-
            Maximum items per page.
             Accepted but currently ignored; no-op until this handler supports the parameter.
        cursor:
          type: string
          description: |-
            Cursor for next page.
             Accepted but currently ignored; no-op until this handler supports the parameter.
      required:
        - indicatorCode
      description: >-
        ListWorldBankIndicatorsRequest specifies filters for retrieving World
        Bank data.
    ListWorldBankIndicatorsResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/WorldBankCountryData'
        pagination:
          $ref: '#/components/schemas/PaginationResponse'
      description: ListWorldBankIndicatorsResponse contains World Bank indicator data.
    WorldBankCountryData:
      type: object
      properties:
        countryCode:
          type: string
          minLength: 1
          description: ISO 3166-1 alpha-2 country code.
        countryName:
          type: string
          description: Country name.
        indicatorCode:
          type: string
          minLength: 1
          description: World Bank indicator code (e.g., "NY.GDP.MKTP.CD").
        indicatorName:
          type: string
          description: Indicator name.
        year:
          type: integer
          format: int32
          description: Data year.
        value:
          type: number
          format: double
          description: Indicator value.
      required:
        - countryCode
        - indicatorCode
      description: >-
        WorldBankCountryData represents a World Bank indicator value for a
        country.
    PaginationResponse:
      type: object
      properties:
        nextCursor:
          type: string
          description: >-
            Cursor for fetching the next page. Empty string indicates no more
            pages.
        totalCount:
          type: integer
          format: int32
          description: >-
            Total count of items matching the query, if known. Zero if the total
            is unknown.
      description: >-
        PaginationResponse contains pagination metadata returned alongside list
        results.
    GetEnergyPricesRequest:
      type: object
      properties:
        commodities:
          type: array
          items:
            type: string
            description: Optional commodity filter. Empty returns all tracked commodities.
      description: GetEnergyPricesRequest specifies which energy commodities to retrieve.
    GetEnergyPricesResponse:
      type: object
      properties:
        prices:
          type: array
          items:
            $ref: '#/components/schemas/EnergyPrice'
      description: GetEnergyPricesResponse contains energy price data.
    EnergyPrice:
      type: object
      properties:
        commodity:
          type: string
          minLength: 1
          description: Energy commodity identifier.
        name:
          type: string
          description: >-
            Human-readable name (e.g., "WTI Crude Oil", "Henry Hub Natural
            Gas").
        price:
          type: number
          format: double
          description: Current price in USD.
        unit:
          type: string
          description: Unit of measurement (e.g., "$/barrel", "$/MMBtu").
        change:
          type: number
          format: double
          description: Percentage change from previous period.
        priceAt:
          type: integer
          format: int64
          description: >-
            Price date, as Unix epoch milliseconds.. Warning: Values > 2^53 may
            lose precision in JavaScript
      required:
        - commodity
      description: EnergyPrice represents a current energy commodity price from EIA.
    GetMacroSignalsRequest:
      type: object
      description: GetMacroSignalsRequest requests the current macro signal dashboard.
    GetMacroSignalsResponse:
      type: object
      properties:
        timestamp:
          type: string
          description: ISO 8601 timestamp of computation.
        verdict:
          type: string
          description: 'Overall verdict: "BUY", "CASH", or "UNKNOWN".'
        bullishCount:
          type: integer
          format: int32
          description: Number of bullish signals.
        totalCount:
          type: integer
          format: int32
          description: Total number of evaluated signals (excluding UNKNOWN).
        signals:
          $ref: '#/components/schemas/MacroSignals'
        meta:
          $ref: '#/components/schemas/MacroMeta'
        unavailable:
          type: boolean
          description: |-
            True when upstream data is unavailable (fallback result).
             True when the upstream or seed-backed variant is unavailable; empty payload fields
             are graceful degradation, not confirmed zero data.
      description: >-
        GetMacroSignalsResponse contains the full macro signal dashboard with 7
        signals and verdict.
    MacroSignals:
      type: object
      properties:
        liquidity:
          $ref: '#/components/schemas/LiquiditySignal'
        flowStructure:
          $ref: '#/components/schemas/FlowStructureSignal'
        macroRegime:
          $ref: '#/components/schemas/MacroRegimeSignal'
        technicalTrend:
          $ref: '#/components/schemas/TechnicalTrendSignal'
        hashRate:
          $ref: '#/components/schemas/HashRateSignal'
        priceMomentum:
          $ref: '#/components/schemas/PriceMomentumSignal'
        fearGreed:
          $ref: '#/components/schemas/FearGreedSignal'
      description: MacroSignals contains all 7 individual signal computations.
    LiquiditySignal:
      type: object
      properties:
        status:
          type: string
          description: '"SQUEEZE", "NORMAL", or "UNKNOWN".'
        value:
          type: number
          format: double
          description: JPY 30d ROC percentage, absent if unavailable.
        sparkline:
          type: array
          items:
            type: number
            format: double
            description: Last 30 JPY close prices.
      description: LiquiditySignal tracks JPY 30d rate of change as a liquidity proxy.
    FlowStructureSignal:
      type: object
      properties:
        status:
          type: string
          description: '"PASSIVE GAP", "ALIGNED", or "UNKNOWN".'
        btcReturn5:
          type: number
          format: double
          description: BTC 5-day return percentage.
        qqqReturn5:
          type: number
          format: double
          description: QQQ 5-day return percentage.
      description: FlowStructureSignal compares BTC vs QQQ 5-day returns.
    MacroRegimeSignal:
      type: object
      properties:
        status:
          type: string
          description: '"RISK-ON", "DEFENSIVE", or "UNKNOWN".'
        qqqRoc20:
          type: number
          format: double
          description: QQQ 20d ROC percentage.
        xlpRoc20:
          type: number
          format: double
          description: XLP 20d ROC percentage.
      description: MacroRegimeSignal compares QQQ vs XLP 20-day rate of change.
    TechnicalTrendSignal:
      type: object
      properties:
        status:
          type: string
          description: '"BULLISH", "BEARISH", "NEUTRAL", or "UNKNOWN".'
        btcPrice:
          type: number
          format: double
          description: Current BTC price.
        sma50:
          type: number
          format: double
          description: 50-day simple moving average.
        sma200:
          type: number
          format: double
          description: 200-day simple moving average.
        vwap30d:
          type: number
          format: double
          description: 30-day volume-weighted average price.
        mayerMultiple:
          type: number
          format: double
          description: Mayer multiple (BTC price / SMA200).
        sparkline:
          type: array
          items:
            type: number
            format: double
            description: Last 30 BTC close prices.
      description: TechnicalTrendSignal evaluates BTC price vs moving averages and VWAP.
    HashRateSignal:
      type: object
      properties:
        status:
          type: string
          description: '"GROWING", "DECLINING", "STABLE", or "UNKNOWN".'
        change30d:
          type: number
          format: double
          description: Hash rate change over 30 days as percentage.
      description: HashRateSignal tracks Bitcoin hash rate momentum.
    PriceMomentumSignal:
      type: object
      properties:
        status:
          type: string
          description: '"STRONG", "MODERATE", "WEAK", or "UNKNOWN".'
      description: >-
        PriceMomentumSignal uses the Mayer Multiple (price/SMA200) as a
        market-adaptive signal.
    FearGreedSignal:
      type: object
      properties:
        status:
          type: string
          description: Classification label (e.g., "Extreme Fear", "Greed").
        value:
          type: integer
          format: int32
          description: Current index value (0-100).
        history:
          type: array
          items:
            $ref: '#/components/schemas/FearGreedHistoryEntry'
      description: FearGreedSignal tracks the Crypto Fear & Greed index.
    FearGreedHistoryEntry:
      type: object
      properties:
        value:
          type: integer
          maximum: 100
          minimum: 0
          format: int32
          description: Index value (0-100).
        date:
          type: string
          description: Date string (YYYY-MM-DD).
      description: FearGreedHistoryEntry is a single day's Fear & Greed index reading.
    MacroMeta:
      type: object
      properties:
        qqqSparkline:
          type: array
          items:
            type: number
            format: double
            description: Last 30 QQQ close prices for sparkline.
      description: MacroMeta contains supplementary chart data.
    GetChinaMacroSnapshotRequest:
      type: object
    GetChinaMacroSnapshotResponse:
      type: object
      properties:
        countryCode:
          type: string
        generatedAt:
          type: string
        status:
          type: string
        launchReady:
          type: boolean
        contentObservationDate:
          type: string
        latestObservationDate:
          type: string
        indicators:
          type: array
          items:
            $ref: '#/components/schemas/ChinaMacroIndicator'
        sourceDecisions:
          type: array
          items:
            $ref: '#/components/schemas/ChinaMacroSourceDecision'
        releaseEvents:
          type: array
          items:
            $ref: '#/components/schemas/ChinaReleaseEvent'
        unavailable:
          type: boolean
          description: >-
            True when the seeded snapshot or release calendar is unavailable;
            callers
             should render the response as degraded rather than treating it as current.
        schemaVersion:
          type: integer
          format: int32
        pillars:
          type: array
          items:
            $ref: '#/components/schemas/ChinaMacroPillarPulse'
    ChinaMacroIndicator:
      type: object
      properties:
        id:
          type: string
          description: |-
            Kept as "indicator" for API compatibility; each row is a versioned,
             revision-aware official observation in cache schema v2.
        label:
          type: string
        category:
          type: string
        value:
          type: number
          format: double
        hasValue:
          type: boolean
        priorValue:
          type: number
          format: double
        hasPriorValue:
          type: boolean
        unit:
          type: string
        observationDate:
          type: string
        source:
          type: string
        sourceUrl:
          type: string
        stale:
          type: boolean
        unavailableReason:
          type: string
        contextOnly:
          type: boolean
        geography:
          type: string
        seasonalAdjustment:
          type: string
        periodKind:
          type: string
        observationPeriod:
          type: string
        releaseTime:
          type: string
        retrievalTime:
          type: string
        direction:
          type: string
        directionReason:
          type: string
        comparisonBasis:
          type: string
        comparisonValue:
          type: number
          format: double
        hasComparisonValue:
          type: boolean
        revisionState:
          type: string
        vintageId:
          type: string
        revisionSequence:
          type: integer
          format: int32
        provenanceJson:
          type: string
          description: >-
            Canonical #5581 payload, validated before crossing the cache/API
            boundary.
        vintages:
          type: array
          items:
            $ref: '#/components/schemas/ChinaMacroVintage'
        transportStatus:
          type: string
        transportFailureReason:
          type: string
    ChinaMacroVintage:
      type: object
      properties:
        vintageId:
          type: string
        sequence:
          type: integer
          format: int32
        state:
          type: string
        value:
          type: number
          format: double
        hasValue:
          type: boolean
        observationPeriod:
          type: string
        periodKind:
          type: string
        releaseTime:
          type: string
        retrievalTime:
          type: string
        supersededBy:
          type: string
        provenanceJson:
          type: string
    ChinaMacroSourceDecision:
      type: object
      properties:
        source:
          type: string
        host:
          type: string
        status:
          type: string
        reason:
          type: string
        checkedAt:
          type: string
        optional:
          type: boolean
        requestCount:
          type: integer
          format: int32
        publisherId:
          type: string
        redirectBehavior:
          type: string
        requestBudget:
          type: integer
          format: int32
        robotsStatus:
          type: string
        termsStatus:
          type: string
        sourceUrl:
          type: string
    ChinaReleaseEvent:
      type: object
      properties:
        id:
          type: string
        event:
          type: string
        countryCode:
          type: string
        releaseDate:
          type: string
        releaseTime:
          type: string
        timezone:
          type: string
        kind:
          type: string
        status:
          type: string
        source:
          type: string
        sourceUrl:
          type: string
    ChinaMacroPillarPulse:
      type: object
      properties:
        pillar:
          type: string
        direction:
          type: string
        reason:
          type: string
        observationIds:
          type: array
          items:
            type: string
    GetChinaActivityNowcastRequest:
      type: object
    GetChinaActivityNowcastResponse:
      type: object
      properties:
        generatedAt:
          type: string
        methodVersion:
          type: string
        comparisonState:
          type: string
        upstreamUnavailable:
          type: boolean
          description: >-
            True only when no official vintage or proxy contribution is
            available.
             Methodological insufficiency with otherwise healthy inputs remains false.
        payloadJson:
          type: string
          description: |-
            Canonical inspectable method payload. Numeric computation and state
             assignment are deterministic and validated before crossing this boundary.
    GetEnergyCapacityRequest:
      type: object
      properties:
        energySources:
          type: array
          items:
            type: string
            description: |-
              Energy source codes to query (e.g., "SUN", "WND", "COL").
               Empty returns all tracked sources (SUN, WND, COL).
        years:
          type: integer
          format: int32
          description: |-
            Number of years of historical data. Default 20 if not set.
             Accepted but currently ignored; no-op until this handler supports the parameter.
    GetEnergyCapacityResponse:
      type: object
      properties:
        series:
          type: array
          items:
            $ref: '#/components/schemas/EnergyCapacitySeries'
    EnergyCapacitySeries:
      type: object
      properties:
        energySource:
          type: string
        name:
          type: string
        data:
          type: array
          items:
            $ref: '#/components/schemas/EnergyCapacityYear'
    EnergyCapacityYear:
      type: object
      properties:
        year:
          type: integer
          format: int32
        capacityMw:
          type: number
          format: double
    GetBisPolicyRatesRequest:
      type: object
      description: GetBisPolicyRatesRequest requests central bank policy rates.
    GetBisPolicyRatesResponse:
      type: object
      properties:
        rates:
          type: array
          items:
            $ref: '#/components/schemas/BisPolicyRate'
      description: GetBisPolicyRatesResponse contains BIS policy rate data.
    BisPolicyRate:
      type: object
      properties:
        countryCode:
          type: string
          description: ISO 2-letter country code (US, GB, JP, etc.)
        countryName:
          type: string
          description: Country or region name.
        rate:
          type: number
          format: double
          description: Current policy rate percentage.
        previousRate:
          type: number
          format: double
          description: Previous period rate percentage.
        date:
          type: string
          description: Date as YYYY-MM.
        centralBank:
          type: string
          description: Central bank name (e.g. "Federal Reserve").
      description: BisPolicyRate represents a central bank policy rate from BIS.
    GetBisExchangeRatesRequest:
      type: object
      description: GetBisExchangeRatesRequest requests effective exchange rates.
    GetBisExchangeRatesResponse:
      type: object
      properties:
        rates:
          type: array
          items:
            $ref: '#/components/schemas/BisExchangeRate'
      description: GetBisExchangeRatesResponse contains BIS effective exchange rate data.
    BisExchangeRate:
      type: object
      properties:
        countryCode:
          type: string
          description: ISO 2-letter country code.
        countryName:
          type: string
          description: Country or region name.
        realEer:
          type: number
          format: double
          description: Real effective exchange rate index.
        nominalEer:
          type: number
          format: double
          description: Nominal effective exchange rate index.
        realChange:
          type: number
          format: double
          description: Percentage change from previous period (real).
        date:
          type: string
          description: Date as YYYY-MM.
      description: BisExchangeRate represents effective exchange rate indices from BIS.
    GetBisCreditRequest:
      type: object
      description: GetBisCreditRequest requests credit-to-GDP ratio data.
    GetBisCreditResponse:
      type: object
      properties:
        entries:
          type: array
          items:
            $ref: '#/components/schemas/BisCreditToGdp'
      description: GetBisCreditResponse contains BIS credit-to-GDP data.
    BisCreditToGdp:
      type: object
      properties:
        countryCode:
          type: string
          description: ISO 2-letter country code.
        countryName:
          type: string
          description: Country or region name.
        creditGdpRatio:
          type: number
          format: double
          description: Total credit as percentage of GDP.
        previousRatio:
          type: number
          format: double
          description: Previous quarter ratio.
        date:
          type: string
          description: Date as YYYY-QN.
      description: BisCreditToGdp represents total credit as percentage of GDP from BIS.
    GetFredSeriesBatchRequest:
      type: object
      properties:
        seriesIds:
          type: array
          items:
            type: string
            maxItems: 10
            minItems: 1
            description: FRED series IDs (e.g., "WALCL", "FEDFUNDS"). Max 10.
          maxItems: 10
          minItems: 1
        limit:
          type: integer
          format: int32
          description: Maximum number of observations per series. Defaults to 120.
      description: >-
        GetFredSeriesBatchRequest looks up multiple FRED series in a single
        call.
    GetFredSeriesBatchResponse:
      type: object
      properties:
        results:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/FredSeries'
          description: Map of series_id -> FRED series for found series.
        fetched:
          type: integer
          format: int32
          description: Number of series successfully fetched.
        requested:
          type: integer
          format: int32
          description: Number of series requested.
      description: GetFredSeriesBatchResponse contains the requested FRED series data.
    ResultsEntry:
      type: object
      properties:
        key:
          type: string
        value:
          $ref: '#/components/schemas/FredSeries'
    ListGroceryBasketPricesRequest:
      type: object
    ListGroceryBasketPricesResponse:
      type: object
      properties:
        countries:
          type: array
          items:
            $ref: '#/components/schemas/CountryBasket'
        fetchedAt:
          type: string
        cheapestCountry:
          type: string
        mostExpensiveCountry:
          type: string
        upstreamUnavailable:
          type: boolean
        wowAvgPct:
          type: number
          format: double
        wowAvailable:
          type: boolean
        prevFetchedAt:
          type: string
    CountryBasket:
      type: object
      properties:
        code:
          type: string
        name:
          type: string
        currency:
          type: string
        flag:
          type: string
        totalUsd:
          type: number
          format: double
        fxRate:
          type: number
          format: double
        items:
          type: array
          items:
            $ref: '#/components/schemas/GroceryItemPrice'
        wowPct:
          type: number
          format: double
    GroceryItemPrice:
      type: object
      properties:
        itemId:
          type: string
        itemName:
          type: string
        unit:
          type: string
        localPrice:
          type: number
          format: double
        usdPrice:
          type: number
          format: double
        currency:
          type: string
        sourceSite:
          type: string
        available:
          type: boolean
    ListBigMacPricesRequest:
      type: object
    ListBigMacPricesResponse:
      type: object
      properties:
        countries:
          type: array
          items:
            $ref: '#/components/schemas/BigMacCountryPrice'
        fetchedAt:
          type: string
        cheapestCountry:
          type: string
        mostExpensiveCountry:
          type: string
        wowAvgPct:
          type: number
          format: double
        wowAvailable:
          type: boolean
        prevFetchedAt:
          type: string
    BigMacCountryPrice:
      type: object
      properties:
        code:
          type: string
        name:
          type: string
        currency:
          type: string
        flag:
          type: string
        localPrice:
          type: number
          format: double
        usdPrice:
          type: number
          format: double
        fxRate:
          type: number
          format: double
        sourceSite:
          type: string
        available:
          type: boolean
        wowPct:
          type: number
          format: double
    GetNationalDebtRequest:
      type: object
      description: GetNationalDebtRequest requests national debt data for all countries.
    GetNationalDebtResponse:
      type: object
      properties:
        entries:
          type: array
          items:
            $ref: '#/components/schemas/NationalDebtEntry'
        seededAt:
          type: string
          description: ISO 8601 timestamp when seed data was written.
        unavailable:
          type: boolean
          description: |-
            True when upstream data is unavailable (fallback result).
             True when the upstream or seed-backed variant is unavailable; empty payload fields
             are graceful degradation, not confirmed zero data.
      description: GetNationalDebtResponse wraps the full list of national debt entries.
    NationalDebtEntry:
      type: object
      properties:
        iso3:
          type: string
          description: ISO3 country code (e.g. "USA").
        debtUsd:
          type: number
          format: double
          description: Total debt in USD at baseline_ts.
        gdpUsd:
          type: number
          format: double
          description: GDP in USD (nominal, latest year).
        debtToGdp:
          type: number
          format: double
          description: Debt as % of GDP.
        annualGrowth:
          type: number
          format: double
          description: Year-over-year debt growth percent (2023->2024).
        perSecondRate:
          type: number
          format: double
          description: Deficit-derived accrual in USD per second.
        perDayRate:
          type: number
          format: double
          description: Deficit-derived accrual in USD per day.
        baselineTs:
          type: string
          format: int64
          description: >-
            UTC ms timestamp anchoring the debt_usd figure
            (2024-01-01T00:00:00Z).
        source:
          type: string
          description: Human-readable source string.
      description: NationalDebtEntry holds debt data for a single country.
    ListFuelPricesRequest:
      type: object
    ListFuelPricesResponse:
      type: object
      properties:
        countries:
          type: array
          items:
            $ref: '#/components/schemas/FuelCountryPrice'
        fetchedAt:
          type: string
        cheapestGasoline:
          type: string
        cheapestDiesel:
          type: string
        mostExpensiveGasoline:
          type: string
        mostExpensiveDiesel:
          type: string
        wowAvailable:
          type: boolean
        prevFetchedAt:
          type: string
        sourceCount:
          type: integer
          format: int32
        countryCount:
          type: integer
          format: int32
    FuelCountryPrice:
      type: object
      properties:
        code:
          type: string
        name:
          type: string
        currency:
          type: string
        flag:
          type: string
        gasoline:
          $ref: '#/components/schemas/FuelPrice'
        diesel:
          $ref: '#/components/schemas/FuelPrice'
        fxRate:
          type: number
          format: double
    FuelPrice:
      type: object
      properties:
        usdPrice:
          type: number
          format: double
        localPrice:
          type: number
          format: double
        grade:
          type: string
        source:
          type: string
        available:
          type: boolean
        wowPct:
          type: number
          format: double
        observedAt:
          type: string
    GetBlsSeriesRequest:
      type: object
      properties:
        seriesId:
          type: string
          description: 'BLS/FRED-backed series ID. Supported values: "USPRIV", "ECIALLCIV".'
        limit:
          type: integer
          format: int32
          description: Maximum number of observations to return. Defaults to 60.
      description: GetBlsSeriesRequest specifies which BLS series to retrieve.
    GetBlsSeriesResponse:
      type: object
      properties:
        series:
          $ref: '#/components/schemas/BlsSeries'
      description: GetBlsSeriesResponse contains the requested BLS series data.
    BlsSeries:
      type: object
      properties:
        seriesId:
          type: string
          description: BLS series ID (e.g. "CES0500000001").
        title:
          type: string
          description: Human-readable series title.
        units:
          type: string
          description: Unit of measure.
        observations:
          type: array
          items:
            $ref: '#/components/schemas/BlsObservation'
      description: BlsSeries is a BLS time series with metadata and observations.
    BlsObservation:
      type: object
      properties:
        year:
          type: string
          description: Year of the observation.
        period:
          type: string
          description: Period code (e.g. "M01" for January, "A01" for annual).
        periodName:
          type: string
          description: Human-readable period name.
        value:
          type: string
          description: Observed value.
      description: BlsObservation is a single BLS data point.
    GetEconomicCalendarRequest:
      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.
    GetEconomicCalendarResponse:
      type: object
      properties:
        events:
          type: array
          items:
            $ref: '#/components/schemas/EconomicEvent'
        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.
    EconomicEvent:
      type: object
      properties:
        event:
          type: string
        country:
          type: string
        date:
          type: string
        impact:
          type: string
        actual:
          type: string
        estimate:
          type: string
        previous:
          type: string
        unit:
          type: string
    GetCrudeInventoriesRequest:
      type: object
      description: >-
        GetCrudeInventoriesRequest is the request message for
        GetCrudeInventories.
    GetCrudeInventoriesResponse:
      type: object
      properties:
        weeks:
          type: array
          items:
            $ref: '#/components/schemas/CrudeInventoryWeek'
        latestPeriod:
          type: string
          description: Timestamp of the most recent EIA data point (ISO 8601).
      description: >-
        GetCrudeInventoriesResponse contains the 8 most recent weeks of US crude
        oil inventory data.
    CrudeInventoryWeek:
      type: object
      properties:
        period:
          type: string
          description: ISO week period (YYYY-MM-DD, Monday of the EIA report week).
        stocksMb:
          type: number
          format: double
          description: Total crude oil stocks in millions of barrels.
        weeklyChangeMb:
          type: number
          format: double
          description: >-
            Week-over-week change in millions of barrels. Positive = build
            (bearish), negative = draw (bullish).
             Absent for the oldest week when no prior week is available for comparison.
      description: >-
        CrudeInventoryWeek represents one week of US crude oil stockpile data
        from EIA WCRSTUS1.
    GetNatGasStorageRequest:
      type: object
      description: GetNatGasStorageRequest is the request message for GetNatGasStorage.
    GetNatGasStorageResponse:
      type: object
      properties:
        weeks:
          type: array
          items:
            $ref: '#/components/schemas/NatGasStorageWeek'
        latestPeriod:
          type: string
          description: Timestamp of the most recent EIA data point (ISO 8601).
      description: >-
        GetNatGasStorageResponse contains the 8 most recent weeks of US natural
        gas storage data.
    NatGasStorageWeek:
      type: object
      properties:
        period:
          type: string
          description: ISO week period (YYYY-MM-DD, Monday of the EIA report week).
        storBcf:
          type: number
          format: double
          description: Working gas in underground storage, Lower-48 States, in Bcf.
        weeklyChangeBcf:
          type: number
          format: double
          description: >-
            Week-over-week change in Bcf. Positive = build (bearish for gas
            prices), negative = draw (bullish).
             Absent for the oldest week when no prior week is available for comparison.
      description: >-
        NatGasStorageWeek represents one week of US natural gas working gas
        storage data from EIA.
    GetEcbFxRatesRequest:
      type: object
      description: GetEcbFxRatesRequest is empty; returns all tracked EUR pairs.
    GetEcbFxRatesResponse:
      type: object
      properties:
        rates:
          type: array
          items:
            $ref: '#/components/schemas/EcbFxRate'
        updatedAt:
          type: string
          description: ISO 8601 timestamp of the ECB publication.
        seededAt:
          type: string
          format: int64
          description: Unix ms when the data was last seeded.
        unavailable:
          type: boolean
          description: |-
            True when Redis key is missing or data is unavailable.
             True when the upstream or seed-backed variant is unavailable; empty payload fields
             are graceful degradation, not confirmed zero data.
      description: GetEcbFxRatesResponse contains the latest ECB reference rates.
    EcbFxRate:
      type: object
      properties:
        pair:
          type: string
          description: Currency pair label, e.g. "EURUSD".
        rate:
          type: number
          format: double
          description: Exchange rate (units of quote currency per 1 EUR).
        date:
          type: string
          description: Date of the observation in YYYY-MM-DD format.
        change1d:
          type: number
          format: double
          description: 1-day change in rate (absolute).
      description: EcbFxRate is a single ECB official reference rate for a currency pair.
    GetEurostatCountryDataRequest:
      type: object
      description: >-
        GetEurostatCountryDataRequest requests Eurostat per-country economic
        data.
    GetEurostatCountryDataResponse:
      type: object
      properties:
        countries:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/EurostatCountryEntry'
          description: >-
            Map of ISO2 country code to economic metrics (e.g. "DE", "FR",
            "IT").
        seededAt:
          type: string
          format: int64
          description: UTC ms timestamp when seed data was written.
        unavailable:
          type: boolean
          description: |-
            True when upstream data is unavailable (fallback result).
             True when the upstream or seed-backed variant is unavailable; empty payload fields
             are graceful degradation, not confirmed zero data.
      description: >-
        GetEurostatCountryDataResponse contains per-country CPI, unemployment,
        and GDP growth.
    CountriesEntry:
      type: object
      properties:
        key:
          type: string
        value:
          $ref: '#/components/schemas/EurostatCountryEntry'
    EurostatCountryEntry:
      type: object
      properties:
        cpi:
          $ref: '#/components/schemas/EurostatMetric'
        unemployment:
          $ref: '#/components/schemas/EurostatMetric'
        gdpGrowth:
          $ref: '#/components/schemas/EurostatMetric'
      description: EurostatCountryEntry holds all available metrics for one EU country.
    EurostatMetric:
      type: object
      properties:
        value:
          type: number
          format: double
          description: Numeric value (e.g. 2.3 for 2.3%).
        date:
          type: string
          description: Period string (e.g. "2024-01" for monthly, "2024-Q1" for quarterly).
        unit:
          type: string
          description: Unit of measurement (e.g. "%").
        priorValue:
          type: number
          format: double
          description: >-
            Prior period value for delta calculation (e.g. previous
            month/quarter).
        hasPrior:
          type: boolean
          description: >-
            True when prior_value is present (proto3 can't distinguish 0 from
            absent).
      description: EurostatMetric holds a single economic metric value for a country.
    GetEuGasStorageRequest:
      type: object
      description: GetEuGasStorageRequest is empty — returns latest EU aggregate snapshot.
    GetEuGasStorageResponse:
      type: object
      properties:
        fillPct:
          type: number
          format: double
          description: >-
            Current storage fill level as a percentage of working gas volume
            (0–100).
        fillPctChange1d:
          type: number
          format: double
          description: >-
            1-day change in fill percentage (positive = injecting, negative =
            withdrawing).
        gasDaysConsumption:
          type: number
          format: double
          description: >-
            Approximate days of consumption remaining at average EU winter
            drawdown rate.
        trend:
          type: string
          description: 'Current storage trend: "injecting", "withdrawing", or "stable".'
        history:
          type: array
          items:
            $ref: '#/components/schemas/EuGasStorageHistoryEntry'
        seededAt:
          type: string
          format: int64
          description: UTC ms timestamp when seed data was written.
        updatedAt:
          type: string
          description: Calendar date of the most recent data point (YYYY-MM-DD).
        unavailable:
          type: boolean
          description: |-
            True when upstream data is unavailable (fallback result).
             True when the upstream or seed-backed variant is unavailable; empty payload fields
             are graceful degradation, not confirmed zero data.
      description: GetEuGasStorageResponse contains the EU aggregate gas storage snapshot.
    EuGasStorageHistoryEntry:
      type: object
      properties:
        date:
          type: string
          description: Calendar date (YYYY-MM-DD).
        fillPct:
          type: number
          format: double
          description: Storage fill level as a percentage of working gas volume capacity.
        gasTwh:
          type: number
          format: double
          description: Working gas volume in storage (TWh).
      description: >-
        EuGasStorageHistoryEntry represents one day of EU aggregate gas storage
        data.
    GetEuYieldCurveRequest:
      type: object
      description: >-
        GetEuYieldCurveRequest fetches the ECB Euro Area AAA sovereign yield
        curve.
    GetEuYieldCurveResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/EuYieldCurveData'
        unavailable:
          type: boolean
          description: |-
            True if data is not yet available in cache.
             True when the upstream or seed-backed variant is unavailable; empty payload fields
             are graceful degradation, not confirmed zero data.
      description: >-
        GetEuYieldCurveResponse contains the latest ECB Euro Area AAA sovereign
        yield curve.
    EuYieldCurveData:
      type: object
      properties:
        date:
          type: string
          description: Date of the observation (YYYY-MM or YYYY-MM-DD).
        rates:
          type: object
          additionalProperties:
            type: number
            format: double
          description: 'Spot rates by tenor. Keys: "1Y", "2Y", "5Y", "10Y", "20Y", "30Y".'
        source:
          type: string
          description: Data source identifier (e.g. "ecb-aaa").
        updatedAt:
          type: string
          description: ISO 8601 timestamp when this was last seeded.
      description: >-
        EuYieldCurveData holds a single observation of the ECB Euro Area AAA
        yield curve.
    RatesEntry:
      type: object
      properties:
        key:
          type: string
        value:
          type: number
          format: double
    GetEuFsiRequest:
      type: object
    GetEuFsiResponse:
      type: object
      properties:
        latestValue:
          type: number
          format: double
        latestDate:
          type: string
        label:
          type: string
        history:
          type: array
          items:
            $ref: '#/components/schemas/EuFsiObservation'
        seededAt:
          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.
        stale:
          type: boolean
          description: >-
            True when latest_date is older than the CISS content-age budget --
            the ECB
             series has stopped publishing (issue #3845). Consumers must not present a
             stale reading as current. Seeder-side detection is content-age
             (STALE_CONTENT in /api/health); this flag is the per-request equivalent.
    EuFsiObservation:
      type: object
      properties:
        date:
          type: string
        value:
          type: number
          format: double
    GetEconomicStressRequest:
      type: object
    GetEconomicStressResponse:
      type: object
      properties:
        compositeScore:
          type: number
          format: double
        label:
          type: string
        components:
          type: array
          items:
            $ref: '#/components/schemas/EconomicStressComponent'
        seededAt:
          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.
    EconomicStressComponent:
      type: object
      properties:
        id:
          type: string
        label:
          type: string
        rawValue:
          type: number
          format: double
        score:
          type: number
          format: double
        weight:
          type: number
          format: double
        missing:
          type: boolean
    GetFaoFoodPriceIndexRequest:
      type: object
    GetFaoFoodPriceIndexResponse:
      type: object
      properties:
        points:
          type: array
          items:
            $ref: '#/components/schemas/FaoFoodPricePoint'
        fetchedAt:
          type: string
        currentFfpi:
          type: number
          format: double
        momPct:
          type: number
          format: double
        yoyPct:
          type: number
          format: double
    FaoFoodPricePoint:
      type: object
      properties:
        date:
          type: string
        ffpi:
          type: number
          format: double
        meat:
          type: number
          format: double
        dairy:
          type: number
          format: double
        cereals:
          type: number
          format: double
        oils:
          type: number
          format: double
        sugar:
          type: number
          format: double
    GetOilStocksAnalysisRequest:
      type: object
      description: >-
        GetOilStocksAnalysisRequest is empty — returns the latest global
        analysis snapshot.
    GetOilStocksAnalysisResponse:
      type: object
      properties:
        updatedAt:
          type: string
          description: UTC ISO-8601 timestamp when this analysis was written.
        dataMonth:
          type: string
          description: 'Data month in YYYY-MM format (source: IEA monthly release).'
        ieaMembers:
          type: array
          items:
            $ref: '#/components/schemas/OilStocksAnalysisMember'
        belowObligation:
          type: array
          items:
            type: string
            description: ISO2 codes of countries currently below the 90-day obligation.
        regionalSummary:
          $ref: '#/components/schemas/OilStocksRegionalSummary'
        unavailable:
          type: boolean
          description: |-
            True when upstream seed data is unavailable (fallback result).
             True when the upstream or seed-backed variant is unavailable; empty payload fields
             are graceful degradation, not confirmed zero data.
      description: >-
        GetOilStocksAnalysisResponse contains the IEA oil stocks days-of-cover
        analysis.
    OilStocksAnalysisMember:
      type: object
      properties:
        iso2:
          type: string
          description: ISO 3166-1 alpha-2 country code.
        daysOfCover:
          type: integer
          format: int32
          description: >-
            Days of supply cover (absent when country is a net exporter or data
            anomaly).
        netExporter:
          type: boolean
          description: True when the country is classified as a net exporter by IEA.
        belowObligation:
          type: boolean
          description: True when days_of_cover < 90 (IEA 90-day obligation threshold).
        obligationMet:
          type: boolean
          description: True when the 90-day obligation is met (net exporters always true).
        rank:
          type: integer
          format: int32
          description: >-
            Rank within the IEA member ranking (1-indexed, net exporters ranked
            last).
        vsObligation:
          type: integer
          format: int32
          description: days_of_cover - 90; absent for net exporters.
      description: >-
        OilStocksAnalysisMember holds days-of-cover data and obligation status
        for one IEA member country.
    OilStocksRegionalSummary:
      type: object
      properties:
        europe:
          $ref: '#/components/schemas/OilStocksRegionalSummaryEurope'
        asiaPacific:
          $ref: '#/components/schemas/OilStocksRegionalSummaryAsiaPacific'
        northAmerica:
          $ref: '#/components/schemas/OilStocksRegionalSummaryNorthAmerica'
      description: >-
        OilStocksRegionalSummary holds regional aggregates for the three IEA
        regions.
    OilStocksRegionalSummaryEurope:
      type: object
      properties:
        avgDays:
          type: integer
          format: int32
          description: Mean days of cover across non-net-exporter European members.
        minDays:
          type: integer
          format: int32
          description: Minimum days of cover across non-net-exporter European members.
        countBelowObligation:
          type: integer
          format: int32
          description: Count of European members below the 90-day obligation.
      description: >-
        OilStocksRegionalSummaryEurope aggregates days-of-cover for European IEA
        members.
    OilStocksRegionalSummaryAsiaPacific:
      type: object
      properties:
        avgDays:
          type: integer
          format: int32
          description: Mean days of cover across Asia-Pacific members (AU, JP, KR, NZ).
        minDays:
          type: integer
          format: int32
          description: Minimum days of cover across Asia-Pacific members.
        countBelowObligation:
          type: integer
          format: int32
          description: Count of Asia-Pacific members below the 90-day obligation.
      description: >-
        OilStocksRegionalSummaryAsiaPacific aggregates days-of-cover for
        Asia-Pacific IEA members.
    OilStocksRegionalSummaryNorthAmerica:
      type: object
      properties:
        netExporters:
          type: integer
          format: int32
          description: Count of net exporters in North America (CA, MX, US).
        avgDays:
          type: integer
          format: int32
          description: >-
            Average days of cover for non-exporter North American members (if
            any).
      description: >-
        OilStocksRegionalSummaryNorthAmerica aggregates data for North American
        IEA members.
    GetOilInventoriesRequest:
      type: object
    GetOilInventoriesResponse:
      type: object
      properties:
        crudeWeeks:
          type: array
          items:
            $ref: '#/components/schemas/CrudeInventoryWeekRef'
        spr:
          $ref: '#/components/schemas/OilInventoriesSprSnapshot'
        natGasWeeks:
          type: array
          items:
            $ref: '#/components/schemas/NatGasWeekRef'
        euGas:
          $ref: '#/components/schemas/OilInventoriesEuGas'
        ieaStocks:
          $ref: '#/components/schemas/OilInventoriesIeaStocks'
        refinery:
          $ref: '#/components/schemas/OilInventoriesRefinery'
        updatedAt:
          type: string
    CrudeInventoryWeekRef:
      type: object
      properties:
        period:
          type: string
        stocksMb:
          type: number
          format: double
        weeklyChangeMb:
          type: number
          format: double
    OilInventoriesSprSnapshot:
      type: object
      properties:
        latestStocksMb:
          type: number
          format: double
        changeWow:
          type: number
          format: double
        weeks:
          type: array
          items:
            $ref: '#/components/schemas/OilInventoriesSprWeek'
    OilInventoriesSprWeek:
      type: object
      properties:
        period:
          type: string
        stocksMb:
          type: number
          format: double
    NatGasWeekRef:
      type: object
      properties:
        period:
          type: string
        storBcf:
          type: number
          format: double
        weeklyChangeBcf:
          type: number
          format: double
    OilInventoriesEuGas:
      type: object
      properties:
        fillPct:
          type: number
          format: double
        fillPctChange1d:
          type: number
          format: double
        trend:
          type: string
        history:
          type: array
          items:
            $ref: '#/components/schemas/OilInventoriesEuGasDay'
    OilInventoriesEuGasDay:
      type: object
      properties:
        date:
          type: string
        fillPct:
          type: number
          format: double
    OilInventoriesIeaStocks:
      type: object
      properties:
        dataMonth:
          type: string
        members:
          type: array
          items:
            $ref: '#/components/schemas/OilInventoriesIeaMember'
        europe:
          $ref: '#/components/schemas/OilInventoriesRegionStats'
        asiaPacific:
          $ref: '#/components/schemas/OilInventoriesRegionStats'
        northAmerica:
          $ref: '#/components/schemas/OilInventoriesRegionStats'
    OilInventoriesIeaMember:
      type: object
      properties:
        iso2:
          type: string
        daysOfCover:
          type: number
          format: double
        netExporter:
          type: boolean
        belowObligation:
          type: boolean
    OilInventoriesRegionStats:
      type: object
      properties:
        avgDays:
          type: number
          format: double
        minDays:
          type: number
          format: double
        countBelowObligation:
          type: integer
          format: int32
    OilInventoriesRefinery:
      type: object
      properties:
        inputsMbpd:
          type: number
          format: double
        period:
          type: string
    GetEnergyCrisisPoliciesRequest:
      type: object
      properties:
        countryCode:
          type: string
          description: Optional ISO-2 country code filter.
        category:
          type: string
          description: 'Optional category filter: "conservation" or "consumer_support".'
      description: >-
        GetEnergyCrisisPoliciesRequest allows optional filtering by country or
        category.
    GetEnergyCrisisPoliciesResponse:
      type: object
      properties:
        source:
          type: string
          description: Source attribution.
        sourceUrl:
          type: string
          description: Source URL.
        context:
          type: string
          description: Context description.
        policies:
          type: array
          items:
            $ref: '#/components/schemas/EnergyCrisisPolicy'
        updatedAt:
          type: string
          description: UTC ISO-8601 timestamp when this data was last updated.
        unavailable:
          type: boolean
          description: |-
            True when upstream seed data is unavailable (fallback result).
             True when the upstream or seed-backed variant is unavailable; empty payload fields
             are graceful degradation, not confirmed zero data.
      description: >-
        GetEnergyCrisisPoliciesResponse contains energy crisis policy data from
        the IEA tracker.
    EnergyCrisisPolicy:
      type: object
      properties:
        country:
          type: string
          description: Country name.
        countryCode:
          type: string
          description: ISO 3166-1 alpha-2 country code.
        category:
          type: string
          description: 'Policy category: "conservation" or "consumer_support".'
        sector:
          type: string
          description: >-
            Affected sector: transport, buildings, industry, electricity,
            agriculture, general.
        measure:
          type: string
          description: Description of the policy measure.
        dateAnnounced:
          type: string
          description: Date announced in ISO-8601 (YYYY-MM-DD) format.
        status:
          type: string
          description: 'Status of the policy: active, planned, or ended.'
      description: >-
        EnergyCrisisPolicy represents a single government policy response to the
        2026 energy crisis.
    ListGlobalTendersRequest:
      type: object
      properties:
        country:
          type: string
          description: ISO 3166-1 alpha-2 country code to match.
        countries:
          type: array
          items:
            type: string
            description: One or more ISO 3166-1 alpha-2 country codes to match.
        region:
          type: string
          description: Geographic region label to match, such as Europe or North America.
        source:
          type: string
          description: >-
            Source adapter identifier: sam, ted, contracts-finder, canada-buys,
            gets, or world-bank.
        status:
          type: string
          description: Source-provided tender status to match, such as open or published.
        deadlineFrom:
          type: string
          description: >-
            Include opportunities whose deadline is on or after this ISO-8601
            timestamp.
        deadlineTo:
          type: string
          description: >-
            Include opportunities whose deadline is on or before this ISO-8601
            timestamp.
        minValue:
          type: number
          format: double
          description: >-
            Include opportunities with a stated estimated value at or above this
            amount.
        maxValue:
          type: number
          format: double
          description: >-
            Include opportunities with a stated estimated value at or below this
            amount.
        currency:
          type: string
          description: ISO 4217 currency code used with min_value and max_value.
        category:
          type: string
          description: Procurement category or classification code to match.
        query:
          type: string
          description: >-
            Case-insensitive search text matched against tender titles and
            descriptions.
        pageSize:
          type: integer
          format: int32
          description: Maximum number of tenders to return per page; capped at 100.
        cursor:
          type: string
          description: Opaque cursor from a previous response's next_cursor field.
        sort:
          type: string
          description: >-
            Result ordering: newest, closing_soon, estimated_value, or
            relevance.
        buyer:
          type: string
          description: Case-insensitive buyer or contracting-authority text to match.
        publishedFrom:
          type: string
          description: Include opportunities published on or after this ISO-8601 timestamp.
        publishedTo:
          type: string
          description: >-
            Include opportunities published on or before this ISO-8601
            timestamp.
        minAutomationScore:
          type: integer
          format: int32
          description: >-
            Include only opportunities whose keyword-based automation_fit score
            is at
             or above this integer value (1-100; values above 100 are clamped, and
             non-integer or non-positive values disable the filter). Disabled when 0
             or unset, which preserves the default all-open-opportunities behavior.
             This is an evidence-backed text-relevance threshold only; it does not
             assert that any party is eligible to bid.
    ListGlobalTendersResponse:
      type: object
      properties:
        tenders:
          type: array
          items:
            $ref: '#/components/schemas/GlobalTender'
        nextCursor:
          type: string
        fetchedAt:
          type: string
        dataAvailable:
          type: boolean
        availability:
          type: string
        sourceStatuses:
          type: array
          items:
            $ref: '#/components/schemas/TenderSourceStatus'
        total:
          type: integer
          format: int32
        appliedFilters:
          type: array
          items:
            type: string
        countryCoverage:
          type: string
          description: >-
            `unknown` means the snapshot contains no record for a requested
            country;
             it must not be interpreted as a confirmed no-opportunity or unsupported-country result.
    GlobalTender:
      type: object
      properties:
        id:
          type: string
        source:
          type: string
        sourceNoticeId:
          type: string
        officialUrl:
          type: string
        countryCode:
          type: string
        region:
          type: string
        title:
          type: string
        description:
          type: string
        buyer:
          type: string
        publishedAt:
          type: string
        updatedAt:
          type: string
        deadline:
          type: string
        status:
          type: string
        noticeType:
          type: string
        money:
          $ref: '#/components/schemas/TenderMoney'
        categoryCodes:
          type: array
          items:
            type: string
        sectors:
          type: array
          items:
            type: string
        eligibilityRequirements:
          type: array
          items:
            type: string
        submissionUrls:
          type: array
          items:
            type: string
        participationMode:
          type: string
        automationFit:
          $ref: '#/components/schemas/AutomationFit'
    TenderMoney:
      type: object
      properties:
        amount:
          type: number
          format: double
        currency:
          type: string
    AutomationFit:
      type: object
      properties:
        level:
          type: string
        score:
          type: integer
          format: int32
        classificationVersion:
          type: string
        matchReasons:
          type: array
          items:
            type: string
        evidence:
          type: array
          items:
            type: string
    TenderSourceStatus:
      type: object
      properties:
        source:
          type: string
        state:
          type: string
        recordCount:
          type: integer
          format: int32
        fetchedAt:
          type: string
          description: Time of the most recent retrieval attempt for this source.
        error:
          type: string
        lastSuccessfulAt:
          type: string
          description: >-
            Time of the most recent successful retrieval; preserved across
            failures.
        stale:
          type: boolean
        paced:
          type: boolean
