openapi: 3.1.0
info:
  title: Windy Network Multi-Asset Market Data API
  version: 1.0.0
  description: >
    Comprehensive market data API supporting cryptocurrency, stock, forex, and options data with real-time streaming
    capabilities.


    ## Authentication


    This API uses OAuth 2.0 for authentication. Supported grant types:

    - **Client Credentials**: For server-to-server communication

    - **Authorization Code**: For web applications

    - **Refresh Token**: To obtain new access tokens

    - **Password Grant**: Legacy support (discouraged)


    Alternatively, you can use API Keys for simpler authentication.


    ## Rate Limiting


    Rate limits are applied per OAuth client or API key:

    - **Free Tier**: 100 requests/minute

    - **Basic Tier**: 1,000 requests/minute

    - **Pro Tier**: 10,000 requests/minute


    ## Scopes


    OAuth 2.0 scopes control access to resources:

    - `crypto:read`, `stock:read`, `forex:read`, `option:read`, `dex:read` - Read market data

    - `crypto:write`, `stock:write` - Manage alerts and watchlists

    - `rate:read`, `ticker:read`, `ohlc:read`, `indicators:read` - Access specific data types

    - `stream:read` - Access WebSocket streams

    - `watchlist:read`, `watchlist:write` - Manage watchlists

    - `alerts:read`, `alerts:write` - Manage price alerts

    - `portfolio:read`, `portfolio:write` - Manage portfolio
  contact:
    name: Windy Network API Support
    email: support@windy.network
    url: https://windy.network/support
  license:
    name: Proprietary
    url: https://windy.network/legal/terms-of-service
servers:
  - url: https://api.windy.network
    description: CoreAPI - Production (authenticated)
  - url: https://ws.windy.network
    description: CoreAPI - WebSocket/SSE (authenticated)
  - url: https://openserver.windy.network
    description: OpenServer - Public (no authentication)
  - url: https://staging-api.windy.network
    description: Staging server
  - url: http://localhost
    description: Local development server
tags:
  - name: OAuth 2.0
    description: OAuth 2.0 authentication and authorization endpoints
  - name: API Keys
    description: API key management for simple authentication
  - name: Crypto Aggregated Rates
    description: Cryptocurrency rate endpoints (stablecoin, basecoin, altcoin)
    x-displayName: Aggregated Rates
  - name: Crypto Analytics
    description: Analytics
    x-displayName: Analytics
  - name: Fiat247 Rates
    description: 24/7 FIAT/USD derived rates from crypto markets
    x-displayName: Rates
  - name: Crypto OHLC
    description: Cryptocurrency OHLC/candlestick data
    x-displayName: OHLC
  - name: Crypto Indicators
    description: Technical indicators for cryptocurrency pairs (SMA, EMA, RSI, MACD, Bollinger Bands)
    x-displayName: Indicators
  - name: Fiat247 Indicators
    description: Technical indicators for fiat currency pairs (SMA, EMA, RSI, MACD, Bollinger Bands)
    x-displayName: Indicators
  - name: Crypto Order Books
    description: Order book and market depth data
    x-displayName: Order Books
  - name: Crypto Assets
    description: Cryptocurrency asset discovery and metadata
    x-displayName: Assets
  - name: Crypto Exchanges
    description: Exchange information, real-time tickers, and trade data
    x-displayName: Exchanges
  - name: Crypto RefRate
    description: Reference rates (fix, tcut, twap) — institutional-grade crypto benchmarks
    x-displayName: Reference Rates
  - name: Crypto Market
    description: Cryptocurrency market statistics and summaries
    x-displayName: Market
  - name: Crypto Streaming
    description: Real-time WebSocket and SSE streams for crypto
    x-displayName: Streaming
  - name: Stock Rates
    description: Stock price endpoints
    x-displayName: Rates
  - name: Stock Tickers
    description: Stock ticker data from exchanges
    x-displayName: Tickers
  - name: Stock OHLC
    description: Stock OHLC/candlestick data
    x-displayName: OHLC
  - name: Stock Indicators
    description: Technical indicators for stocks
    x-displayName: Indicators
  - name: Stock Trades
    description: Stock trade data
    x-displayName: Trades
  - name: Stock Assets
    description: Stock discovery and metadata
    x-displayName: Assets
  - name: Stock Market
    description: Stock market statistics and summaries
    x-displayName: Market
  - name: Stock Streaming
    description: Real-time WebSocket streams for stocks
    x-displayName: Streaming
  - name: Forex Rates
    description: Foreign exchange rates
    x-displayName: Rates
  - name: Forex OHLC
    description: Forex OHLC/candlestick data
    x-displayName: OHLC
  - name: Forex Indicators
    description: Technical indicators for forex pairs
    x-displayName: Indicators
  - name: Forex Assets
    description: Forex pair discovery and metadata
    x-displayName: Assets
  - name: Forex Streaming
    description: Real-time WebSocket streams for forex
    x-displayName: Streaming
  - name: Option Rates
    description: Options contract pricing
    x-displayName: Rates
  - name: Option Assets
    description: Options contract discovery
    x-displayName: Assets
  - name: User Alerts
    description: Price alert management
    x-displayName: Alerts
  - name: User Watchlist
    description: Watchlist management
    x-displayName: Watchlist
  - name: User Portfolio
    description: Portfolio tracking and management
    x-displayName: Portfolio
  - name: System
    description: >
      Health check and status endpoints for monitoring API availability. Use these to verify connectivity and check
      service status in your monitoring infrastructure.
  - name: OpenServer
    description: Public unauthenticated endpoints (openserver.windy.network)
  - name: Market Calendar
    description: Market hours, forex sessions, stock exchange schedules, and bank holidays with DST support
    x-displayName: Market Calendar
  - name: Crypto Depth
    x-displayName: Depth
    description: Cross-exchange aggregated order book depth
  - name: Crypto Liquidity
    x-displayName: Liquidity
    description: Real-time liquidity analytics across exchanges
  - name: DEX Midrate
    x-displayName: Midrate
  - name: Fiat247 OHLC
    x-displayName: OHLC
  - name: Fiat247 Rates
    x-displayName: Rates
  - name: Cryptocurrency
    description: >
      Real-time and historical cryptocurrency market data aggregated from **25+ exchanges** worldwide.


      Access spot rates, ticker snapshots, OHLC candlestick data, order books, trade streams, and technical indicators
      for thousands of crypto pairs. Data is available as cross-exchange composites or with exchange-level granularity.


      **Capabilities:** Live mid-rates & bid/ask spreads, volume-weighted averages, candlestick data (1m to 1M
      intervals), technical indicators (SMA, EMA, RSI, MACD, Bollinger Bands), real-time streaming via WebSocket and
      SSE.
  - name: DEX
    description: >
      **Decentralized Exchange (DEX) market data** — real-time aggregate midrates from on-chain liquidity pools.


      Access weighted median prices calculated across multiple DEX pools (Uniswap, PancakeSwap, Raydium, etc.) with
      adaptive EMA smoothing. Prices are updated every ~1 second via WebSocket or SSE streaming.


      **Capabilities:** Real-time aggregate midrates, WebSocket and SSE streaming, weighted median pricing across DEX
      pools.
  - name: Stocks
    description: >
      Equity market data covering major global exchanges.


      Access real-time prices, historical OHLC data, technical indicators, and trade-level information for stocks and
      ETFs. Includes asset discovery and metadata such as sector, market cap, and exchange information.


      **Capabilities:** Real-time and delayed quotes, OHLC candlestick data across multiple timeframes, server-side
      technical indicators, asset discovery, real-time streaming via WebSocket.
  - name: Forex
    description: >
      Traditional foreign exchange market data for major, minor, and exotic currency pairs. Rates are sourced during
      market hours (Sunday 17:00 ET through Friday 17:00 ET).


      **Capabilities:** Live spot mid-rates, bid/ask & spreads, OHLC candlestick data, technical indicators, currency
      pair discovery, real-time streaming via WebSocket.


      > For **24/7 fiat currency rates** that continue through weekends and holidays, see the Fiat247 section below.
  - name: Fiat247
    description: >
      **24/7 derived fiat currency rates** — even when traditional forex markets are closed.


      Fiat247 uses real-time cryptocurrency trading activity across 25+ exchanges to derive reliable fiat cross-rates
      like GBP/USD, EUR/USD, and AUD/USD around the clock. Crypto assets (BTC, ETH, USDT, USDC) are actively traded
      against fiat currencies 24/7 — by observing these prices simultaneously, we derive implied fiat cross-rates using
      multi-source, quality-weighted aggregation.


      **Capabilities:** Continuous rates for 18+ fiat currencies including weekends and holidays, gap-free OHLC
      candlestick data, technical indicators, cross-validated against traditional forex during market hours.


      **Available currencies:** AED, ARS, AUD, BRL, CAD, CHF, COP, EUR, GBP, IDR, JPY, MXN, NGN, PLN, SGD, TRY, UAH, ZAR
  - name: Options
    description: >
      Options contract pricing and discovery for crypto derivatives.


      Access real-time pricing data (bid, ask, mark, implied volatility) and browse available contracts across supported
      options exchanges. Filter by underlying asset, expiry date, and strike price.
  - name: User Features
    description: >
      Personalization and workflow tools for building applications on top of Windy Network data.


      Set price alerts, manage watchlists, and track portfolio performance — all via API. These endpoints require
      user-scoped authentication (OAuth 2.0 with appropriate scopes).
security:
  - BearerAuth: []
  - ApiKeyAuth: []
paths:
  /oauth/token:
    post:
      tags:
        - OAuth 2.0
      summary: OAuth 2.0 Token Endpoint
      description: |
        Obtain access tokens using various OAuth 2.0 grant types.

        **Supported Grant Types:**
        - `client_credentials` - Machine-to-machine authentication
        - `authorization_code` - Exchange authorization code for tokens
        - `refresh_token` - Refresh an expired access token
        - `password` - Username/password authentication (legacy, discouraged)
      operationId: postOauthToken
      security: []
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              oneOf:
                - $ref: "#/components/schemas/ClientCredentialsGrant"
                - $ref: "#/components/schemas/AuthorizationCodeGrant"
                - $ref: "#/components/schemas/RefreshTokenGrant"
                - $ref: "#/components/schemas/PasswordGrant"
            examples:
              clientCredentials:
                summary: Client Credentials Grant
                value:
                  grant_type: client_credentials
                  client_id: your_client_id
                  client_secret: your_client_secret
                  scope: crypto:read stock:read
              authorizationCode:
                summary: Authorization Code Grant
                value:
                  grant_type: authorization_code
                  code: authorization_code_here
                  redirect_uri: https://yourapp.com/callback
                  client_id: your_client_id
                  client_secret: your_client_secret
              refreshToken:
                summary: Refresh Token Grant
                value:
                  grant_type: refresh_token
                  refresh_token: your_refresh_token
                  client_id: your_client_id
                  client_secret: your_client_secret
      responses:
        "200":
          description: Access token successfully issued
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TokenResponse"
        "400":
          description: Invalid request parameters
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OAuth2Error"
        "401":
          description: Invalid client credentials
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OAuth2Error"
  /oauth/authorize:
    get:
      tags:
        - OAuth 2.0
      summary: OAuth 2.0 Authorization Endpoint
      description: |
        Initiates the OAuth 2.0 authorization code flow. User will be redirected to login page.
      operationId: getOauthAuthorize
      security: []
      parameters:
        - name: response_type
          in: query
          required: true
          schema:
            type: string
            enum:
              - code
        - name: client_id
          in: query
          required: true
          schema:
            type: string
        - name: redirect_uri
          in: query
          required: true
          schema:
            type: string
            format: uri
        - name: scope
          in: query
          schema:
            type: string
            example: crypto:read stock:read
        - name: state
          in: query
          required: true
          schema:
            type: string
          description: Random string to prevent CSRF attacks
      responses:
        "302":
          description: Redirect to login page or callback URL with authorization code
        "400":
          description: Invalid request parameters
  /oauth/revoke:
    post:
      tags:
        - OAuth 2.0
      summary: Revoke OAuth 2.0 Token
      description: Revoke an access token or refresh token (RFC 7009)
      operationId: postOauthRevoke
      security: []
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              required:
                - token
                - client_id
                - client_secret
              properties:
                token:
                  type: string
                  description: The token to revoke
                token_type_hint:
                  type: string
                  enum:
                    - access_token
                    - refresh_token
                  description: Hint about the type of token
                client_id:
                  type: string
                client_secret:
                  type: string
      responses:
        "200":
          description: Token successfully revoked
        "400":
          description: Invalid request
  /oauth/introspect:
    post:
      tags:
        - OAuth 2.0
      summary: Token Introspection
      description: Check if a token is valid and get token metadata (RFC 7662)
      operationId: postOauthIntrospect
      security: []
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              required:
                - token
                - client_id
                - client_secret
              properties:
                token:
                  type: string
                client_id:
                  type: string
                client_secret:
                  type: string
      responses:
        "200":
          description: Token introspection result
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TokenIntrospection"
  /oauth/userinfo:
    get:
      tags:
        - OAuth 2.0
      summary: Get User Information
      description: Returns user information for the authenticated user (OpenID Connect)
      operationId: getOauthUserinfo
      security:
        - BearerAuth:
            - profile:read
      responses:
        "200":
          description: User information
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/UserInfo"
        "401":
          $ref: "#/components/responses/Unauthorized"
  /.well-known/oauth-authorization-server:
    get:
      tags:
        - OAuth 2.0
      summary: OAuth 2.0 Authorization Server Metadata
      description: Returns OAuth 2.0 server metadata (RFC 8414)
      operationId: getWellKnownOauthAuthorizationServer
      security: []
      responses:
        "200":
          description: OAuth 2.0 server metadata
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OAuth2Metadata"
  /.well-known/openid-configuration:
    get:
      tags:
        - OAuth 2.0
      summary: OpenID Connect Discovery
      description: Returns OpenID Connect configuration
      operationId: getWellKnownOpenidConfiguration
      security: []
      responses:
        "200":
          description: OpenID Connect configuration
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OpenIDConfiguration"
  /.well-known/jwks.json:
    get:
      tags:
        - OAuth 2.0
      summary: JSON Web Key Set
      description: Returns public keys for verifying JWT signatures
      operationId: getWellKnownJwks
      security: []
      responses:
        "200":
          description: JSON Web Key Set
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/JWKS"
  /oauth/clients:
    post:
      tags:
        - OAuth 2.0
      summary: Register OAuth Client
      description: Dynamically register a new OAuth 2.0 client (RFC 7591)
      operationId: postOauthClients
      security:
        - BearerAuth:
            - admin:write
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ClientRegistration"
      responses:
        "201":
          description: Client successfully registered
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ClientInformation"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
  /oauth/clients/{clientId}:
    get:
      tags:
        - OAuth 2.0
      summary: Get OAuth Client Details
      description: Retrieve OAuth client configuration
      operationId: getOauthClientsByClientId
      security:
        - BearerAuth:
            - admin:read
      parameters:
        - $ref: "#/components/parameters/ClientIdParam"
      responses:
        "200":
          description: Client information
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ClientInformation"
        "404":
          $ref: "#/components/responses/NotFound"
    put:
      tags:
        - OAuth 2.0
      summary: Update OAuth Client
      description: Update OAuth client configuration
      operationId: putOauthClientsByClientId
      security:
        - BearerAuth:
            - admin:write
      parameters:
        - $ref: "#/components/parameters/ClientIdParam"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ClientRegistration"
      responses:
        "200":
          description: Client successfully updated
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ClientInformation"
        "404":
          $ref: "#/components/responses/NotFound"
    delete:
      tags:
        - OAuth 2.0
      summary: Delete OAuth Client
      description: Remove an OAuth client
      operationId: deleteOauthClientsByClientId
      security:
        - BearerAuth:
            - admin:write
      parameters:
        - $ref: "#/components/parameters/ClientIdParam"
      responses:
        "204":
          description: Client successfully deleted
        "404":
          $ref: "#/components/responses/NotFound"
  /apikeys:
    get:
      tags:
        - API Keys
      summary: List API Keys
      description: Get all API keys for the authenticated user
      operationId: getApikeys
      security:
        - BearerAuth:
            - profile:read
      responses:
        "200":
          description: List of API keys
          content:
            application/json:
              schema:
                type: object
                properties:
                  keys:
                    type: array
                    items:
                      $ref: "#/components/schemas/ApiKey"
    post:
      tags:
        - API Keys
      summary: Create API Key
      description: Generate a new API key
      operationId: postApikeys
      security:
        - BearerAuth:
            - profile:write
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - name
              properties:
                name:
                  type: string
                  description: Descriptive name for the API key
                  example: Production Server Key
                scopes:
                  type: array
                  items:
                    type: string
                  description: OAuth scopes for this API key
                  example:
                    - crypto:read
                    - stock:read
                expiresIn:
                  type: integer
                  description: Expiration time in seconds (0 = no expiration)
                  example: 2592000
      responses:
        "201":
          description: API key successfully created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiKeyWithSecret"
        "400":
          $ref: "#/components/responses/BadRequest"
  /apikeys/{keyId}:
    get:
      tags:
        - API Keys
      summary: Get API Key Details
      description: Retrieve API key information (without the secret)
      operationId: getApikeysByKeyId
      security:
        - BearerAuth:
            - profile:read
      parameters:
        - name: keyId
          in: path
          required: true
          schema:
            type: string
          description: API key ID
      responses:
        "200":
          description: API key information
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiKey"
        "404":
          $ref: "#/components/responses/NotFound"
    delete:
      tags:
        - API Keys
      summary: Revoke API Key
      description: Delete an API key
      operationId: deleteApikeysByKeyId
      security:
        - BearerAuth:
            - profile:write
      parameters:
        - name: keyId
          in: path
          required: true
          schema:
            type: string
      responses:
        "204":
          description: API key successfully revoked
        "404":
          $ref: "#/components/responses/NotFound"
  /apikeys/{keyId}/usage:
    get:
      tags:
        - API Keys
      summary: Get API Key Usage Statistics
      description: Retrieve usage metrics for an API key
      operationId: getApikeysByKeyIdUsage
      security:
        - BearerAuth:
            - profile:read
      parameters:
        - name: keyId
          in: path
          required: true
          schema:
            type: string
        - name: period
          in: query
          schema:
            type: string
            enum:
              - 1h
              - 24h
              - 7d
              - 30d
            default: 24h
          description: Time period for statistics
      responses:
        "200":
          description: API key usage statistics
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiKeyUsage"
  /v2/crypto/rates/live/session/{base}-{term}:
    get:
      tags:
        - Crypto Aggregated Rates
      summary: Session & Day-of-Week Analytics
      description: |
        Behavioural breakdown of an asset by **trading session** and **weekday**, computed
        from the aggregated weighted midrate over a configurable lookback window.

        Use this endpoint to answer questions like:
        - **"When does this asset move the most?"** — compare volatility across Asia,
          Europe, and US sessions to find the most/least active windows.
        - **"When is the cheapest time to execute a large order?"** — pick the session
          with the lowest realised volatility and most stable returns.
        - **"Are weekends quieter than weekdays?"** — day-of-week bucketing surfaces
          consistent calendar effects.
        - **"Has the Asian session been bullish recently?"** — `avgReturnBps` per
          session reveals systematic drift.

        ## Sessions (UTC)
        | Session  | Window            | Typical activity                     |
        |----------|-------------------|--------------------------------------|
        | `asia`   | 00:00 – 08:00 UTC | Tokyo, Hong Kong, Singapore, Korea   |
        | `europe` | 08:00 – 16:00 UTC | London, Frankfurt, Zurich            |
        | `us`     | 16:00 – 24:00 UTC | New York, Chicago                    |

        Each session bucket includes the recurring window as `startUtc` / `endUtc`
        (ISO 8601, anchored to today's UTC date for a concrete reference instance).

        ## Metrics

        Each bucket reports:
        - **`count`** — number of observations contributing
        - **`avgReturnBps`** — mean return in basis points (1 bp = 0.01%)
        - **`volatilityBps`** — sample standard deviation of returns, also in bps

        Session buckets count **hourly** observations within the lookback window.
        Day-of-week buckets count **daily** observations (one per UTC date).

        ## Lookback

        Default **30 days**. Pass `?lookback=NNd` (1–90 days) or `?lookback=NNh` (1–2160
        hours). Longer windows produce more statistically stable estimates; shorter
        windows reflect the most recent regime.
      operationId: getV2CryptoRatesLiveSessionByPair
      security:
        - BearerAuth:
            - crypto:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/BaseParam"
        - $ref: "#/components/parameters/TermParam"
        - name: lookback
          in: query
          schema:
            type: string
            default: 30d
            example: 30d
          description: |
            Lookback window. Format `NNd` (1-90 days) or `NNh` (1-2160 hours).
            Default `30d`.
      responses:
        "200":
          description: Session and day-of-week analytics
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SessionAnalyticsResponse"
        "404":
          $ref: "#/components/responses/NotFound"
  /v2/crypto/rates/live/midrate/{base}-{term}:
    get:
      tags:
        - Crypto Aggregated Rates
      summary: Aggregated Weighted Midrate
      description: |
        Real-time consensus mid-price for a crypto pair, computed as a volume-weighted
        average across every exchange we monitor. Outliers are filtered so a single
        misbehaving venue cannot move the published price.

        Use this as your single source of truth for "the price of BTC-USD right now"
        across portfolio valuation, NAV calculation, fee-quoting, charts, and
        downstream analytics.

        **HTTP GET** returns the most recent midrate.
        **WebSocket** (`wss://api.windy.network/v2/crypto/rates/live/midrate/{base}-{term}`)
        pushes every update.
      operationId: getV2CryptoRatesLiveMidrateByPair
      security:
        - BearerAuth:
            - crypto:read
            - rate:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/BaseParam"
        - name: term
          in: path
          required: true
          schema:
            type: string
            example: USD
          description: Term currency
      responses:
        "200":
          description: Current midrate
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/RateResponse"
        "404":
          $ref: "#/components/responses/NotFound"
  /v2/crypto/exchanges/{exchange}/live/ticker/{base}-{term}:
    get:
      tags:
        - Crypto Exchanges
      summary: Get Exchange Ticker
      description: |
        Real-time ticker for a single exchange — bid, ask, last trade, 24h high/low,
        24h volume, and price change.

        Use this when you need to know what one specific exchange is showing
        (e.g., to display a Coinbase price next to your "consensus" midrate, or to
        feed an exchange-specific trading bot).

        **HTTP GET** returns the latest snapshot.
        **WebSocket** (`wss://api.windy.network/v2/crypto/exchange/{exchange}/ticker/{symbol}`)
        pushes every update from that exchange.
      operationId: getV2CryptoExchangesByExchangeLiveTickerBySymbol
      security:
        - BearerAuth:
            - crypto:read
            - ticker:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/ExchangeParam"
        - $ref: "#/components/parameters/BaseParam"
        - $ref: "#/components/parameters/TermParam"
      responses:
        "200":
          description: Ticker data
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TickerResponse"
  /v2/crypto/exchanges/ticker/{base}-{term}:
    get:
      tags:
        - Crypto Exchanges
      summary: Get Aggregated Ticker
      description: |
        Ticker data combined across every exchange that trades the pair — the global
        highest bid, lowest ask, average price, and total 24h volume, plus a
        per-exchange breakdown.

        Use it when you want one canonical "what's this asset doing" view without
        picking a specific venue.
      operationId: getV2CryptoExchangesTickerByPair
      security:
        - BearerAuth:
            - crypto:read
            - ticker:read
        - ApiKeyAuth: []
      parameters:
        - name: base
          in: path
          required: true
          schema:
            type: string
            example: BTC
        - name: term
          in: path
          required: true
          schema:
            type: string
            example: USDT
      responses:
        "200":
          description: Aggregated ticker
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AggregatedTickerResponse"
  /v2/crypto/exchanges/tickers:
    get:
      tags:
        - Crypto Exchanges
      summary: List Tickers [SOON]
      description: |
        Bulk fetch ticker data for many pairs in one call, with optional `exchange`,
        `base`, and `term` filters. Use it instead of looping over single-pair calls
        when you need a wide snapshot — e.g., a heatmap or a portfolio view.
      operationId: getV2CryptoExchangesTickers
      x-badges:
        - name: SOON
          position: after
          color: yellow
      security:
        - BearerAuth:
            - crypto:read
            - ticker:read
        - ApiKeyAuth: []
      parameters:
        - name: exchange
          in: query
          schema:
            type: string
            example: binance
        - name: term
          in: query
          schema:
            type: string
            example: USDT
        - name: base
          in: query
          schema:
            type: string
            example: BTC
        - $ref: "#/components/parameters/LimitParam"
      responses:
        "200":
          description: List of tickers
          content:
            application/json:
              schema:
                type: object
                properties:
                  tickers:
                    type: array
                    items:
                      $ref: "#/components/schemas/TickerResponse"
  /v2/crypto/exchanges/tickers/{exchange}:
    get:
      tags:
        - Crypto Exchanges
      summary: Get All Tickers for Exchange [SOON]
      description: |
        Every ticker we receive from a single exchange in one response. Useful to
        scan an entire venue's market in one round-trip — e.g., to compute exchange-
        wide statistics or render a complete venue dashboard.
      operationId: getV2CryptoExchangesTickersByExchange
      x-badges:
        - name: SOON
          position: after
          color: yellow
      security:
        - BearerAuth:
            - crypto:read
            - ticker:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/ExchangeParam"
      responses:
        "200":
          description: Exchange tickers
          content:
            application/json:
              schema:
                type: object
                properties:
                  exchange:
                    type: string
                  tickers:
                    type: array
                    items:
                      $ref: "#/components/schemas/TickerResponse"
  /v2/crypto/rates/ohlc/{timeframe}/{base}-{term}:
    get:
      tags:
        - Crypto OHLC
      summary: Get OHLC/Candlestick Data (v2)
      description: |
        Candlestick data — open, high, low, close — for a crypto pair, computed from
        our aggregated weighted midrate. The candles reflect the cross-exchange
        consensus, not a single venue, so they're robust against single-exchange
        outliers.

        Use it for charts, technical analysis, building strategies, or any time-series
        view. Pick the right `timeframe` for your need: `m1`–`m30` for intraday,
        `h1`–`h4` for short-term swings, `d1`–`mo1` for longer-term analysis.
      operationId: getV2CryptoRatesOhlcByPair
      security:
        - BearerAuth:
            - crypto:read
            - ohlc:read
        - ApiKeyAuth: []
      parameters:
        - name: timeframe
          in: path
          required: true
          schema:
            type: string
            enum:
              - m1
              - m5
              - m15
              - m30
              - h1
              - h4
              - d1
              - w1
              - mo1
            example: h1
          description: Candlestick timeframe
        - $ref: "#/components/parameters/BaseParam"
        - $ref: "#/components/parameters/TermParam"
        - $ref: "#/components/parameters/LimitParam"
        - $ref: "#/components/parameters/FromParam"
        - $ref: "#/components/parameters/ToParam"
      responses:
        "200":
          description: OHLC data
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OHLCResponse"
  /v2/crypto/rates/historic/midrate/{base}-{term}:
    get:
      tags:
        - Crypto Aggregated Rates
      summary: Get Historical Rates
      description: |
        Long-history time series of the aggregated weighted midrate. Returns rate,
        bid, ask, volume, and the number of contributing exchanges at each timestamp.

        Use this for charts, backtests, P&L reconstruction, NAV history, and any
        analysis that needs more than the live snapshot. Pass `from`/`to` to scope
        the window, `limit` to cap the response size.
      operationId: getV2CryptoRatesHistoryByPair
      security:
        - BearerAuth:
            - crypto:read
            - rate:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/BaseParam"
        - $ref: "#/components/parameters/TermParam"
        - $ref: "#/components/parameters/FromParam"
        - $ref: "#/components/parameters/ToParam"
        - $ref: "#/components/parameters/LimitParam"
      responses:
        "200":
          description: Historical rates
          content:
            application/json:
              schema:
                type: object
                properties:
                  type:
                    type: string
                    example: crypto
                  pair:
                    type: string
                    example: BTC-USD
                  base:
                    type: string
                  term:
                    type: string
                  count:
                    type: integer
                  rates:
                    type: array
                    items:
                      type: object
                      properties:
                        timestamp:
                          type: string
                          format: date-time
                        rate:
                          type: number
                          format: double
                        bid:
                          type: number
                          format: double
                        ask:
                          type: number
                          format: double
                        volume:
                          type: number
                          format: double
                        data_points:
                          type: integer
  /v2/crypto/rates/export/midrate/{base}-{term}:
    get:
      tags:
        - Crypto Aggregated Rates
      summary: Bulk-export Historical Rates (CSV / Parquet)
      description: |
        **Streaming bulk download** of the aggregated weighted midrate time
        series, up to **1,000,000 rows per request**. Output is delivered as
        a streamed `attachment` — the browser saves it directly to disk and
        never loads the full payload into memory.

        Choose `format=csv` (default, gzipped on the wire — extension `.csv.gz`)
        for spreadsheet / pandas / DuckDB use, or `format=parquet` for
        columnar / typed analysis (`pyarrow`, Spark, DuckDB, ClickHouse-local).

        The server applies hard ceilings: `max_execution_time=180s`,
        `max_memory_usage=2GiB`, `max_result_rows=1,000,000`. Requests that
        would exceed any of these are aborted before any bytes leave
        ClickHouse — the response is JSON `502` rather than a truncated file.

        Memory profile: the entire pipeline (ClickHouse → clickhouse-proxy →
        nginx → client) streams in ~8 KiB chunks. A 50 MB gzipped export and
        a 5 GB one use the same server-side memory.

        **Rate-limited** at `6r/m` per IP (one export every 10 s).
      operationId: getV2CryptoRatesExportMidrate
      security:
        - BearerAuth:
            - crypto:read
            - rate:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/BaseParam"
        - $ref: "#/components/parameters/TermParam"
        - $ref: "#/components/parameters/FromParam"
        - $ref: "#/components/parameters/ToParam"
        - name: limit
          in: query
          required: false
          description: |
            Maximum rows to return. Server cap is 1,000,000.
            Default: 1,000,000 (i.e., "give me everything within the window").
          schema:
            type: integer
            minimum: 1
            maximum: 1000000
            default: 1000000
        - name: format
          in: query
          required: false
          description: |
            Output format:
              - `csv`     — `CSVWithNames`, gzipped (`Content-Encoding: gzip`),
                            filename `<prefix>_<base>_<term>_...csv.gz`.
                            Browsers auto-decompress; with curl use `--compressed`
                            or `-o name.csv.gz`.
              - `parquet` — `Apache Parquet` binary, no extra compression
                            (Parquet is self-compressing), filename
                            `<prefix>_<base>_<term>_...parquet`.
          schema:
            type: string
            enum:
              - csv
              - parquet
            default: csv
      responses:
        "200":
          description: |
            Streamed file download. `Content-Disposition: attachment;
            filename="..."` is always set. The body is the raw export bytes
            (gzipped CSV or Parquet); ordering is ascending by timestamp.
          headers:
            Content-Type:
              schema:
                type: string
                example: application/gzip
            Content-Disposition:
              schema:
                type: string
                example: attachment; filename="midrate_BTC_USD_now-30d_now.csv.gz"
            Content-Encoding:
              description: Present only for `format=csv` — bytes are gzipped.
              schema:
                type: string
                example: gzip
          content:
            application/gzip:
              schema:
                type: string
                format: binary
            application/vnd.apache.parquet:
              schema:
                type: string
                format: binary
        "400":
          description: Invalid format, limit, or timestamp parameter.
        "429":
          description: Export rate limit exceeded (6 per minute per IP).
        "502":
          description: |
            ClickHouse query aborted before streaming started — typically
            because `max_execution_time`, `max_memory_usage`, or
            `max_result_rows` would be exceeded. Body is JSON
            `{error, status, body}` with the ClickHouse-level message.
  /v2/fiat247/rates/historic/midrate/{base}-{term}:
    get:
      tags:
        - Fiat247 Rates
      summary: Get Fiat247 Historical Rates
      description: |
        Long-history time series of the 24/7 fiat rate for a currency pair (e.g., GBP-USD,
        EUR-USD). Same crypto-derived rate as the live endpoint, but with full historical
        depth for charts, P&L history, and back-dated valuations.
      operationId: getV2Fiat247RatesHistoryByPair
      security:
        - BearerAuth:
            - fiat247:read
            - rate:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/Fiat247BaseParam"
        - $ref: "#/components/parameters/Fiat247TermParam"
        - $ref: "#/components/parameters/FromParam"
        - $ref: "#/components/parameters/ToParam"
        - $ref: "#/components/parameters/LimitParam"
      responses:
        "200":
          description: Historical fiat247 rates
          content:
            application/json:
              schema:
                type: object
                properties:
                  type:
                    type: string
                    example: fiat247
                  pair:
                    type: string
                    example: GBP-USD
                  base:
                    type: string
                  term:
                    type: string
                  count:
                    type: integer
                  rates:
                    type: array
                    items:
                      type: object
                      properties:
                        timestamp:
                          type: string
                          format: date-time
                        rate:
                          type: number
                          format: double
                        bid:
                          type: number
                          format: double
                        ask:
                          type: number
                          format: double
                        volume:
                          type: number
                          format: double
                        data_points:
                          type: integer
  /v2/crypto/rates/historic/ohlc/{timeframe}/{base}-{term}:
    get:
      tags:
        - Crypto OHLC
      summary: Get Historical OHLC Candles
      description: |
        Long-history candlestick data for a crypto pair. Same OHLC shape as the live
        endpoint, but with deeper history — useful for backtests, year-over-year charts,
        and any analysis that needs more than the recent rolling window.
      operationId: getV2CryptoRatesOhlcHistoryByPair
      security:
        - BearerAuth:
            - crypto:read
            - ohlc:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/TimeframeParam"
        - $ref: "#/components/parameters/BaseParam"
        - $ref: "#/components/parameters/TermParam"
        - $ref: "#/components/parameters/FromParam"
        - $ref: "#/components/parameters/ToParam"
        - $ref: "#/components/parameters/LimitParam"
      responses:
        "200":
          description: Historical OHLC candles
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OHLCResponse"
  /v2/fiat247/rates/historic/ohlc/{timeframe}/{base}-{term}:
    get:
      tags:
        - Fiat247 OHLC
      summary: Get Fiat247 Historical OHLC Candles
      description: |
        Long-history candlestick data for a 24/7 fiat pair. Use for charts and
        backtests that need more than the recent rolling window.
      operationId: getV2Fiat247RatesOhlcHistoryByPair
      security:
        - BearerAuth:
            - fiat247:read
            - ohlc:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/TimeframeParam"
        - $ref: "#/components/parameters/Fiat247BaseParam"
        - $ref: "#/components/parameters/Fiat247TermParam"
        - $ref: "#/components/parameters/FromParam"
        - $ref: "#/components/parameters/ToParam"
        - $ref: "#/components/parameters/LimitParam"
      responses:
        "200":
          description: Historical fiat247 OHLC candles
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OHLCResponse"
  /v1/crypto/indicator/live/sma/{timeframe}/{window}/{base}-{term}:
    get:
      tags:
        - Crypto Indicators
      summary: Simple Moving Average (SMA)
      description: |
        Simple Moving Average — the unweighted average of the closing price over the
        last `window` candles. Smooths short-term noise and reveals the underlying
        trend. Common windows: 20 (short term), 50 (medium term), 200 (long term).

        Use it to confirm trend direction (price above the 200-SMA = long-term uptrend),
        identify support/resistance, or build crossover signals (e.g., 50 crosses 200).
        Pass `expand_underlying=true` to also receive the raw candles used.
      operationId: getV1CryptoIndicatorLiveSmaByPair
      security:
        - BearerAuth:
            - crypto:read
            - indicators:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/TimeframeParam"
        - $ref: "#/components/parameters/WindowParam"
        - $ref: "#/components/parameters/BaseParam"
        - $ref: "#/components/parameters/TermParam"
        - $ref: "#/components/parameters/FromParam"
        - $ref: "#/components/parameters/ToParam"
        - $ref: "#/components/parameters/LimitParam"
        - $ref: "#/components/parameters/ExpandUnderlyingParam"
        - $ref: "#/components/parameters/TimestampFormatParam"
      responses:
        "200":
          description: SMA values
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/IndicatorResponse"
              examples:
                unix_timestamps:
                  summary: Unix timestamp format (default)
                  value:
                    indicator: sma
                    window: 20
                    type: crypto
                    pair: BTC-USD
                    base: BTC
                    term: USD
                    timeframe: h1
                    count: 2
                    values:
                      - timestamp: 1705398600000
                        value: 42750.12345678
                      - timestamp: 1705395000000
                        value: 42650.87654321
                iso_timestamps:
                  summary: ISO timestamp format
                  value:
                    indicator: sma
                    window: 20
                    type: crypto
                    pair: BTC-USD
                    base: BTC
                    term: USD
                    timeframe: h1
                    count: 2
                    values:
                      - timestamp: "2024-01-16T09:30:00Z"
                        value: 42750.12345678
                      - timestamp: "2024-01-16T08:30:00Z"
                        value: 42650.87654321
        "400":
          description: Invalid parameters
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: No data found for pair/timeframe
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v1/crypto/indicator/live/ema/{timeframe}/{window}/{base}-{term}:
    get:
      tags:
        - Crypto Indicators
      summary: Exponential Moving Average (EMA)
      description: |
        Exponential Moving Average — like SMA, but weighted so recent prices count
        more than older ones. Reacts faster to price changes, which makes it the
        usual choice for short-term trend signals.

        Use it the same way as SMA but when responsiveness matters more than smoothness.
        Pass `expand_underlying=true` to also receive the raw candles used.
      operationId: getV1CryptoIndicatorLiveEmaByPair
      security:
        - BearerAuth:
            - crypto:read
            - indicators:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/TimeframeParam"
        - $ref: "#/components/parameters/WindowParam"
        - $ref: "#/components/parameters/BaseParam"
        - $ref: "#/components/parameters/TermParam"
        - $ref: "#/components/parameters/FromParam"
        - $ref: "#/components/parameters/ToParam"
        - $ref: "#/components/parameters/LimitParam"
        - $ref: "#/components/parameters/ExpandUnderlyingParam"
        - $ref: "#/components/parameters/TimestampFormatParam"
      responses:
        "200":
          description: EMA values
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/IndicatorResponse"
              examples:
                basic:
                  summary: Basic EMA response
                  value:
                    indicator: ema
                    window: 20
                    type: crypto
                    pair: BTC-USD
                    base: BTC
                    term: USD
                    timeframe: h1
                    count: 2
                    values:
                      - timestamp: 1705398600000
                        value: 42780.45678901
                      - timestamp: 1705395000000
                        value: 42690.12345678
        "400":
          description: Invalid parameters
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: No data found for pair/timeframe
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v2/fiat247/rates/live/{base}-{term}:
    get:
      tags:
        - Fiat247 Rates
      summary: Get Fiat247 Rate
      description: |
        Real-time fiat-to-fiat rate (GBP-USD, EUR-USD, JPY-USD, …) that **never closes**.

        Standard forex rates pause overnight and on weekends, which leaves a 60+ hour
        gap every weekend. We synthesize a continuous rate by triangulating crypto
        markets that trade 24/7 (e.g., USDT-GBP × USDT-USD ≈ GBP-USD), giving you a
        usable price at every second of every day.

        Use this for international fintech, weekend transfers, crypto-to-fiat
        conversion, and any product that needs a fiat rate when the official market
        is closed.
      operationId: getV2Fiat247RatesLiveByPair
      security:
        - BearerAuth:
            - fiat247:read
            - rate:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/Fiat247BaseParam"
        - $ref: "#/components/parameters/Fiat247TermParam"
      responses:
        "200":
          description: Current fiat247 rate
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Fiat247RateResponse"
        "404":
          $ref: "#/components/responses/NotFound"
        "429":
          $ref: "#/components/responses/RateLimitExceeded"
  /v2/fiat247/rates/live/base/{base}-{fiat}:
    get:
      tags:
        - Fiat247 Rates
      summary: Get Crypto/Fiat Base Rate
      description: |
        Real-time price of a cryptocurrency expressed directly in a non-USD fiat
        currency — e.g., BTC-GBP, ETH-EUR, SOL-JPY.

        Internally we triangulate the crypto-USD price with the corresponding fiat
        rate, so the value updates continuously even when traditional forex markets
        are closed. Use it to display crypto prices natively in your user's local
        currency without a separate conversion step.
      operationId: getV2Fiat247RatesLiveBaseByPair
      security:
        - BearerAuth:
            - fiat247:read
            - rate:read
        - ApiKeyAuth: []
      parameters:
        - name: base
          in: path
          required: true
          schema:
            type: string
            example: BTC
          description: Crypto asset symbol (e.g., BTC, ETH)
        - name: fiat
          in: path
          required: true
          schema:
            type: string
            example: GBP
          description: Fiat currency symbol (e.g., GBP, EUR, JPY)
      responses:
        "200":
          description: Crypto/Fiat rate
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Fiat247RateResponse"
        "404":
          $ref: "#/components/responses/NotFound"
        "429":
          $ref: "#/components/responses/RateLimitExceeded"
  /v1/fiat247/ohlc/{timeframe}/{base}-{term}:
    get:
      tags:
        - Fiat247 OHLC
      summary: Get Fiat247 OHLC Candles
      description: |
        Candlestick data for a 24/7 fiat pair — open, high, low, and close at the
        timeframe of your choice (1-minute through monthly). Use it to chart fiat
        rates with no weekend gaps, run technical analysis, or feed visualisations.
      operationId: getV1Fiat247OhlcByPair
      security:
        - BearerAuth:
            - fiat247:read
            - ohlc:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/TimeframeParam"
        - $ref: "#/components/parameters/Fiat247BaseParam"
        - $ref: "#/components/parameters/Fiat247TermParam"
        - $ref: "#/components/parameters/FromParam"
        - $ref: "#/components/parameters/ToParam"
        - $ref: "#/components/parameters/LimitParam"
      responses:
        "200":
          description: OHLC candle data
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OHLCResponse"
        "404":
          $ref: "#/components/responses/NotFound"
        "429":
          $ref: "#/components/responses/RateLimitExceeded"
  /v1/fiat247/indicator/sma/{timeframe}/{window}/{base}-{term}:
    get:
      tags:
        - Fiat247 Indicators
      summary: Simple Moving Average (SMA) for Fiat
      description: |
        Simple Moving Average for a 24/7 fiat pair. Smooths noise to reveal trend
        direction. Common windows: 20 / 50 / 200. Use for trend confirmation, support
        and resistance, or moving-average crossover strategies.
      operationId: getV1Fiat247IndicatorSmaByPair
      security:
        - BearerAuth:
            - fiat247:read
            - indicators:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/TimeframeParam"
        - $ref: "#/components/parameters/WindowParam"
        - $ref: "#/components/parameters/Fiat247BaseParam"
        - $ref: "#/components/parameters/Fiat247TermParam"
        - $ref: "#/components/parameters/FromParam"
        - $ref: "#/components/parameters/ToParam"
        - $ref: "#/components/parameters/LimitParam"
        - $ref: "#/components/parameters/ExpandUnderlyingParam"
        - $ref: "#/components/parameters/TimestampFormatParam"
      responses:
        "200":
          description: SMA values
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/IndicatorResponse"
        "400":
          description: Invalid parameters
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: No data found for pair/timeframe
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v1/fiat247/indicator/ema/{timeframe}/{window}/{base}-{term}:
    get:
      tags:
        - Fiat247 Indicators
      summary: Exponential Moving Average (EMA) for Fiat
      description: |
        Exponential Moving Average for a 24/7 fiat pair. Weights recent prices more
        heavily so it reacts faster than SMA — preferred for short-term trend signals.
      operationId: getV1Fiat247IndicatorEmaByPair
      security:
        - BearerAuth:
            - fiat247:read
            - indicators:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/TimeframeParam"
        - $ref: "#/components/parameters/WindowParam"
        - $ref: "#/components/parameters/Fiat247BaseParam"
        - $ref: "#/components/parameters/Fiat247TermParam"
        - $ref: "#/components/parameters/FromParam"
        - $ref: "#/components/parameters/ToParam"
        - $ref: "#/components/parameters/LimitParam"
        - $ref: "#/components/parameters/ExpandUnderlyingParam"
        - $ref: "#/components/parameters/TimestampFormatParam"
      responses:
        "200":
          description: EMA values
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/IndicatorResponse"
        "400":
          description: Invalid parameters
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: No data found for pair/timeframe
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v1/crypto/indicator/live/rsi/{timeframe}/{window}/{base}-{term}:
    get:
      tags:
        - Crypto Indicators
      summary: Relative Strength Index (RSI)
      description: |
        RSI is a 0–100 momentum indicator that compares the size of recent gains to
        recent losses. It tells you whether an asset is overbought or oversold relative
        to its own recent behaviour — independent of price level.

        **Reading the value:**
        - **> 70** — overbought, may be due for a pullback
        - **< 30** — oversold, may be due for a bounce
        - **50** — neutral momentum

        Common window: **14**. Computed using Wilder's smoothing (the standard).
        Use it for entry timing, divergence detection (price makes new high but RSI
        doesn't = trend weakening), or as a filter inside a larger strategy.
      operationId: getV1CryptoIndicatorLiveRsiByPair
      security:
        - BearerAuth:
            - crypto:read
            - indicators:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/TimeframeParam"
        - $ref: "#/components/parameters/WindowParam"
        - $ref: "#/components/parameters/BaseParam"
        - $ref: "#/components/parameters/TermParam"
        - $ref: "#/components/parameters/FromParam"
        - $ref: "#/components/parameters/ToParam"
        - $ref: "#/components/parameters/LimitParam"
        - $ref: "#/components/parameters/ExpandUnderlyingParam"
        - $ref: "#/components/parameters/TimestampFormatParam"
      responses:
        "200":
          description: RSI values
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/RSIResponse"
              example:
                indicator: rsi
                window: 14
                type: crypto
                pair: BTC-USD
                base: BTC
                term: USD
                timeframe: h1
                count: 2
                values:
                  - timestamp: 1705398600000
                    value: 65.5
                  - timestamp: 1705395000000
                    value: 62.3
        "400":
          description: Invalid parameters
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: No data found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v1/crypto/indicator/live/macd/{timeframe}/{base}-{term}:
    get:
      tags:
        - Crypto Indicators
      summary: Moving Average Convergence Divergence (MACD)
      description: |
        MACD measures the difference between a fast and a slow EMA, then smooths that
        difference to produce a "signal" line. The gap between them (the histogram)
        flags shifts in momentum.

        **How traders read it:**
        - **MACD crosses above signal** → bullish momentum starting
        - **MACD crosses below signal** → bearish momentum starting
        - **Histogram growing** → trend strengthening; **shrinking** → trend weakening
        - **Divergence** (price makes new high but MACD doesn't) → trend may be ending

        Defaults are the classic **12 / 26 / 9** parameters; tune `fast`, `slow`, and
        `signal` for shorter or longer-term sensitivity.
      operationId: getV1CryptoIndicatorLiveMacdByPair
      security:
        - BearerAuth:
            - crypto:read
            - indicators:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/TimeframeParam"
        - $ref: "#/components/parameters/BaseParam"
        - $ref: "#/components/parameters/TermParam"
        - name: fast
          in: query
          description: Fast EMA period (2-100)
          schema:
            type: integer
            minimum: 2
            maximum: 100
            default: 12
            example: 12
        - name: slow
          in: query
          description: Slow EMA period (2-200, must be > fast)
          schema:
            type: integer
            minimum: 2
            maximum: 200
            default: 26
            example: 26
        - name: signal
          in: query
          description: Signal line EMA period (2-50)
          schema:
            type: integer
            minimum: 2
            maximum: 50
            default: 9
            example: 9
        - $ref: "#/components/parameters/FromParam"
        - $ref: "#/components/parameters/ToParam"
        - $ref: "#/components/parameters/LimitParam"
        - $ref: "#/components/parameters/ExpandUnderlyingParam"
        - $ref: "#/components/parameters/TimestampFormatParam"
      responses:
        "200":
          description: MACD values
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MACDResponse"
        "400":
          description: Invalid parameters
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: No data found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v1/crypto/indicator/live/bbands/{timeframe}/{window}/{base}-{term}:
    get:
      tags:
        - Crypto Indicators
      summary: Bollinger Bands
      description: |
        Bollinger Bands wrap a moving average with an upper and lower band drawn at a
        configurable number of standard deviations from the middle. The bands widen
        when volatility rises and tighten when it falls.

        **How traders read them:**
        - **Price near upper band** → potentially overbought
        - **Price near lower band** → potentially oversold
        - **Bands tightening** ("squeeze") → low volatility, often precedes a breakout
        - **`percentB`** locates price within the bands (0 = at lower, 1 = at upper)
        - **`bandwidth`** quantifies how wide the bands are right now

        Defaults: **20-period SMA, 2 standard deviations** (the standard Bollinger setup).
      operationId: getV1CryptoIndicatorLiveBbandsByPair
      security:
        - BearerAuth:
            - crypto:read
            - indicators:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/TimeframeParam"
        - $ref: "#/components/parameters/WindowParam"
        - $ref: "#/components/parameters/BaseParam"
        - $ref: "#/components/parameters/TermParam"
        - name: stddev
          in: query
          description: Standard deviation multiplier (0.5-5)
          schema:
            type: number
            minimum: 0.5
            maximum: 5
            default: 2
            example: 2
        - $ref: "#/components/parameters/FromParam"
        - $ref: "#/components/parameters/ToParam"
        - $ref: "#/components/parameters/LimitParam"
        - $ref: "#/components/parameters/ExpandUnderlyingParam"
        - $ref: "#/components/parameters/TimestampFormatParam"
      responses:
        "200":
          description: Bollinger Bands values
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/BollingerBandsResponse"
        "400":
          description: Invalid parameters
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: No data found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v1/fiat247/indicator/rsi/{timeframe}/{window}/{base}-{term}:
    get:
      tags:
        - Fiat247 Indicators
      summary: Relative Strength Index (RSI) for Fiat
      description: |
        RSI (0–100) for a 24/7 fiat pair. Reads above 70 are overbought, below 30 are
        oversold, around 50 is neutral. Common window: 14. Useful for entry timing
        and divergence detection.
      operationId: getV1Fiat247IndicatorRsiByPair
      security:
        - BearerAuth:
            - fiat247:read
            - indicators:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/TimeframeParam"
        - $ref: "#/components/parameters/WindowParam"
        - $ref: "#/components/parameters/Fiat247BaseParam"
        - $ref: "#/components/parameters/Fiat247TermParam"
        - $ref: "#/components/parameters/FromParam"
        - $ref: "#/components/parameters/ToParam"
        - $ref: "#/components/parameters/LimitParam"
        - $ref: "#/components/parameters/ExpandUnderlyingParam"
        - $ref: "#/components/parameters/TimestampFormatParam"
      responses:
        "200":
          description: RSI values
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/RSIResponse"
        "400":
          description: Invalid parameters
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: No data found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v1/fiat247/indicator/macd/{timeframe}/{base}-{term}:
    get:
      tags:
        - Fiat247 Indicators
      summary: Moving Average Convergence Divergence (MACD) for Fiat
      description: |
        MACD for a 24/7 fiat pair. Tracks momentum shifts via the gap between a fast
        and slow EMA. Crossovers between MACD and signal flag changes in trend.
        Defaults: 12 / 26 / 9.
      operationId: getV1Fiat247IndicatorMacdByPair
      security:
        - BearerAuth:
            - fiat247:read
            - indicators:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/TimeframeParam"
        - $ref: "#/components/parameters/Fiat247BaseParam"
        - $ref: "#/components/parameters/Fiat247TermParam"
        - name: fast
          in: query
          schema:
            type: integer
            default: 12
        - name: slow
          in: query
          schema:
            type: integer
            default: 26
        - name: signal
          in: query
          schema:
            type: integer
            default: 9
        - $ref: "#/components/parameters/FromParam"
        - $ref: "#/components/parameters/ToParam"
        - $ref: "#/components/parameters/LimitParam"
        - $ref: "#/components/parameters/ExpandUnderlyingParam"
        - $ref: "#/components/parameters/TimestampFormatParam"
      responses:
        "200":
          description: MACD values
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MACDResponse"
        "400":
          description: Invalid parameters
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: No data found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v1/fiat247/indicator/bbands/{timeframe}/{window}/{base}-{term}:
    get:
      tags:
        - Fiat247 Indicators
      summary: Bollinger Bands for Fiat
      description: |
        Bollinger Bands for a 24/7 fiat pair. The bands widen on high volatility and
        tighten on low volatility — a tight band ("squeeze") often precedes a breakout.
        Defaults: 20-period SMA, 2 standard deviations.
      operationId: getV1Fiat247IndicatorBbandsByPair
      security:
        - BearerAuth:
            - fiat247:read
            - indicators:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/TimeframeParam"
        - $ref: "#/components/parameters/WindowParam"
        - $ref: "#/components/parameters/Fiat247BaseParam"
        - $ref: "#/components/parameters/Fiat247TermParam"
        - name: stddev
          in: query
          schema:
            type: number
            default: 2
        - $ref: "#/components/parameters/FromParam"
        - $ref: "#/components/parameters/ToParam"
        - $ref: "#/components/parameters/LimitParam"
        - $ref: "#/components/parameters/ExpandUnderlyingParam"
        - $ref: "#/components/parameters/TimestampFormatParam"
      responses:
        "200":
          description: Bollinger Bands values
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/BollingerBandsResponse"
        "400":
          description: Invalid parameters
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: No data found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v2/crypto/exchanges/{exchange}/live/trade/{base}-{term}:
    get:
      tags:
        - Crypto Exchanges
      summary: Get Latest Trade
      description: |
        The most recent executed trade on a specific exchange — price, size, side
        (buy/sell), and timestamp. Useful for "last trade" tickers, trade tape
        previews, and any UI that wants to show live activity from a single venue.

        **HTTP GET** returns the latest trade.
        **WebSocket** (`wss://api.windy.network/v2/crypto/exchange/{exchange}/trade/{base}-{term}`)
        pushes every new trade as it happens.
      operationId: getV2CryptoExchangesByExchangeLiveTradeByPair
      security:
        - BearerAuth:
            - crypto:read
            - trades:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/ExchangeParam"
        - $ref: "#/components/parameters/BaseParam"
        - $ref: "#/components/parameters/TermParam"
      responses:
        "200":
          description: Latest trade
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Trade"
        "404":
          $ref: "#/components/responses/NotFound"
  /v2/crypto/exchanges/{exchange}/live/trades/{base}-{term}:
    get:
      tags:
        - Crypto Exchanges
      summary: Get Recent Trades List
      description: |
        The most recent N trades on a single exchange, newest first. Each entry has
        price, size, side, and timestamp.

        Use it to render a trade tape, compute very-short-term VWAP / volume, or
        sanity-check what just happened on a specific venue. Default 25, max 50.
      operationId: getV2CryptoExchangesByExchangeLiveTradesByPair
      security:
        - BearerAuth:
            - crypto:read
            - trades:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/ExchangeParam"
        - $ref: "#/components/parameters/BaseParam"
        - $ref: "#/components/parameters/TermParam"
        - name: limit
          in: query
          schema:
            type: integer
            default: 25
            maximum: 50
            minimum: 1
          description: Number of trades to return (default 25, max 50)
      responses:
        "200":
          description: Recent trades from exchange
          content:
            application/json:
              schema:
                type: object
                properties:
                  symbol:
                    type: string
                    example: BTC/USDT
                  exchange:
                    type: string
                    example: binance
                  count:
                    type: integer
                    example: 25
                  trades:
                    type: array
                    items:
                      $ref: "#/components/schemas/Trade"
        "404":
          $ref: "#/components/responses/NotFound"
  /v2/crypto/exchanges/trades/{base}-{term}:
    get:
      tags:
        - Crypto Exchanges
      summary: Get Aggregated Trades [SOON]
      description: |
        Recent trades for a pair merged from every exchange we track, newest first.
        Each entry includes which exchange it came from, so you can see who's
        actually trading right now.

        Use it for a unified "global tape" view, cross-venue volume comparison, or
        to spot single-exchange surges. Default 25, max 50.
      operationId: getV2CryptoExchangesTradesByPair
      x-badges:
        - name: SOON
          position: after
          color: yellow
      security:
        - BearerAuth:
            - crypto:read
            - trades:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/BaseParam"
        - $ref: "#/components/parameters/TermParam"
        - name: limit
          in: query
          schema:
            type: integer
            default: 25
            maximum: 50
            minimum: 1
          description: Number of trades to return (default 25, max 50)
      responses:
        "200":
          description: Aggregated trades
          content:
            application/json:
              schema:
                type: object
                properties:
                  symbol:
                    type: string
                    example: BTC/USDT
                  count:
                    type: integer
                    example: 25
                  trades:
                    type: array
                    items:
                      allOf:
                        - $ref: "#/components/schemas/Trade"
                        - type: object
                          properties:
                            exchange:
                              type: string
                              example: binance
        "404":
          $ref: "#/components/responses/NotFound"
  /v2/crypto/exchanges/{exchange}/live/funding/{base}-{term}:
    get:
      tags:
        - Crypto Exchanges
      summary: Get Latest Funding Rate [NEW]
      description: |
        The current funding rate for a perpetual futures contract on a specific
        exchange. Funding is the periodic payment between longs and shorts that keeps
        a perp's price tethered to spot — a positive rate means longs pay shorts,
        negative means shorts pay longs.

        Use it to monitor leverage cost, build carry strategies (long spot + short
        perp to harvest funding), or measure how bullish/bearish positioning is right
        now. The response also includes mark price, index price, and the next funding
        timestamp. Updated every 10 minutes.
      operationId: getV2CryptoExchangesByExchangeLiveFundingByPair
      x-badges:
        - name: NEW
          position: after
          color: green
      security:
        - BearerAuth:
            - crypto:read
            - derivatives:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/ExchangeParam"
        - $ref: "#/components/parameters/BaseParam"
        - $ref: "#/components/parameters/TermParam"
      responses:
        "200":
          description: Latest funding rate sample
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/FundingRate"
        "404":
          $ref: "#/components/responses/NotFound"
  /v2/crypto/exchanges/{exchange}/historic/funding/{base}-{term}:
    get:
      tags:
        - Crypto Exchanges
      summary: Get Historic Funding Rates [NEW]
      description: |
        Recent history of funding rates for a perpetual contract. Use it to chart
        funding over time, compute the average funding cost over a holding period,
        or compare current funding against a recent baseline.

        - Without `from`/`to` → returns the most recent N samples (newest first)
        - With `from`/`to` → returns samples in that window (oldest first)

        We retain up to 7 days of recent samples (the 5,000 most recent).
      operationId: getV2CryptoExchangesByExchangeHistoricFundingByPair
      x-badges:
        - name: NEW
          position: after
          color: green
      security:
        - BearerAuth:
            - crypto:read
            - derivatives:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/ExchangeParam"
        - $ref: "#/components/parameters/BaseParam"
        - $ref: "#/components/parameters/TermParam"
        - $ref: "#/components/parameters/FromParam"
        - $ref: "#/components/parameters/ToParam"
        - $ref: "#/components/parameters/LimitParam"
      responses:
        "200":
          description: Historic funding rate samples
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/FundingRateHistory"
  /v2/crypto/exchanges/{exchange}/live/open-interest/{base}-{term}:
    get:
      tags:
        - Crypto Exchanges
      summary: Get Latest Open Interest [NEW]
      description: |
        Total notional value of all open positions in a perpetual contract on a
        specific exchange — i.e., how much money is currently committed to that market.

        Rising open interest with rising price = new longs entering (strong trend).
        Falling open interest with rising price = shorts covering (weaker rally).
        Use it to gauge conviction behind a price move, monitor leverage build-up,
        or compare positioning across exchanges. Updated every 10 minutes.
      operationId: getV2CryptoExchangesByExchangeLiveOpenInterestByPair
      x-badges:
        - name: NEW
          position: after
          color: green
      security:
        - BearerAuth:
            - crypto:read
            - derivatives:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/ExchangeParam"
        - $ref: "#/components/parameters/BaseParam"
        - $ref: "#/components/parameters/TermParam"
      responses:
        "200":
          description: Latest open interest sample
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OpenInterest"
        "404":
          $ref: "#/components/responses/NotFound"
  /v2/crypto/exchanges/{exchange}/historic/open-interest/{base}-{term}:
    get:
      tags:
        - Crypto Exchanges
      summary: Get Historic Open Interest [NEW]
      description: |
        Recent history of open interest for a perpetual contract. Use it to chart how
        positioning evolves over time, spot OI spikes that often precede volatility,
        or correlate OI changes with price moves.

        - Without `from`/`to` → returns the most recent N samples (newest first)
        - With `from`/`to` → returns samples in that window (oldest first)

        We retain up to 7 days of recent samples (the 5,000 most recent).
      operationId: getV2CryptoExchangesByExchangeHistoricOpenInterestByPair
      x-badges:
        - name: NEW
          position: after
          color: green
      security:
        - BearerAuth:
            - crypto:read
            - derivatives:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/ExchangeParam"
        - $ref: "#/components/parameters/BaseParam"
        - $ref: "#/components/parameters/TermParam"
        - $ref: "#/components/parameters/FromParam"
        - $ref: "#/components/parameters/ToParam"
        - $ref: "#/components/parameters/LimitParam"
      responses:
        "200":
          description: Historic open interest samples
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OpenInterestHistory"
  /v2/crypto/exchanges/{exchange}/live/liquidation/{base}-{term}:
    get:
      tags:
        - Crypto Exchanges
      summary: Get Latest Liquidation [NEW]
      description: |
        The most recent forced position closure ("liquidation") on a specific exchange
        for a perpetual contract. A liquidation happens when a leveraged trader runs
        out of margin and the exchange force-closes their position at market.

        Each event includes the side (was a long or short liquidated), the price it
        cleared at, and the size. Use liquidations to spot capitulation, identify
        cascade events, or feed live "rekt" feeds. Liquidations are event-driven, so
        quiet pairs may have no recent events.
      operationId: getV2CryptoExchangesByExchangeLiveLiquidationByPair
      x-badges:
        - name: NEW
          position: after
          color: green
      security:
        - BearerAuth:
            - crypto:read
            - derivatives:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/ExchangeParam"
        - $ref: "#/components/parameters/BaseParam"
        - $ref: "#/components/parameters/TermParam"
      responses:
        "200":
          description: Latest liquidation event
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Liquidation"
        "404":
          $ref: "#/components/responses/NotFound"
  /v2/crypto/exchanges/{exchange}/historic/liquidation/{base}-{term}:
    get:
      tags:
        - Crypto Exchanges
      summary: Get Historic Liquidations [NEW]
      description: |
        Recent liquidation events on a single exchange for a perpetual contract.
        Useful for visualising liquidation clusters around key price levels,
        measuring market stress, or building "liquidation feed" widgets.

        - Without `from`/`to` → returns the most recent N events (newest first)
        - With `from`/`to` → returns events in that window (oldest first)

        We retain the 100 most recent events from the last day.
      operationId: getV2CryptoExchangesByExchangeHistoricLiquidationByPair
      x-badges:
        - name: NEW
          position: after
          color: green
      security:
        - BearerAuth:
            - crypto:read
            - derivatives:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/ExchangeParam"
        - $ref: "#/components/parameters/BaseParam"
        - $ref: "#/components/parameters/TermParam"
        - $ref: "#/components/parameters/FromParam"
        - $ref: "#/components/parameters/ToParam"
        - $ref: "#/components/parameters/LimitParam"
      responses:
        "200":
          description: Historic liquidation events
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/LiquidationHistory"
  /v2/crypto/exchanges/{exchange}/live/orderbook/{base}-{term}:
    get:
      tags:
        - Crypto Exchanges
      summary: Get Order Book
      description: |
        Live order book snapshot for a single exchange — the resting bids and asks at
        each price level, plus the best bid/ask and exchange-supplied update sequence.

        Bids come back highest-price first, asks lowest-price first. Use it for
        depth-of-market widgets, single-venue execution analysis, or to feed a market
        microstructure model. Tune `?depth=N` (1–1000) for how many levels per side
        you want.
      operationId: getV2CryptoExchangesByExchangeLiveOrderbookByPair
      security:
        - BearerAuth:
            - crypto:read
            - orderbook:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/ExchangeParam"
        - $ref: "#/components/parameters/BaseParam"
        - $ref: "#/components/parameters/TermParam"
        - name: depth
          in: query
          schema:
            type: integer
            default: 20
            minimum: 1
            maximum: 1000
            example: 20
          description: Maximum number of price levels to return per side (bids and asks)
      responses:
        "200":
          description: Order book snapshot
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OrderBookResponse"
        "404":
          $ref: "#/components/responses/NotFound"
  /v2/crypto/exchanges/orderbook/{base}-{term}:
    get:
      tags:
        - Crypto Order Books
      summary: Get Aggregated Order Book
      description: |
        A single unified order book for a pair, merged across every exchange that
        trades it. Liquidity at the same price from different venues is summed, and
        each level lists which exchanges contribute to it.

        Use it to see the **true** depth available at any price level, identify the
        dominant liquidity providers, and run pre-trade analysis that accounts for
        all venues at once.

        `best_bid` and `best_ask` are global (the highest bid and lowest ask anywhere),
        so `spread` can be **negative** when markets are crossed — that's a real
        cross-exchange arbitrage signal, not an error. Tune `?depth=N` for levels per side.
      operationId: getV2CryptoExchangesOrderbookByPair
      security:
        - BearerAuth:
            - crypto:read
            - orderbook:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/BaseParam"
        - $ref: "#/components/parameters/TermParam"
        - name: depth
          in: query
          schema:
            type: integer
            default: 20
            minimum: 1
            maximum: 1000
            example: 20
          description: Maximum number of price levels to return per side after aggregation
      responses:
        "200":
          description: Aggregated order book snapshot
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AggregatedOrderBookResponse"
        "404":
          $ref: "#/components/responses/NotFound"
  /v2/crypto/analytics/live/liquidity/{base}-{term}:
    get:
      tags:
        - Crypto Analytics
      summary: Real-Time Liquidity Score
      description: |
        A single 0–100 score that answers "**how liquid is this asset right now?**"
        — the higher the score, the easier it is to trade meaningful size without
        moving the price.

        The score blends two things: how much resting depth sits within 10bps of the
        mid-price (most of the weight) and how tight the bid-ask spread is. Beneath
        the score you also get a depth breakdown at 1 / 5 / 10 / 50 bps thresholds
        so you can see exactly where the liquidity sits.

        **Ratings:** 80–100 Excellent · 60–79 Good · 40–59 Moderate · 20–39 Thin · 0–19 Very Thin.

        Use it for position sizing limits, listing committee reviews, collateral
        haircut policies, or risk dashboards.
      operationId: getV2CryptoAnalyticsLiveLiquidityByPair
      security:
        - BearerAuth:
            - crypto:read
            - orderbook:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/BaseParam"
        - $ref: "#/components/parameters/TermParam"
      responses:
        "200":
          description: Liquidity score
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/LiquidityScoreResponse"
        "404":
          $ref: "#/components/responses/NotFound"
  /v2/crypto/analytics/live/spread/{base}-{term}:
    get:
      tags:
        - Crypto Analytics
      summary: Real-Time Bid-Ask Spread Across Exchanges
      description: |
        Returns the current bid-ask spread per exchange for a trading pair, ranked
        from tightest to widest. Spread is reported as both absolute price units
        and basis points (`(ask - bid) / mid × 10000`).

        Includes summary stats (tightest/widest exchange, average and median bps)
        and the per-exchange breakdown with bid, ask, mid, and timestamp.

        Use cases: choosing execution venue, Transaction Cost Analysis (TCA),
        monitoring spread regime changes, comparing exchange liquidity quality.
      operationId: getV2CryptoAnalyticsLiveSpreadByPair
      security:
        - BearerAuth:
            - crypto:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/BaseParam"
        - $ref: "#/components/parameters/TermParam"
      responses:
        "200":
          description: Per-exchange spread snapshot
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SpreadResponse"
        "404":
          $ref: "#/components/responses/NotFound"
  /v2/crypto/analytics/live/premium/{base}-{term}:
    get:
      tags:
        - Crypto Analytics
      summary: Cross-Exchange Premium / Discount
      description: |
        Per-exchange premium or discount versus the cross-exchange consensus mid-price.
        The consensus is the **volume-weighted mean** of every exchange's mid (or
        equal-weighted as a fallback if no volume is reported), and each exchange's
        premium is reported in both basis points and percent.

        Use it to spot regional premiums (e.g. the Korean "Kimchi premium" on Upbit/
        Bithumb), to flag exchanges that have drifted from consensus, or to feed an
        arbitrage scanner. Sorted from highest premium to lowest.
      operationId: getV2CryptoAnalyticsLivePremiumByPair
      security:
        - BearerAuth:
            - crypto:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/BaseParam"
        - $ref: "#/components/parameters/TermParam"
      responses:
        "200":
          description: Per-exchange premium snapshot
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PremiumResponse"
        "404":
          $ref: "#/components/responses/NotFound"
  /v2/crypto/analytics/live/cex-dex-premium/{base}-{term}:
    get:
      tags:
        - Crypto Analytics
      summary: CEX vs DEX Premium
      description: |
        Compares the aggregated CEX midrate (across all 27+ centralised exchanges)
        with the on-chain DEX midrate (Uniswap, Curve, Balancer, etc.) for the same
        token, and returns the premium delta — both as an absolute price difference
        and in basis points.

        Use cases:
        - Spotting arbitrage opportunities when the gap is persistent
        - Detecting regulatory friction (a token blocked on certain CEXes)
        - Research signal — "where the trustworthy price is" for a given asset

        `higherSide` reports `cex`, `dex`, or `neutral`. A 404 is returned only when
        neither side has any data; if only one side is available the response
        includes that side's snapshot and `premium` is `null` with a `warning`.
      operationId: getV2CryptoAnalyticsLiveCexDexPremiumByPair
      security:
        - BearerAuth:
            - crypto:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/BaseParam"
        - $ref: "#/components/parameters/TermParam"
      responses:
        "200":
          description: CEX vs DEX premium snapshot
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CexDexPremiumResponse"
        "404":
          $ref: "#/components/responses/NotFound"
  /v2/crypto/exchanges/comparison/{base}:
    get:
      tags:
        - Crypto Exchanges
      summary: Per-Exchange Comparison Dashboard
      description: |
        Per-exchange snapshot for a base asset across `BASE/USD`, `BASE/USDT`,
        `BASE/USDC`, `BASE/EUR` ticker hashes. Each row carries last price,
        mid, spread (bps), 24h percent change, USD-equivalent volume, age of
        last update, and a `fresh` flag (true if < 60s old). Sorted by volume
        descending.

        Use it to choose execution venue, monitor data-feed health, or build a
        marketplace comparison page.
      operationId: getV2CryptoExchangesComparisonByBase
      security:
        - BearerAuth:
            - crypto:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/BaseParam"
      responses:
        "200":
          description: Per-exchange comparison
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ExchangeComparisonResponse"
        "404":
          $ref: "#/components/responses/NotFound"
  /v2/crypto/rates/audit/midrate/{base}-{term}:
    get:
      tags:
        - Crypto - Rates
      summary: Audit-Trail Midrate (Single Timestamp)
      description: |
        Verified historical aggregated midrate at a specific timestamp, suitable
        for fund NAV calculation, audit verification, and tax cost-basis. Returns
        the row from the ClickHouse archive closest to the requested `ts` (looking
        backward if no exact match), plus a methodology block disclosing how the
        midrate was derived.

        `ts` accepts ISO 8601, Unix seconds, or `now-Nd` style relative times.
      operationId: getV2CryptoRatesAuditMidrateByPair
      security:
        - BearerAuth:
            - crypto:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/BaseParam"
        - $ref: "#/components/parameters/TermParam"
        - name: ts
          in: query
          required: true
          schema:
            type: string
            example: "2025-12-31T23:59:59Z"
          description: Timestamp to look up (ISO 8601, Unix seconds, or 'now-Nd')
      responses:
        "200":
          description: Audit-trail snapshot
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AuditMidrateResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "404":
          $ref: "#/components/responses/NotFound"
  /v2/crypto/exchanges/funding/{base}-{term}:
    get:
      tags:
        - Crypto - Derivatives
      summary: Aggregate Funding Rate (Cross-Exchange)
      description: |
        Latest funding rate for the pair across every perps-supporting exchange we
        track. Returns the per-exchange list ranked highest to lowest, plus a
        summary (average, positive/negative count, highest/lowest venue, spread).

        Each row carries the funding rate (raw and × 100), implied APR (rate × 3 ×
        365 × 100, assuming 8h funding intervals), next funding rate, mark price,
        and index price.
      operationId: getV2CryptoExchangesFundingByPair
      security:
        - BearerAuth:
            - crypto:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/BaseParam"
        - $ref: "#/components/parameters/TermParam"
      responses:
        "200":
          description: Aggregated funding rate snapshot
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/FundingAggregateResponse"
        "404":
          $ref: "#/components/responses/NotFound"
  /v2/crypto/exchanges/open-interest/{base}-{term}:
    get:
      tags:
        - Crypto - Derivatives
      summary: Aggregate Open Interest (Cross-Exchange)
      description: |
        Latest open interest for the pair summed across every perps-supporting
        exchange. Returns the total amount and total notional value, plus a
        per-exchange breakdown. The summary highlights the largest venue and its
        share of total OI — a quick read on concentration risk.
      operationId: getV2CryptoExchangesOpenInterestByPair
      security:
        - BearerAuth:
            - crypto:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/BaseParam"
        - $ref: "#/components/parameters/TermParam"
      responses:
        "200":
          description: Aggregated open interest snapshot
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OpenInterestAggregateResponse"
        "404":
          $ref: "#/components/responses/NotFound"
  /v2/crypto/exchanges/liquidation/{base}-{term}:
    get:
      tags:
        - Crypto - Derivatives
      summary: Aggregate Liquidations (Cross-Exchange)
      description: |
        Recent liquidation events merged across every perps-supporting exchange,
        sorted newest-first. Long liquidations (`side=sell`) and short
        liquidations (`side=buy`) are summarised at the top — counts, total
        notional value, share, and the dominant side.

        Use it as the cross-exchange replacement for the per-exchange liquidation
        endpoint when you want a single feed rather than 13 separate ones.
      operationId: getV2CryptoExchangesLiquidationByPair
      security:
        - BearerAuth:
            - crypto:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/BaseParam"
        - $ref: "#/components/parameters/TermParam"
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            default: 50
            minimum: 1
            maximum: 500
      responses:
        "200":
          description: Aggregated liquidation feed
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/LiquidationAggregateResponse"
        "404":
          $ref: "#/components/responses/NotFound"
  /v2/crypto/analytics/live/liquidation-heatmap/{base}-{term}:
    get:
      tags:
        - Crypto Analytics
      summary: Liquidation Heatmap (Bucketed by Price)
      description: |
        Recent liquidation events bucketed by price level (configurable basis-point
        bucket width, default 25bps). Each bucket reports long-liquidation notional,
        short-liquidation notional, and event count. Useful for visualising
        "liquidation walls" relative to mid-price.
      operationId: getV2CryptoAnalyticsLiveLiquidationHeatmapByPair
      security:
        - BearerAuth:
            - crypto:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/BaseParam"
        - $ref: "#/components/parameters/TermParam"
        - name: bucket_bps
          in: query
          required: false
          schema:
            type: integer
            default: 25
            minimum: 1
            maximum: 500
          description: Bucket width in basis points relative to derived mid-price
      responses:
        "200":
          description: Liquidation heatmap
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/LiquidationHeatmapResponse"
        "404":
          $ref: "#/components/responses/NotFound"
  /v2/crypto/analytics/live/derivatives-sentiment/{base}:
    get:
      tags:
        - Crypto Analytics
      summary: Derivatives Sentiment Composite
      description: |
        Single -100 to +100 score representing positioning in the derivatives market
        for an asset. Today's components: average funding rate (across exchanges,
        for {BASE}/USDT) and recent liquidation imbalance (long vs short).

        Labels: `extreme_bullish` (≥60), `bullish` (≥25), `neutral`, `bearish`
        (≤-25), `extreme_bearish` (≤-60). Higher absolute value can flag
        contrarian extremes.

        **MVP note:** rolling baselines (funding vs 30d avg, OI vs 30d avg, basis
        vs historical) require ClickHouse archival and will be wired in next.
      operationId: getV2CryptoAnalyticsLiveDerivativesSentimentByBase
      security:
        - BearerAuth:
            - crypto:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/BaseParam"
      responses:
        "200":
          description: Derivatives sentiment composite
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DerivativesSentimentResponse"
        "404":
          $ref: "#/components/responses/NotFound"
  /v2/crypto/analytics/live/funding-arb/{base}-{term}:
    get:
      tags:
        - Crypto Analytics
      summary: Funding-Rate Arbitrage Scanner
      description: |
        Finds the highest and lowest funding rate for a perps pair across exchanges
        and reports the implied annualised carry pickup from shorting the
        high-funding venue and longing the low-funding venue.

        APR ignores fees, borrow costs, and exchange-specific liquidation rules —
        use it as a discovery feed rather than a P&L estimate.
      operationId: getV2CryptoAnalyticsLiveFundingArbByPair
      security:
        - BearerAuth:
            - crypto:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/BaseParam"
        - $ref: "#/components/parameters/TermParam"
      responses:
        "200":
          description: Funding-rate arbitrage scan
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/FundingArbResponse"
        "404":
          $ref: "#/components/responses/NotFound"
  /v2/crypto/indices/live/rwa:
    get:
      tags:
        - Crypto - Indices
      summary: RWA / Tokenized-Asset Sector Index
      description: |
        Equal-weighted and volume-weighted 24h percent change across a curated
        basket of Real-World Asset (RWA) tokens — ONDO, OM, POLYX, MKR, RWA, CFG,
        GFI, PENDLE, USDM, USDY, TRU, MPL, MAPLE.

        Returns the per-constituent 24h change plus a composite "sector return"
        and sentiment label. Use it as a daily snapshot for the RWA narrative.
      operationId: getV2CryptoIndicesLiveRwa
      security:
        - BearerAuth:
            - crypto:read
        - ApiKeyAuth: []
      responses:
        "200":
          description: RWA sector index snapshot
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SectorIndexResponse"
        "404":
          $ref: "#/components/responses/NotFound"
  /v2/crypto/indices/live/ai:
    get:
      tags:
        - Crypto - Indices
      summary: AI / Crypto-AI Sector Index
      description: |
        Equal-weighted and volume-weighted 24h percent change across a curated
        basket of AI / crypto-AI tokens — TAO, FET, RENDER/RNDR, AGIX, OCEAN, GRT,
        AKT, NEAR, ARKM, WLD, PAAL, AIOZ.

        Returns the per-constituent 24h change plus a composite "sector return"
        and sentiment label.
      operationId: getV2CryptoIndicesLiveAi
      security:
        - BearerAuth:
            - crypto:read
        - ApiKeyAuth: []
      responses:
        "200":
          description: AI sector index snapshot
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SectorIndexResponse"
        "404":
          $ref: "#/components/responses/NotFound"
  /v2/crypto/indices/live/risk-on-score:
    get:
      tags:
        - Crypto - Indices
      summary: Risk-On / Risk-Off Composite Score
      description: |
        Single 0-100 score representing whether the crypto market is positioned
        risk-on or risk-off right now. Composed today from BTC, ETH, and SOL 24h
        direction with confluence weighting.

        Labels: `strong_risk_on` (≥75), `risk_on` (≥60), `neutral` (40-60),
        `risk_off` (≥25), `strong_risk_off` (<25).

        **MVP note:** crypto-internal inputs only. Forex DXY/JPY and calendar
        overlay land in a follow-up.
      operationId: getV2CryptoIndicesLiveRiskOnScore
      security:
        - BearerAuth:
            - crypto:read
        - ApiKeyAuth: []
      responses:
        "200":
          description: Risk-on composite score
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/RiskOnScoreResponse"
        "404":
          $ref: "#/components/responses/NotFound"
  /v2/crypto/indices/live/macro/{base}:
    get:
      tags:
        - Crypto - Indices
      summary: Macro Dashboard (per asset)
      description: |
        Per-asset macro snapshot pairing the cross-exchange aggregated mid and 24h
        change with cross-asset context (BTC and ETH 24h direction, ratio vs BTC,
        ratio vs ETH).

        **MVP note:** crypto-internal context only today. Forex DXY/JPY/EUR side
        and calendar event overlays (FOMC, CPI) will be wired in next.
      operationId: getV2CryptoIndicesLiveMacroByBase
      security:
        - BearerAuth:
            - crypto:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/BaseParam"
      responses:
        "200":
          description: Macro snapshot
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MacroDashboardResponse"
        "404":
          $ref: "#/components/responses/NotFound"
  /v2/crypto/stablecoin/live/peg/all:
    get:
      tags:
        - Crypto - Stablecoin
      summary: Stablecoin Peg Monitor (All)
      description: |
        Snapshot of every monitored stablecoin's deviation from its peg target,
        sorted by stress score (worst first). Each entry includes the volume-weighted
        cross-exchange aggregated mid, deviation in basis points, cross-venue spread,
        and a 0-100 stress score with a label (`healthy`, `watch`, `elevated`,
        `critical`).

        Use this as the "is anything going on with stablecoins right now?" feed —
        suitable as a circuit-breaker input for DeFi protocols and a counterparty-risk
        signal for treasury managers.
      operationId: getV2CryptoStablecoinLivePegAll
      security:
        - BearerAuth:
            - crypto:read
        - ApiKeyAuth: []
      responses:
        "200":
          description: Peg snapshot for every monitored stablecoin
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/StablecoinPegAllResponse"
        "404":
          $ref: "#/components/responses/NotFound"
  /v2/crypto/stablecoin/live/peg/{symbol}:
    get:
      tags:
        - Crypto - Stablecoin
      summary: Stablecoin Peg Monitor (Single)
      description: |
        Real-time peg deviation for a single stablecoin across every exchange that
        trades it. Returns the volume-weighted aggregated mid, per-exchange
        breakdown, cross-venue spread, and a stress score 0-100. Stablecoins are
        anchored to their declared peg (USD or EUR).
      operationId: getV2CryptoStablecoinLivePegBySymbol
      security:
        - BearerAuth:
            - crypto:read
        - ApiKeyAuth: []
      parameters:
        - name: symbol
          in: path
          required: true
          schema:
            type: string
            example: USDT
          description: Stablecoin symbol (e.g. USDT, USDC, DAI, FDUSD, USDe, EURC)
      responses:
        "200":
          description: Peg snapshot
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/StablecoinPegResponse"
        "404":
          $ref: "#/components/responses/NotFound"
  /v2/crypto/stablecoin/live/dominance:
    get:
      tags:
        - Crypto - Stablecoin
      summary: Stablecoin Volume Dominance
      description: |
        Volume share of each stablecoin across our trade-pair universe. Volume is
        summed from `BASE/{stablecoin}` ticker `quoteVolume` for a curated list of
        liquid bases (BTC, ETH, SOL, BNB, XRP, DOGE, ADA, TRX) — that gives a fair
        cross-stable comparison without weighting toward any single asset.

        Use it to track regime shifts (e.g. USDT share falling, USDC rising) and
        regional preferences when combined with venue-level data.
      operationId: getV2CryptoStablecoinLiveDominance
      security:
        - BearerAuth:
            - crypto:read
        - ApiKeyAuth: []
      responses:
        "200":
          description: Stablecoin dominance snapshot
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/StablecoinDominanceResponse"
        "404":
          $ref: "#/components/responses/NotFound"
  /v2/crypto/stablecoin/live/rating:
    get:
      tags:
        - Crypto - Stablecoin
      summary: Stablecoin Risk Rating (AAA → C)
      description: |
        Letter-grade rating per stablecoin, refreshed continuously, derived from
        observable market data — peg stress, cross-venue divergence, and trade-volume
        share. Higher score (AAA) means tight peg, low cross-venue divergence, and
        meaningful share of stablecoin trade volume.

        Suitable for collateral-acceptance policies, DeFi protocol LTV tiers, and
        listing-committee scoring. This is faster and more reactive than annualised
        agency ratings (S&P, Bluechip).
      operationId: getV2CryptoStablecoinLiveRating
      security:
        - BearerAuth:
            - crypto:read
        - ApiKeyAuth: []
      responses:
        "200":
          description: Rating table
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/StablecoinRatingResponse"
        "404":
          $ref: "#/components/responses/NotFound"
  /v2/crypto/stablecoin/live/flow:
    get:
      tags:
        - Crypto - Stablecoin
      summary: Stablecoin Flow Index
      description: |
        Snapshot of where stablecoin trade volume is concentrated and which symbols
        show stress vs healthy peg. Each row is tagged `inflow_destination`,
        `outflow_pressure`, or `neutral` based on a simple heuristic combining peg
        stress and current share.

        **MVP note:** this returns a current-state snapshot. Proper time-series
        rotation tracking ("USDe lost X% share over 4h, flowed to USDC") will land
        once historical stablecoin volume is archived in ClickHouse.
      operationId: getV2CryptoStablecoinLiveFlow
      security:
        - BearerAuth:
            - crypto:read
        - ApiKeyAuth: []
      responses:
        "200":
          description: Flow snapshot
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/StablecoinFlowResponse"
        "404":
          $ref: "#/components/responses/NotFound"
  /v2/crypto/analytics/live/aggressive/{base}-{term}:
    get:
      tags:
        - Crypto Analytics
      summary: Aggressive Buy/Sell Ratio
      description: |
        Real-time taker-buy vs taker-sell volume split across all exchanges over a
        configurable window. Answers "is the market being aggressively bought or
        aggressively sold right now?".

        For each trade in the window, the side flag (`buy` / `sell`) attributes the
        notional (`cost`) to the buy or sell bucket. We sum per-exchange and globally,
        then return the ratio, percentages, and a `mood` label (`bullish`,
        `mildly_bullish`, `neutral`, `mildly_bearish`, `bearish`).

        Use it as a short-window order-flow indicator. CoinGlass and Velo sell the
        equivalent under various names ("Long/Short Buy", "Aggressive Order Flow").
      operationId: getV2CryptoAnalyticsLiveAggressiveByPair
      security:
        - BearerAuth:
            - crypto:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/BaseParam"
        - $ref: "#/components/parameters/TermParam"
        - name: window
          in: query
          required: false
          schema:
            type: string
            enum:
              - 1m
              - 5m
              - 15m
              - 30m
              - 1h
              - 4h
            default: 5m
          description: Lookback window for trade aggregation
      responses:
        "200":
          description: Aggressive volume split
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AggressiveResponse"
        "404":
          $ref: "#/components/responses/NotFound"
  /v2/crypto/analytics/live/whale/{base}-{term}:
    get:
      tags:
        - Crypto Analytics
      summary: Whale Trade Scanner
      description: |
        Scans recent trades across every exchange that trades the pair and returns
        only those whose notional (`cost = price × amount`) exceeds the `min`
        threshold. Each trade is tagged with its venue, side, taker flag, and
        timestamp; results are returned newest-first.

        The summary block reports buy/sell counts, total buy/sell notional, and the
        signed net notional — a quick read on whether whales are net buying or
        selling right now.

        Useful as a real-time large-order feed (Telegram bot, dashboard ticker) or as
        an input to a whale-flow indicator.
      operationId: getV2CryptoAnalyticsLiveWhaleByPair
      security:
        - BearerAuth:
            - crypto:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/BaseParam"
        - $ref: "#/components/parameters/TermParam"
        - name: min
          in: query
          required: false
          schema:
            type: number
            format: double
            default: 1000000
            minimum: 0
            maximum: 100000000
          description: Minimum trade notional (in quote currency, typically USD/USDT) to qualify as whale
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            default: 25
            minimum: 1
            maximum: 100
          description: Maximum number of matched trades to return
      responses:
        "200":
          description: Whale trade scan
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WhaleResponse"
        "404":
          $ref: "#/components/responses/NotFound"
  /v2/crypto/analytics/live/arbitrage/{base}-{term}:
    get:
      tags:
        - Crypto Analytics
      summary: Cross-Exchange Arbitrage Scanner
      description: |
        Finds the venue with the lowest **ask** and the venue with the highest **bid**
        for a pair across all exchanges, and reports the raw spread between them in
        basis points. A positive spread (bid > ask on different venues) indicates a
        crossed market — a candidate arbitrage opportunity, before fees and transfer
        costs.

        Also returns up to ten ranked cross-exchange `(buy, sell)` pair opportunities,
        always with different `buyExchange` and `sellExchange`.

        **Important:** the response shows raw price spread only. Real profitability
        requires subtracting taker fees on both sides, withdrawal fees, gas, and the
        risk of price drift during transfer. Treat this as a discovery feed, not an
        execution plan.
      operationId: getV2CryptoAnalyticsLiveArbitrageByPair
      security:
        - BearerAuth:
            - crypto:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/BaseParam"
        - $ref: "#/components/parameters/TermParam"
      responses:
        "200":
          description: Arbitrage scan
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ArbitrageResponse"
        "404":
          $ref: "#/components/responses/NotFound"
  /v2/crypto/analytics/live/dex-share/{base}:
    get:
      tags:
        - Crypto Analytics
      summary: DEX Share of Trading Volume
      description: |
        Reports the share of trading volume for a base asset that happens **on-chain
        via DEXes** versus on **centralised exchanges**. Both sides are anchored on
        USD-equivalent 24h volume so the comparison is apples-to-apples.

        The CEX side aggregates volume across `BASE/USD`, `BASE/USDT`, and `BASE/USDC`
        for every centralised exchange we cover, preferring `quoteVolume` (already
        USD-denominated) and falling back to `baseVolume × last` when needed. The DEX
        side uses our aggregated on-chain DEX feed for `BASE/USD`.

        Use it as a research / policy signal — secular shift of liquidity onto DEXes
        is one of the cleanest decentralisation indicators. Examples: BTC ≈ 99% CEX,
        ETH ≈ 87% CEX, UNI ≈ 41% CEX, PEPE ≈ 11% CEX.
      operationId: getV2CryptoAnalyticsLiveDexShareByBase
      security:
        - BearerAuth:
            - crypto:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/BaseParam"
      responses:
        "200":
          description: DEX share snapshot
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DexShareResponse"
        "404":
          $ref: "#/components/responses/NotFound"
  /v2/crypto/orderbook/live/depth/{base}-{term}:
    get:
      tags:
        - Crypto Order Books
      summary: Cross-Exchange Aggregated Depth
      description: |
        Total USD liquidity sitting within 1, 5, 10, 25, 50, and 100 basis points of
        the mid-price — bids and asks separately — pooled across every exchange that
        trades the pair. Plus a per-exchange breakdown so you can see who provides
        the depth.

        Use it to answer "how much can I buy/sell within X bps of mid before I move
        the market?", to set order-size policy, or to understand venue concentration
        risk.

        Mid is the global best bid / best ask. **Spread can be negative** when
        markets are crossed across exchanges — that's a real arbitrage signal, not
        an error.
      operationId: getV2CryptoOrderbookLiveDepthByPair
      security:
        - BearerAuth:
            - crypto:read
            - orderbook:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/BaseParam"
        - $ref: "#/components/parameters/TermParam"
      responses:
        "200":
          description: Aggregated depth snapshot
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AggregatedDepthResponse"
        "404":
          $ref: "#/components/responses/NotFound"
  /v2/crypto/analytics/slippage/{base}-{term}:
    post:
      tags:
        - Crypto Analytics
      summary: Slippage Estimator [NEW]
      description: |
        Pre-trade simulation: "if I market-buy $X of this asset right now, what
        average price will I get and how many bps of slippage will I pay?"

        The endpoint walks the real order book to estimate two scenarios:
        - **Smart-routed** across every exchange we track (best-case)
        - **Best single exchange** (apples-to-apples comparison)

        It then quantifies the USD savings from smart routing and shows a per-exchange
        fill breakdown so you can see exactly where the liquidity comes from.

        Use it before executing institutional-size orders, to size up trades against
        available depth, or to feed a best-execution engine. Send `side` (`buy` /
        `sell`) and `amount` (USD notional, 1–10,000,000).
      operationId: postV2CryptoAnalyticsSlippageByPair
      x-badges:
        - name: NEW
          position: after
          color: green
      security:
        - BearerAuth:
            - crypto:read
            - orderbook:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/BaseParam"
        - $ref: "#/components/parameters/TermParam"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - side
                - amount
              properties:
                side:
                  type: string
                  enum:
                    - buy
                    - sell
                  description: Order side (buy walks asks, sell walks bids)
                amount:
                  type: number
                  minimum: 1
                  maximum: 10000000
                  example: 500000
                  description: USD notional amount to simulate
                exchanges:
                  type: array
                  items:
                    type: string
                  example:
                    - binance
                    - kraken
                    - coinbase
                  description: Exchange filter (default all available)
      responses:
        "200":
          description: Slippage estimation result
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ExecutionSimulationResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "404":
          $ref: "#/components/responses/NotFound"
  /v1/crypto/assets:
    get:
      tags:
        - Crypto Assets
      summary: List Cryptocurrency Assets
      description: |
        Symbols we track, grouped by category. Backed by Redis registry sets —
        `crypto:registry:basecoin`, `:altcoin`, `:stablecoin`, `:ohlc`, `:refrate`.

        **Default response** returns all five categories at once with per-category
        sorted symbol lists, per-category counts, and the total unique symbol count
        across all categories.

        **Filter to one category** with `?type=basecoin|altcoin|stablecoin|ohlc|refrate`
        for a single sorted list, paginated via `?limit` / `?offset`.

        **Search** with `?search=BTC` to filter symbols by case-insensitive substring
        match (applies in either response shape).

        Use it to populate selectors, validate user input, or discover what's
        available before subscribing to other endpoints.
      operationId: getV1CryptoAssets
      security:
        - BearerAuth:
            - crypto:read
        - ApiKeyAuth: []
      parameters:
        - name: type
          in: query
          required: false
          schema:
            type: string
            enum:
              - basecoin
              - altcoin
              - stablecoin
              - ohlc
              - refrate
          description: Filter to a single category. When omitted, all categories are returned.
        - name: search
          in: query
          required: false
          schema:
            type: string
            example: BTC
          description: Case-insensitive substring filter on symbol
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            default: 1000
            minimum: 1
            maximum: 5000
          description: Page size. With `?type=` it caps the returned page; without `?type=` it caps each category independently.
        - name: offset
          in: query
          required: false
          schema:
            type: integer
            default: 0
            minimum: 0
          description: Pagination offset (only meaningful with `?type=`)
      responses:
        "200":
          description: |
            Two possible shapes depending on `?type=`:
              - With `?type=` → a single category page (`type`, `total`, `count`, `offset`, `limit`, `symbols`)
              - Without `?type=` → all categories (`totalUnique`, `categoryCounts`, `categories`)
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: "#/components/schemas/CryptoAssetsAllResponse"
                  - $ref: "#/components/schemas/CryptoAssetsByTypeResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
  /v1/fiat247/assets:
    get:
      tags:
        - Fiat247 Rates
      summary: List Fiat247 Assets
      description: |
        Symbols available in the 24/7 fiat universe (e.g., GBP, EUR, JPY, CHF). Backed
        by the `fiat247:registry:symbol` Redis set.

        Returns a sorted symbol list with optional `?search=` substring filter and
        `?limit` / `?offset` pagination. Use it to populate fiat selectors and
        validate input before calling rate endpoints.
      operationId: getV1Fiat247Assets
      security:
        - BearerAuth:
            - fiat247:read
        - ApiKeyAuth: []
      parameters:
        - name: search
          in: query
          required: false
          schema:
            type: string
            example: EUR
          description: Case-insensitive substring filter on symbol
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            default: 500
            minimum: 1
            maximum: 2000
        - name: offset
          in: query
          required: false
          schema:
            type: integer
            default: 0
            minimum: 0
      responses:
        "200":
          description: Sorted fiat247 symbol list
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Fiat247AssetsResponse"
  /v1/crypto/assets/{symbol}:
    get:
      tags:
        - Crypto Assets
      summary: Get Asset Details
      description: |
        Full metadata for a single asset by symbol — name, classification, and other
        descriptive fields. Use it to render asset detail pages or enrich a row in
        your UI without separate look-ups.
      operationId: getV1CryptoAssetsBySymbol
      security:
        - BearerAuth:
            - crypto:read
        - ApiKeyAuth: []
      parameters:
        - name: symbol
          in: path
          required: true
          schema:
            type: string
            example: BTC
      responses:
        "200":
          description: Asset details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CryptoAsset"
        "404":
          $ref: "#/components/responses/NotFound"
  /v1/crypto/pairs:
    get:
      tags:
        - Crypto Assets
      summary: List Trading Pairs
      description: |
        Every base/term pair we have data for, optionally filtered by `?base=`,
        `?term=`, or `?exchange=`. Use it to populate pair selectors, pre-validate
        a pair before issuing other requests, or check coverage on a specific
        exchange.
      operationId: getV1CryptoPairs
      security:
        - BearerAuth:
            - crypto:read
        - ApiKeyAuth: []
      parameters:
        - name: base
          in: query
          schema:
            type: string
        - name: term
          in: query
          schema:
            type: string
        - name: exchange
          in: query
          schema:
            type: string
        - $ref: "#/components/parameters/LimitParam"
      responses:
        "200":
          description: List of trading pairs
          content:
            application/json:
              schema:
                type: object
                properties:
                  pairs:
                    type: array
                    items:
                      $ref: "#/components/schemas/TradingPair"
  /v1/crypto/exchanges:
    get:
      tags:
        - Crypto Exchanges
      summary: List Supported Exchanges
      description: |
        Every cryptocurrency exchange we ingest data from, returned as a sorted list
        of identifiers. Use it to build exchange filters, validate the `exchange`
        path parameter on per-exchange endpoints, or display venue coverage on a
        status page.
      operationId: getV1CryptoExchanges
      security:
        - BearerAuth:
            - crypto:read
        - ApiKeyAuth: []
      responses:
        "200":
          description: Sorted list of exchange names
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string
                example:
                  - binance
                  - bithumb
                  - bybit
                  - coinbase
                  - cryptocom
                  - gate
                  - gemini
                  - htx
                  - kraken
                  - kucoin
                  - okx
                  - onetrading
                  - p2b
                  - poloniex
  /v1/crypto/exchanges/{exchange}:
    get:
      tags:
        - Crypto Exchanges
      summary: Get Exchange Detail
      description: |
        Detailed status and inventory for a single exchange — every trading pair we
        receive from it, plus health stats (uptime, ticker / trade counts, error
        counts). Use it to render an exchange detail page, audit coverage, or build
        an internal monitoring dashboard.
      operationId: getV1CryptoExchangesByExchange
      security:
        - BearerAuth:
            - crypto:read
        - ApiKeyAuth: []
      parameters:
        - name: exchange
          in: path
          required: true
          description: Exchange name (lowercase)
          schema:
            type: string
            example: binance
      responses:
        "200":
          description: Exchange detail with pods and tokens
          content:
            application/json:
              schema:
                type: object
                properties:
                  exchange:
                    type: string
                    example: binance
                  token_count:
                    type: integer
                    description: Total distinct trading pairs
                    example: 460
                  tokens:
                    type: array
                    description: Sorted list of all trading pairs
                    items:
                      type: string
                    example:
                      - BTC/USDT
                      - ETH/USDT
                      - SOL/USDT
                  total_ticker_count:
                    type: integer
                    description: Aggregated ticker updates across all pods
                    example: 921292
                  total_trade_count:
                    type: integer
                    description: Aggregated trade updates across all pods
                    example: 5609962
                  total_error_count:
                    type: integer
                    example: 0
                  pods:
                    type: array
                    description: Per-pod status and stats
                    items:
                      type: object
                      properties:
                        index:
                          type: integer
                          example: 0
                        status:
                          type: string
                          example: healthy
                        uptime:
                          type: integer
                          description: Uptime in seconds
                          example: 34920
                        market_type:
                          type: string
                          example: spot
                        updated_at:
                          type: string
                          format: date-time
                        ticker_count:
                          type: integer
                          example: 460646
                        trade_count:
                          type: integer
                          example: 2804981
                        error_count:
                          type: integer
                          example: 0
                        reconnect_count:
                          type: integer
                          example: 0
                        token_count:
                          type: integer
                          description: Tokens handled by this pod
                          example: 230
        "404":
          description: Exchange not found
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: exchange not found
                  exchange:
                    type: string
  /v2/crypto/rates/refrate/symbols:
    get:
      tags:
        - Crypto RefRate
      summary: List Available RefRate Symbols
      description: |
        Sorted list of every symbol that currently has an active reference rate
        fixing. Use it before calling the per-symbol RefRate endpoints to confirm
        coverage, or to populate a UI selector.
      operationId: getV2CryptoRatesRefrateSymbols
      security:
        - BearerAuth:
            - crypto:read
        - ApiKeyAuth: []
      responses:
        "200":
          description: Sorted list of available symbols
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string
                example:
                  - BTC-USD
                  - ETH-USD
                  - LTC-USD
                  - SOL-USD
                  - USDC-USD
  /v2/crypto/rates/refrate/{product}/{base}-{term}/latest:
    get:
      tags:
        - Crypto RefRate
      summary: Get Latest RefRate Fixing
      description: |
        The most recent **reference rate** fixing for a pair — an institutional-grade
        benchmark price derived using a documented, auditable methodology (volume-
        weighted, with outliers excluded). Three product flavours:

        - **`fix`** — discrete fixing at scheduled times (1h or end-of-day)
        - **`twap`** — Time-Weighted Average Price over a rolling window
        - **`tcut`** — trimmed-cut benchmark (extreme samples removed)

        Use a reference rate (rather than the live midrate) when you need a stable,
        defensible price for NAV calculation, derivatives settlement, regulatory
        reporting, accounting, or any process that requires a tamper-resistant mark.
      operationId: getV2CryptoRatesRefrateByProductByPairLatest
      security:
        - BearerAuth:
            - crypto:read
        - ApiKeyAuth: []
      parameters:
        - name: product
          in: path
          required: true
          schema:
            type: string
            enum:
              - fix
              - tcut
              - twap
            example: fix
        - $ref: "#/components/parameters/BaseParam"
        - $ref: "#/components/parameters/TermParam"
      responses:
        "200":
          description: Latest fixing data
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/RefRateFixing"
        "404":
          description: No data available
  /v2/crypto/rates/refrate/{product}/{base}-{term}/historic:
    get:
      tags:
        - Crypto RefRate
      summary: Get RefRate History
      description: |
        Historical reference rate fixings for a pair. Use it to audit what the
        benchmark was at any past timestamp, build a long-running history of
        institutional marks, or compare prior settlements.

        Pass `from` / `to` for a window, `limit` to cap the response. The `?t=`
        query param does an exact-time single-item lookup (kept for backward
        compatibility).
      operationId: getV2CryptoRatesRefrateByProductByPairHistory
      security:
        - BearerAuth:
            - crypto:read
        - ApiKeyAuth: []
      parameters:
        - name: product
          in: path
          required: true
          schema:
            type: string
            enum:
              - fix
              - tcut
              - twap
        - $ref: "#/components/parameters/BaseParam"
        - $ref: "#/components/parameters/TermParam"
        - $ref: "#/components/parameters/FromParam"
        - $ref: "#/components/parameters/ToParam"
        - $ref: "#/components/parameters/LimitParam"
        - name: t
          in: query
          description: Exact fixing time for single-item lookup (legacy, ISO 8601)
          schema:
            type: string
            example: "2026-03-26T23:00:00.000Z"
      responses:
        "200":
          description: Historical fixings
          content:
            application/json:
              schema:
                type: object
                properties:
                  product:
                    type: string
                  symbol:
                    type: string
                  count:
                    type: integer
                  fixings:
                    type: array
                    items:
                      $ref: "#/components/schemas/RefRateFixing"
        "404":
          description: No data for the specified symbol and product
  /v2/crypto/rates/refrate/constituent/{base}-{term}:
    get:
      tags:
        - Crypto RefRate
      summary: Get RefRate Constituent Data
      description: |
        Full audit trail for the latest reference rate fixing — every exchange that
        contributed (or was considered and excluded), with its bid, ask, volume,
        weight in the fixing, and a reason if it was excluded.

        Use it to demonstrate the methodology to an auditor, debug why a fixing came
        out the way it did, or build a transparency view inside your application.
      operationId: getV2CryptoRatesRefrateConstituentByPair
      security:
        - BearerAuth:
            - crypto:read
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/BaseParam"
        - $ref: "#/components/parameters/TermParam"
      responses:
        "200":
          description: Constituent breakdown
          content:
            application/json:
              schema:
                type: object
                properties:
                  symbol:
                    type: string
                    example: BTC-USD
                  count:
                    type: integer
                    example: 27
                  constituents:
                    type: array
                    items:
                      type: object
                      properties:
                        key:
                          type: string
                          example: binance-BTC-USDT
                        bid:
                          type: number
                        ask:
                          type: number
                        midUsd:
                          type: number
                        volume:
                          type: number
                        weight:
                          type: number
                        included:
                          type: boolean
                        reason:
                          type: string
                          nullable: true
                        fixingTime:
                          type: string
                          format: date-time
                        interval:
                          type: string
        "404":
          description: No constituent data available
  /v1/crypto/market/summary:
    get:
      tags:
        - Crypto Market
      summary: Get Market Summary
      description: |
        High-level snapshot of the entire crypto market — total tracked assets,
        aggregate volume, rough breadth indicators. Use it to render a "market at a
        glance" widget on a homepage or dashboard.
      operationId: getV1CryptoMarketSummary
      security:
        - BearerAuth:
            - crypto:read
        - ApiKeyAuth: []
      responses:
        "200":
          description: Market summary
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MarketSummary"
  /v1/crypto/market/gainers:
    get:
      tags:
        - Crypto Market
      summary: Get Top Gainers
      description: |
        The best-performing crypto assets by percentage price change over the chosen
        timeframe. Use it to drive "top movers" lists, leaderboards, or alerts that
        surface what's running today.
      operationId: getV1CryptoMarketGainers
      security:
        - BearerAuth:
            - crypto:read
        - ApiKeyAuth: []
      parameters:
        - name: timeframe
          in: query
          schema:
            type: string
            enum:
              - 1h
              - 24h
              - 7d
              - 30d
            default: 24h
        - $ref: "#/components/parameters/LimitParam"
      responses:
        "200":
          description: Top gainers
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MarketMoversResponse"
  /v1/crypto/market/losers:
    get:
      tags:
        - Crypto Market
      summary: Get Top Losers
      description: |
        The worst-performing crypto assets by percentage price change over the chosen
        timeframe. Mirror of the gainers endpoint — useful for surfacing capitulation,
        risk dashboards, or contrarian-entry watchlists.
      operationId: getV1CryptoMarketLosers
      security:
        - BearerAuth:
            - crypto:read
        - ApiKeyAuth: []
      parameters:
        - name: timeframe
          in: query
          schema:
            type: string
            enum:
              - 1h
              - 24h
              - 7d
              - 30d
            default: 24h
        - $ref: "#/components/parameters/LimitParam"
      responses:
        "200":
          description: Top losers
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MarketMoversResponse"
  /v1/crypto/market/volume:
    get:
      tags:
        - Crypto Market
      summary: Get Highest Volume Assets
      description: |
        Crypto assets ranked by trading volume over the chosen timeframe. Use it to
        identify what the market is actually trading right now (volume = real
        attention), surface "trending" lists, or pre-filter universes for analytics.
      operationId: getV1CryptoMarketVolume
      security:
        - BearerAuth:
            - crypto:read
        - ApiKeyAuth: []
      parameters:
        - name: timeframe
          in: query
          schema:
            type: string
            enum:
              - 1h
              - 24h
              - 7d
            default: 24h
        - $ref: "#/components/parameters/LimitParam"
      responses:
        "200":
          description: Highest volume assets
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/VolumeRankingResponse"
  /v1/crypto/stream/subscribe:
    post:
      tags:
        - Crypto Streaming
      summary: Subscribe to Real-Time Stream [NEW]
      description: |
        Subscribe to real-time cryptocurrency data streams via WebSocket or Server-Sent Events (SSE).

        **WebSocket URL**: `wss://api.windy.network/v1/crypto/stream/ws`

        **SSE URL**: `https://api.windy.network/v1/crypto/stream/sse`
      operationId: postV1CryptoStreamSubscribe
      x-badges:
        - name: NEW
          position: after
          color: green
      security:
        - BearerAuth:
            - crypto:read
            - stream:read
        - ApiKeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - channels
              properties:
                channels:
                  type: array
                  items:
                    type: string
                  example:
                    - ticker:BTC-USDT
                    - trades:ETH-USDT
                    - orderbook:SOL-USDT
                exchanges:
                  type: array
                  items:
                    type: string
                  example:
                    - binance
                    - coinbase
      responses:
        "200":
          description: Subscription details
          content:
            application/json:
              schema:
                type: object
                properties:
                  subscriptionId:
                    type: string
                  channels:
                    type: array
                    items:
                      type: string
                  wsUrl:
                    type: string
                    example: wss://api.windy.network/v1/crypto/stream/ws?token=xyz
                  sseUrl:
                    type: string
                    example: https://api.windy.network/v1/crypto/stream/sse?token=xyz
  /v1/stock/quote/{symbol}:
    get:
      tags:
        - Stock Rates
      summary: Get Stock Quote
      description: |
        Latest quote for a single stock — last price, bid, ask, change, and volume.
        Use for "current price" displays in trading apps, dashboards, or watchlists.
      operationId: getV1StockQuoteBySymbol
      security:
        - BearerAuth:
            - stock:read
            - rate:read
        - ApiKeyAuth: []
      parameters:
        - name: symbol
          in: path
          required: true
          schema:
            type: string
            example: AAPL
          description: Stock ticker symbol
      responses:
        "200":
          description: Stock quote
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/StockQuote"
        "404":
          $ref: "#/components/responses/NotFound"
  /v1/stock/quotes:
    get:
      tags:
        - Stock Rates
      summary: Get Multiple Stock Quotes
      description: |
        Bulk fetch quotes for many stocks in one call. Pass a comma-separated list
        of symbols (`?symbols=AAPL,GOOGL,MSFT`). Use it instead of looping over
        single-symbol calls when rendering watchlists or portfolio snapshots.
      operationId: getV1StockQuotes
      security:
        - BearerAuth:
            - stock:read
            - rate:read
        - ApiKeyAuth: []
      parameters:
        - name: symbols
          in: query
          required: true
          schema:
            type: string
            example: AAPL,GOOGL,MSFT,TSLA
          description: Comma-separated list of stock symbols
      responses:
        "200":
          description: Multiple stock quotes
          content:
            application/json:
              schema:
                type: object
                properties:
                  quotes:
                    type: array
                    items:
                      $ref: "#/components/schemas/StockQuote"
  /v1/forex/rate/{pair}:
    get:
      tags:
        - Forex Rates
      summary: Get Forex Real-time Rate
      description: |
        Live exchange rate for a forex pair. Pair format is the standard 6-letter
        symbol (e.g., `GBPUSD`, `EURUSD`, `USDJPY`).

        **HTTP GET** returns the current rate.
        **WebSocket / SSE / long-poll** at the same URL pushes every update for
        clients that need a live stream.
      operationId: getV1ForexRateByPair
      security:
        - BearerAuth:
            - forex:read
            - rate:read
        - ApiKeyAuth: []
      parameters:
        - name: pair
          in: path
          required: true
          schema:
            type: string
            example: GBPUSD
          description: Forex pair symbol (e.g., GBPUSD, EURUSD, USDJPY)
      responses:
        "200":
          description: Real-time forex rate (nchan stream)
          content:
            application/json:
              schema:
                type: object
                properties:
                  symbol:
                    type: string
                    example: GBPUSD
                  rate:
                    type: number
                    example: 1.33885
                  bid:
                    type: number
                    example: 1.33885
                  ask:
                    type: number
                    example: 1.33885
                  spread:
                    type: number
                    example: 0
                  ts:
                    type: integer
                    example: 1773081804043
                    description: Unix timestamp in milliseconds
  /v1/forex/rates:
    get:
      tags:
        - Forex Rates
      summary: Get Multiple Forex Rates
      description: |
        Bulk fetch rates for many forex pairs in one call. Pick a `base` currency
        and one or more `quotes` — the response gives you the rate of `base` against
        each. Use it to render a multi-currency price grid in a single round-trip.
      operationId: getV1ForexRates
      security:
        - BearerAuth:
            - forex:read
            - rate:read
        - ApiKeyAuth: []
      parameters:
        - name: base
          in: query
          required: true
          schema:
            type: string
            example: USD
          description: Base currency
        - name: quotes
          in: query
          schema:
            type: string
            example: EUR,GBP,JPY,CHF
          description: Comma-separated term currencies
      responses:
        "200":
          description: Multiple forex rates
          content:
            application/json:
              schema:
                type: object
                properties:
                  base:
                    type: string
                  rates:
                    type: object
                    additionalProperties:
                      type: number
  /v1/forex/ohlc/{timeframe}/{pair}:
    get:
      tags:
        - Forex OHLC
      summary: Get Forex OHLC Candles
      description: |
        Candlestick data (open, high, low, close) for a forex pair at the timeframe
        of your choice. Pair format is the 6-letter symbol (e.g., `GBPUSD`).
        Use for charts and technical analysis.
      operationId: getV1ForexOhlcByPair
      security:
        - BearerAuth:
            - forex:read
            - ohlc:read
        - ApiKeyAuth: []
      parameters:
        - name: timeframe
          in: path
          required: true
          schema:
            type: string
            enum:
              - m1
              - m5
              - m15
              - m30
              - h1
              - h4
              - d1
              - w1
              - mo1
            example: h1
          description: Candle timeframe
        - name: pair
          in: path
          required: true
          schema:
            type: string
            example: GBPUSD
          description: Forex pair symbol
        - name: from
          in: query
          schema:
            type: string
            example: now-7d
          description: Start timestamp (ISO 8601, relative, or Unix)
        - name: to
          in: query
          schema:
            type: string
            example: now
          description: End timestamp
        - name: limit
          in: query
          schema:
            type: integer
            default: 168
            maximum: 1000
          description: Maximum candles to return
      responses:
        "200":
          description: OHLC candle data
          content:
            application/json:
              schema:
                type: object
                properties:
                  type:
                    type: string
                    example: forex
                  pair:
                    type: string
                    example: GBPUSD
                  symbol:
                    type: string
                    example: GBPUSD
                  timeframe:
                    type: string
                    example: h1
                  count:
                    type: integer
                  candles:
                    type: array
                    items:
                      $ref: "#/components/schemas/OHLCCandle"
  /v1/forex/indicator/sma/{timeframe}/{window}/{pair}:
    get:
      tags:
        - Forex Indicators
      summary: Forex SMA
      description: |
        Simple Moving Average for a forex pair — unweighted average of the close
        over the last `window` candles. Smooths short-term noise and reveals the
        underlying trend. Common windows: 20 / 50 / 200.
      operationId: getV1ForexIndicatorSmaByPair
      security:
        - BearerAuth:
            - forex:read
            - indicators:read
        - ApiKeyAuth: []
      parameters:
        - name: timeframe
          in: path
          required: true
          schema:
            type: string
            enum:
              - m1
              - m5
              - m15
              - m30
              - h1
              - h4
              - d1
              - w1
              - mo1
        - name: window
          in: path
          required: true
          schema:
            type: integer
            enum:
              - 5
              - 7
              - 9
              - 10
              - 12
              - 14
              - 20
              - 21
              - 25
              - 26
              - 50
              - 100
              - 200
        - name: pair
          in: path
          required: true
          schema:
            type: string
            example: GBPUSD
        - name: from
          in: query
          schema:
            type: string
        - name: to
          in: query
          schema:
            type: string
        - name: limit
          in: query
          schema:
            type: integer
            default: 100
      responses:
        "200":
          description: SMA values
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/IndicatorResponse"
  /v1/forex/indicator/ema/{timeframe}/{window}/{pair}:
    get:
      tags:
        - Forex Indicators
      summary: Forex EMA
      description: |
        Exponential Moving Average for a forex pair — like SMA but weights recent
        prices more heavily, so it reacts faster to changes. Preferred for short-term
        trend signals.
      operationId: getV1ForexIndicatorEmaByPair
      security:
        - BearerAuth:
            - forex:read
            - indicators:read
        - ApiKeyAuth: []
      parameters:
        - name: timeframe
          in: path
          required: true
          schema:
            type: string
            enum:
              - m1
              - m5
              - m15
              - m30
              - h1
              - h4
              - d1
              - w1
              - mo1
        - name: window
          in: path
          required: true
          schema:
            type: integer
            enum:
              - 5
              - 7
              - 9
              - 10
              - 12
              - 14
              - 20
              - 21
              - 25
              - 26
              - 50
              - 100
              - 200
        - name: pair
          in: path
          required: true
          schema:
            type: string
            example: GBPUSD
        - name: from
          in: query
          schema:
            type: string
        - name: to
          in: query
          schema:
            type: string
        - name: limit
          in: query
          schema:
            type: integer
            default: 100
      responses:
        "200":
          description: EMA values
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/IndicatorResponse"
  /v1/forex/indicator/rsi/{timeframe}/{window}/{pair}:
    get:
      tags:
        - Forex Indicators
      summary: Forex RSI
      description: |
        RSI (0–100 momentum oscillator) for a forex pair. Above 70 = overbought,
        below 30 = oversold. Common window: 14. Useful for entry timing and
        divergence detection.
      operationId: getV1ForexIndicatorRsiByPair
      security:
        - BearerAuth:
            - forex:read
            - indicators:read
        - ApiKeyAuth: []
      parameters:
        - name: timeframe
          in: path
          required: true
          schema:
            type: string
            enum:
              - m1
              - m5
              - m15
              - m30
              - h1
              - h4
              - d1
              - w1
              - mo1
        - name: window
          in: path
          required: true
          schema:
            type: integer
            enum:
              - 5
              - 7
              - 9
              - 10
              - 12
              - 14
              - 20
              - 21
              - 25
              - 26
              - 50
              - 100
              - 200
        - name: pair
          in: path
          required: true
          schema:
            type: string
            example: GBPUSD
        - name: from
          in: query
          schema:
            type: string
        - name: to
          in: query
          schema:
            type: string
        - name: limit
          in: query
          schema:
            type: integer
            default: 100
      responses:
        "200":
          description: RSI values
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/IndicatorResponse"
  /v1/forex/indicator/macd/{timeframe}/{pair}:
    get:
      tags:
        - Forex Indicators
      summary: Forex MACD
      description: |
        MACD for a forex pair — measures momentum via the gap between a fast and slow
        EMA. Crossovers between MACD and signal flag changes in trend direction.
        Defaults: 12 / 26 / 9.
      operationId: getV1ForexIndicatorMacdByPair
      security:
        - BearerAuth:
            - forex:read
            - indicators:read
        - ApiKeyAuth: []
      parameters:
        - name: timeframe
          in: path
          required: true
          schema:
            type: string
            enum:
              - m1
              - m5
              - m15
              - m30
              - h1
              - h4
              - d1
              - w1
              - mo1
        - name: pair
          in: path
          required: true
          schema:
            type: string
            example: GBPUSD
        - name: fast
          in: query
          schema:
            type: integer
            default: 12
        - name: slow
          in: query
          schema:
            type: integer
            default: 26
        - name: signal
          in: query
          schema:
            type: integer
            default: 9
        - name: from
          in: query
          schema:
            type: string
        - name: to
          in: query
          schema:
            type: string
        - name: limit
          in: query
          schema:
            type: integer
            default: 100
      responses:
        "200":
          description: MACD values
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MACDResponse"
  /v1/forex/indicator/bbands/{timeframe}/{window}/{pair}:
    get:
      tags:
        - Forex Indicators
      summary: Forex Bollinger Bands
      description: |
        Bollinger Bands for a forex pair. The bands wrap a moving average at a
        configurable standard-deviation distance, widening on high volatility and
        tightening on low volatility. A "squeeze" often precedes a breakout.
        Defaults: 20-period SMA, 2 standard deviations.
      operationId: getV1ForexIndicatorBbandsByPair
      security:
        - BearerAuth:
            - forex:read
            - indicators:read
        - ApiKeyAuth: []
      parameters:
        - name: timeframe
          in: path
          required: true
          schema:
            type: string
            enum:
              - m1
              - m5
              - m15
              - m30
              - h1
              - h4
              - d1
              - w1
              - mo1
        - name: window
          in: path
          required: true
          schema:
            type: integer
            enum:
              - 5
              - 7
              - 9
              - 10
              - 12
              - 14
              - 20
              - 21
              - 25
              - 26
              - 50
              - 100
              - 200
        - name: pair
          in: path
          required: true
          schema:
            type: string
            example: GBPUSD
        - name: stddev
          in: query
          schema:
            type: number
            default: 2
        - name: from
          in: query
          schema:
            type: string
        - name: to
          in: query
          schema:
            type: string
        - name: limit
          in: query
          schema:
            type: integer
            default: 100
      responses:
        "200":
          description: Bollinger Bands values
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/BBandsResponse"
  /v1/option/chain/{underlying}:
    get:
      tags:
        - Option Rates
      summary: Get Option Chain
      description: |
        Option chain for an underlying asset — every strike and expiry available,
        with bid, ask, last, volume, and open interest. Filter by `?expiration=` to
        focus on a single expiry. Use it to render option grids, build strategy
        builders, or screen for unusual activity.
      operationId: getV1OptionChainByUnderlying
      security:
        - BearerAuth:
            - option:read
        - ApiKeyAuth: []
      parameters:
        - name: underlying
          in: path
          required: true
          schema:
            type: string
            example: AAPL
        - name: expiration
          in: query
          schema:
            type: string
            format: date
            example: "2024-12-20"
      responses:
        "200":
          description: Option chain
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OptionChain"
  /v1/user/alerts:
    get:
      tags:
        - User Alerts
      summary: List Price Alerts
      description: |
        Every price alert configured for the authenticated user — the symbol it
        watches, the trigger condition, and whether it's active. Use it to populate
        the user's "my alerts" screen.
      operationId: getV1UserAlerts
      security:
        - BearerAuth:
            - alerts:read
      responses:
        "200":
          description: List of alerts
          content:
            application/json:
              schema:
                type: object
                properties:
                  alerts:
                    type: array
                    items:
                      $ref: "#/components/schemas/PriceAlert"
    post:
      tags:
        - User Alerts
      summary: Create Price Alert
      description: |
        Create a price alert for the authenticated user. The alert fires when the
        configured condition is met — e.g., BTC-USD crosses above $100,000.
      operationId: postV1UserAlerts
      security:
        - BearerAuth:
            - alerts:write
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateAlertRequest"
      responses:
        "201":
          description: Alert created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PriceAlert"
  /v1/user/alerts/{alertId}:
    get:
      tags:
        - User Alerts
      summary: Get Alert Details
      description: Get details of a specific price alert
      operationId: getV1UserAlertsByAlertId
      security:
        - BearerAuth:
            - alerts:read
      parameters:
        - name: alertId
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: Alert details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PriceAlert"
        "404":
          $ref: "#/components/responses/NotFound"
    delete:
      tags:
        - User Alerts
      summary: Delete Price Alert
      description: Delete a price alert
      operationId: deleteV1UserAlertsByAlertId
      security:
        - BearerAuth:
            - alerts:write
      parameters:
        - name: alertId
          in: path
          required: true
          schema:
            type: string
      responses:
        "204":
          description: Alert deleted
        "404":
          $ref: "#/components/responses/NotFound"
  /v1/user/watchlists:
    get:
      tags:
        - User Watchlist
      summary: List Watchlists
      description: |
        Every watchlist owned by the authenticated user. Use it to render the user's
        list of saved asset collections.
      operationId: getV1UserWatchlists
      security:
        - BearerAuth:
            - watchlist:read
      responses:
        "200":
          description: List of watchlists
          content:
            application/json:
              schema:
                type: object
                properties:
                  watchlists:
                    type: array
                    items:
                      $ref: "#/components/schemas/Watchlist"
    post:
      tags:
        - User Watchlist
      summary: Create Watchlist
      description: Create a new watchlist
      operationId: postV1UserWatchlists
      security:
        - BearerAuth:
            - watchlist:write
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - name
              properties:
                name:
                  type: string
                  example: My Crypto Portfolio
                description:
                  type: string
      responses:
        "201":
          description: Watchlist created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Watchlist"
  /v1/user/watchlists/{watchlistId}:
    get:
      tags:
        - User Watchlist
      summary: Get Watchlist
      description: Get details of a specific watchlist
      operationId: getV1UserWatchlistsByWatchlistId
      security:
        - BearerAuth:
            - watchlist:read
      parameters:
        - name: watchlistId
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: Watchlist details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Watchlist"
        "404":
          $ref: "#/components/responses/NotFound"
    put:
      tags:
        - User Watchlist
      summary: Update Watchlist
      description: Update watchlist name or description
      operationId: putV1UserWatchlistsByWatchlistId
      security:
        - BearerAuth:
            - watchlist:write
      parameters:
        - name: watchlistId
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                description:
                  type: string
      responses:
        "200":
          description: Watchlist updated
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Watchlist"
    delete:
      tags:
        - User Watchlist
      summary: Delete Watchlist
      description: Delete a watchlist
      operationId: deleteV1UserWatchlistsByWatchlistId
      security:
        - BearerAuth:
            - watchlist:write
      parameters:
        - name: watchlistId
          in: path
          required: true
          schema:
            type: string
      responses:
        "204":
          description: Watchlist deleted
  /v1/user/watchlists/{watchlistId}/items:
    post:
      tags:
        - User Watchlist
      summary: Add Item to Watchlist
      description: Add an asset to a watchlist
      operationId: postV1UserWatchlistsByWatchlistIdItems
      security:
        - BearerAuth:
            - watchlist:write
      parameters:
        - name: watchlistId
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - symbol
                - assetType
              properties:
                symbol:
                  type: string
                  example: BTC
                assetType:
                  type: string
                  enum:
                    - crypto
                    - stock
                    - forex
                    - option
      responses:
        "201":
          description: Item added
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Watchlist"
  /v1/user/watchlists/{watchlistId}/items/{symbol}:
    delete:
      tags:
        - User Watchlist
      summary: Remove Item from Watchlist
      description: Remove an asset from a watchlist
      operationId: deleteV1UserWatchlistsByWatchlistIdItemsBySymbol
      security:
        - BearerAuth:
            - watchlist:write
      parameters:
        - name: watchlistId
          in: path
          required: true
          schema:
            type: string
        - name: symbol
          in: path
          required: true
          schema:
            type: string
      responses:
        "204":
          description: Item removed
  /v1/user/portfolio:
    get:
      tags:
        - User Portfolio
      summary: Get Portfolio
      description: |
        The authenticated user's portfolio — every holding, valued at current market
        prices, with totals and high-level performance. Use it to render the
        portfolio overview screen.
      operationId: getV1UserPortfolio
      security:
        - BearerAuth:
            - portfolio:read
      responses:
        "200":
          description: Portfolio details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Portfolio"
  /v1/user/portfolio/holdings:
    get:
      tags:
        - User Portfolio
      summary: List Holdings
      description: Get all holdings in the portfolio
      operationId: getV1UserPortfolioHoldings
      security:
        - BearerAuth:
            - portfolio:read
      responses:
        "200":
          description: List of holdings
          content:
            application/json:
              schema:
                type: object
                properties:
                  holdings:
                    type: array
                    items:
                      $ref: "#/components/schemas/Holding"
    post:
      tags:
        - User Portfolio
      summary: Add Holding
      description: Add a new holding to the portfolio
      operationId: postV1UserPortfolioHoldings
      security:
        - BearerAuth:
            - portfolio:write
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AddHoldingRequest"
      responses:
        "201":
          description: Holding added
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Holding"
  /v1/user/portfolio/holdings/{holdingId}:
    put:
      tags:
        - User Portfolio
      summary: Update Holding
      description: Update a portfolio holding
      operationId: putV1UserPortfolioHoldingsByHoldingId
      security:
        - BearerAuth:
            - portfolio:write
      parameters:
        - name: holdingId
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                quantity:
                  type: number
                averagePrice:
                  type: number
      responses:
        "200":
          description: Holding updated
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Holding"
    delete:
      tags:
        - User Portfolio
      summary: Remove Holding
      description: Remove a holding from the portfolio
      operationId: deleteV1UserPortfolioHoldingsByHoldingId
      security:
        - BearerAuth:
            - portfolio:write
      parameters:
        - name: holdingId
          in: path
          required: true
          schema:
            type: string
      responses:
        "204":
          description: Holding removed
  /v1/user/portfolio/performance:
    get:
      tags:
        - User Portfolio
      summary: Get Portfolio Performance
      description: |
        Performance metrics for the user's portfolio over a chosen period — total
        return, P&L, drawdowns, and per-asset contribution. Use it to power
        performance dashboards and statements.
      operationId: getV1UserPortfolioPerformance
      security:
        - BearerAuth:
            - portfolio:read
      parameters:
        - name: period
          in: query
          schema:
            type: string
            enum:
              - 1d
              - 1w
              - 1m
              - 3m
              - 1y
              - all
            default: 1m
      responses:
        "200":
          description: Portfolio performance
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PortfolioPerformance"
  /v1/health:
    get:
      tags:
        - System
      summary: Health Check
      description: Basic health check endpoint
      operationId: getV1Health
      security: []
      responses:
        "200":
          description: Service is healthy
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: healthy
                  timestamp:
                    type: integer
                    format: int64
                    example: 1701234567890
  /v1/status:
    get:
      tags:
        - System
      summary: System Status
      description: Detailed system status and component health
      operationId: getV1Status
      security: []
      responses:
        "200":
          description: System status
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SystemStatus"
  /v1/stats:
    get:
      tags:
        - System
      summary: API Statistics
      description: API usage statistics and metrics
      operationId: getV1Stats
      security:
        - BearerAuth:
            - admin:read
      responses:
        "200":
          description: API statistics
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiStats"
  /v1/ping:
    get:
      tags:
        - System
      summary: Ping
      description: Simple ping endpoint for connectivity testing
      operationId: getV1Ping
      security: []
      responses:
        "200":
          description: Pong
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    example: pong
  /v1/time:
    get:
      tags:
        - System
      summary: Server Time
      description: Get current server time
      operationId: getV1Time
      security: []
      responses:
        "200":
          description: Server time
          content:
            application/json:
              schema:
                type: object
                properties:
                  timestamp:
                    type: integer
                    format: int64
                    example: 1701234567890
                  iso:
                    type: string
                    format: date-time
                    example: "2023-11-29T10:22:47.890Z"
  /v1/version:
    get:
      tags:
        - System
      summary: API Version
      description: Get API version information
      operationId: getV1Version
      security: []
      responses:
        "200":
          description: Version information
          content:
            application/json:
              schema:
                type: object
                properties:
                  version:
                    type: string
                    example: 1.0.0
                  apiVersion:
                    type: string
                    example: v1
                  buildDate:
                    type: string
                    example: "2023-11-29"
  /v1/crypto/stream/ws:
    get:
      tags:
        - OpenServer
      summary: WebSocket Stream (Public)
      description: |
        Connect to public WebSocket stream for real-time crypto rate updates.
        No authentication required.

        **Server**: `wss://openserver.windy.network`

        **Channel Format**:
        - `stablecoin:{SYMBOL}` - e.g., `stablecoin:USDT`
        - `basecoin:{SYMBOL}` - e.g., `basecoin:BTC`

        **Example**: `wss://openserver.windy.network/v1/crypto/stream/ws?channels=stablecoin:USDT,basecoin:BTC`
      operationId: getV1CryptoStreamWs
      security: []
      servers:
        - url: wss://openserver.windy.network
          description: OpenServer WebSocket
      parameters:
        - name: channels
          in: query
          required: true
          schema:
            type: string
            example: stablecoin:USDT,basecoin:BTC
          description: Comma-separated list of channels to subscribe
      responses:
        "101":
          description: WebSocket connection established
  /v1/crypto/stream/sse:
    get:
      tags:
        - OpenServer
      summary: SSE Stream (Public)
      description: |
        Connect to public Server-Sent Events stream for real-time crypto rate updates.
        No authentication required.

        **Server**: `https://openserver.windy.network`

        **Channel Format**:
        - `stablecoin:{SYMBOL}` - e.g., `stablecoin:USDT`
        - `basecoin:{SYMBOL}` - e.g., `basecoin:BTC`

        **Example**: `https://openserver.windy.network/v1/crypto/stream/sse?channels=stablecoin:USDT,basecoin:BTC`
      operationId: getV1CryptoStreamSse
      security: []
      servers:
        - url: https://openserver.windy.network
          description: OpenServer SSE
      parameters:
        - name: channels
          in: query
          required: true
          schema:
            type: string
            example: stablecoin:USDT,basecoin:BTC
          description: Comma-separated list of channels to subscribe
      responses:
        "200":
          description: SSE stream connected
          content:
            text/event-stream:
              schema:
                type: string
                example: "data: {\"symbol\":\"USDT\",\"rate\":1.0001,\"timestamp\":1701234567890}"
  /v1/crypto/stream/poll:
    get:
      tags:
        - OpenServer
      summary: Long-Polling (Public)
      description: |
        HTTP long-polling endpoint for crypto rate updates.
        No authentication required. Updates every 10 seconds.

        **Server**: `https://openserver.windy.network`
      operationId: getV1CryptoStreamPoll
      security: []
      servers:
        - url: https://openserver.windy.network
          description: OpenServer HTTP
      parameters:
        - name: channels
          in: query
          required: true
          schema:
            type: string
            example: stablecoin:USDT
          description: Comma-separated list of channels
      responses:
        "200":
          description: Rate data
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/RateResponse"
  /v1/calendar/status:
    get:
      tags:
        - Market Calendar
      summary: Get Full Market Calendar Status
      description: |
        Get real-time status of all forex sessions and stock exchanges.
        Includes DST-aware times, active sessions, and next session changes.
      operationId: getV1CalendarStatus
      security:
        - BearerAuth:
            - calendar:read
        - ApiKeyAuth: []
      responses:
        "200":
          description: Current market calendar status
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MarketCalendarStatus"
  /v1/calendar/forex/sessions:
    get:
      tags:
        - Market Calendar
      summary: Get All Forex Sessions Status
      description: Get status of all forex trading sessions (Sydney, Tokyo, London, New York)
      operationId: getV1CalendarForexSessions
      security:
        - BearerAuth:
            - calendar:read
        - ApiKeyAuth: []
      responses:
        "200":
          description: All forex session statuses
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AllForexSessionsResponse"
  /v1/calendar/forex/sessions/{session}:
    get:
      tags:
        - Market Calendar
      summary: Get Forex Session Status
      description: Get detailed status for a specific forex session
      operationId: getV1CalendarForexSessionsBySession
      security:
        - BearerAuth:
            - calendar:read
        - ApiKeyAuth: []
      parameters:
        - name: session
          in: path
          required: true
          schema:
            type: string
            enum:
              - sydney
              - tokyo
              - london
              - new_york
          description: Forex session name
      responses:
        "200":
          description: Forex session status
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ForexSessionStatus"
        "404":
          $ref: "#/components/responses/NotFound"
  /v1/calendar/forex/sessions/{session}/schedule:
    get:
      tags:
        - Market Calendar
      summary: Get Forex Session Schedule
      description: Get weekly schedule with DST information for a forex session
      operationId: getV1CalendarForexSessionsBySessionSchedule
      security:
        - BearerAuth:
            - calendar:read
        - ApiKeyAuth: []
      parameters:
        - name: session
          in: path
          required: true
          schema:
            type: string
            enum:
              - sydney
              - tokyo
              - london
              - new_york
      responses:
        "200":
          description: Session schedule
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ForexSchedule"
        "404":
          $ref: "#/components/responses/NotFound"
  /v1/calendar/exchanges:
    get:
      tags:
        - Market Calendar
      summary: Get All Exchange Statuses
      description: Get status of all supported stock exchanges
      operationId: getV1CalendarExchanges
      security:
        - BearerAuth:
            - calendar:read
        - ApiKeyAuth: []
      responses:
        "200":
          description: All exchange statuses
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AllExchangesResponse"
  /v1/calendar/exchanges/{exchange}:
    get:
      tags:
        - Market Calendar
      summary: Get Exchange Status
      description: Get detailed status for a specific stock exchange
      operationId: getV1CalendarExchangesByExchange
      security:
        - BearerAuth:
            - calendar:read
        - ApiKeyAuth: []
      parameters:
        - name: exchange
          in: path
          required: true
          schema:
            type: string
            enum:
              - NYSE
              - NASDAQ
              - LSE
              - TSE
              - ASX
              - HKEX
              - SSE
              - SZSE
              - BSE
              - NSE
              - EURONEXT
              - XETRA
              - SGX
              - KRX
              - TWSE
          description: Stock exchange code
      responses:
        "200":
          description: Exchange status
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/StockExchangeStatus"
        "404":
          $ref: "#/components/responses/NotFound"
  /v1/calendar/exchanges/{exchange}/schedule:
    get:
      tags:
        - Market Calendar
      summary: Get Exchange Schedule
      description: Get trading schedule including upcoming trading days and holidays
      operationId: getV1CalendarExchangesByExchangeSchedule
      security:
        - BearerAuth:
            - calendar:read
        - ApiKeyAuth: []
      parameters:
        - name: exchange
          in: path
          required: true
          schema:
            type: string
        - name: days
          in: query
          schema:
            type: integer
            default: 7
            minimum: 1
            maximum: 30
          description: Number of days to include in schedule
      responses:
        "200":
          description: Exchange schedule
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ExchangeSchedule"
        "404":
          $ref: "#/components/responses/NotFound"
  /v1/calendar/holidays/{countryCode}:
    get:
      tags:
        - Market Calendar
      summary: Get Country Holidays
      description: |
        Get bank holidays for a country (199+ countries supported).
        Uses ISO 3166-1 alpha-2 country codes.
      operationId: getV1CalendarHolidaysByCountryCode
      security:
        - BearerAuth:
            - calendar:read
        - ApiKeyAuth: []
      parameters:
        - name: countryCode
          in: path
          required: true
          schema:
            type: string
            pattern: ^[A-Z]{2}$
            example: US
          description: ISO 3166-1 alpha-2 country code
        - name: year
          in: query
          schema:
            type: integer
            example: 2025
          description: Year for holidays (default current year)
        - name: type
          in: query
          schema:
            type: string
            enum:
              - all
              - public
              - bank
            default: all
          description: Filter by holiday type
      responses:
        "200":
          description: Country holidays
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CountryHolidays"
        "404":
          $ref: "#/components/responses/NotFound"
  /v1/calendar/holidays/markets:
    get:
      tags:
        - Market Calendar
      summary: Get Market Holidays
      description: Get holidays affecting specific markets/exchanges in a date range
      operationId: getV1CalendarHolidaysMarkets
      security:
        - BearerAuth:
            - calendar:read
        - ApiKeyAuth: []
      parameters:
        - name: exchanges
          in: query
          schema:
            type: string
            example: NYSE,LSE,TSE
          description: Comma-separated exchange codes
        - name: from
          in: query
          required: true
          schema:
            type: string
            format: date
            example: "2025-01-01"
          description: Start date (YYYY-MM-DD)
        - name: to
          in: query
          required: true
          schema:
            type: string
            format: date
            example: "2025-12-31"
          description: End date (YYYY-MM-DD)
      responses:
        "200":
          description: Market holidays
          content:
            application/json:
              schema:
                type: object
                properties:
                  holidays:
                    type: array
                    items:
                      $ref: "#/components/schemas/MarketHoliday"
  /v2/dex/rates/live/midrate/{base}-{term}:
    get:
      tags:
        - DEX Midrate
      summary: DEX Aggregated Weighted Midrate
      description: |
        Aggregated weighted mid-price for a token derived from on-chain decentralised
        exchanges (Uniswap, Curve, Balancer, etc.). Pools are weighted across fee
        tiers by liquidity and smoothed to filter noise from thinly-traded pairs.

        Use it for tokens that don't trade meaningfully on centralised exchanges, to
        cross-check CEX prices against on-chain liquidity, or to feed DeFi-native
        applications.

        **HTTP GET** returns the latest midrate.
        **WebSocket** (`wss://api.windy.network/v2/dex/rates/live/midrate/{base}-{term}`) pushes
        every update.
      operationId: getV2DexRatesLiveMidrateByPair
      security:
        - BearerAuth:
            - dex:read
            - rate:read
        - ApiKeyAuth: []
      parameters:
        - name: base
          in: path
          required: true
          schema:
            type: string
            example: ETH
          description: Base token symbol (e.g., ETH, BTC, LINK)
        - name: term
          in: path
          required: true
          schema:
            type: string
            example: USD
          description: Term currency (currently only USD)
      responses:
        "200":
          description: DEX midrate
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DexMidrateResponse"
        "404":
          $ref: "#/components/responses/NotFound"
components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: OAuth 2.0 Bearer token (JWT)
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
      description: API Key for simple authentication
  parameters:
    ExchangeParam:
      name: exchange
      in: path
      required: true
      schema:
        type: string
        example: binance
      description: Exchange identifier (e.g., binance, coinbase, kraken)
    BaseParam:
      name: base
      in: path
      required: true
      schema:
        type: string
        example: BTC
      description: Base currency symbol (crypto)
    FiatBaseParam:
      name: base
      in: path
      required: true
      schema:
        type: string
        example: GBP
      description: Base fiat currency symbol (e.g., GBP, EUR, JPY)
    Fiat247BaseParam:
      name: base
      in: path
      required: true
      schema:
        type: string
        example: GBP
      description: Fiat currency symbol (e.g., GBP, EUR, JPY)
    Fiat247TermParam:
      name: term
      in: path
      required: true
      schema:
        type: string
        example: USD
      description: Term currency (pricing currency)
    TermParam:
      name: term
      in: path
      required: true
      schema:
        type: string
        example: USD
      description: Term currency (pricing currency, also known as quote currency)
    TimeframeParam:
      name: timeframe
      in: path
      required: true
      schema:
        type: string
        enum:
          - m1
          - m5
          - m15
          - m30
          - h1
          - h4
          - d1
          - w1
          - mo1
        example: h1
      description: Timeframe for data aggregation
    LimitParam:
      name: limit
      in: query
      schema:
        type: integer
        minimum: 1
        maximum: 1000
        default: 100
        example: 100
      description: Maximum number of results to return
    TimestampFromParam:
      name: from
      in: query
      schema:
        type: integer
        format: int64
        example: 1701000000000
      description: Start timestamp in milliseconds
    TimestampToParam:
      name: to
      in: query
      schema:
        type: integer
        format: int64
        example: 1701234567890
      description: End timestamp in milliseconds
    ClientIdParam:
      name: clientId
      in: path
      required: true
      schema:
        type: string
      description: OAuth client ID
    WindowParam:
      name: window
      in: path
      required: true
      schema:
        type: integer
        enum:
          - 5
          - 7
          - 9
          - 10
          - 12
          - 14
          - 20
          - 21
          - 25
          - 26
          - 50
          - 100
          - 200
        example: 20
      description: Moving average window/period size
    FromParam:
      name: from
      in: query
      schema:
        type: string
        example: now-7d
      description: |
        Start timestamp. Supports multiple formats:
        - Relative: `now`, `now-1d`, `now-7d`, `now-30d`
        - Unix timestamp (seconds or milliseconds): `1705312200`, `1705312200000`
        - ISO 8601: `2024-01-15T09:30:00Z`
        - Date only: `2024-01-15`
    ToParam:
      name: to
      in: query
      schema:
        type: string
        example: now
      description: |
        End timestamp. Supports same formats as `from` parameter.
        Defaults to current time if not specified.
    ExpandUnderlyingParam:
      name: expand_underlying
      in: query
      schema:
        type: boolean
        default: false
        example: false
      description: Include raw OHLC candles used for indicator calculation
    TimestampFormatParam:
      name: timestamp_format
      in: query
      schema:
        type: string
        enum:
          - unix
          - iso
        default: unix
        example: unix
      description: |
        Timestamp format in response:
        - `unix` (default): Millisecond timestamps (e.g., 1705312200000)
        - `iso`: ISO 8601 format (e.g., "2024-01-15T09:30:00Z")
  responses:
    BadRequest:
      description: Bad request - invalid parameters
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
    Unauthorized:
      description: Unauthorized - invalid or missing authentication
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
    Forbidden:
      description: Forbidden - insufficient permissions
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
    NotFound:
      description: Resource not found
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
    RateLimitExceeded:
      description: Rate limit exceeded
      headers:
        X-RateLimit-Limit:
          schema:
            type: integer
          description: Request limit per time window
        X-RateLimit-Remaining:
          schema:
            type: integer
          description: Remaining requests in current window
        X-RateLimit-Reset:
          schema:
            type: integer
            format: int64
          description: Timestamp when rate limit resets
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
  schemas:
    ClientCredentialsGrant:
      type: object
      required:
        - grant_type
        - client_id
        - client_secret
      properties:
        grant_type:
          type: string
          enum:
            - client_credentials
        client_id:
          type: string
        client_secret:
          type: string
        scope:
          type: string
          example: crypto:read stock:read
    AuthorizationCodeGrant:
      type: object
      required:
        - grant_type
        - code
        - redirect_uri
        - client_id
      properties:
        grant_type:
          type: string
          enum:
            - authorization_code
        code:
          type: string
        redirect_uri:
          type: string
          format: uri
        client_id:
          type: string
        client_secret:
          type: string
    RefreshTokenGrant:
      type: object
      required:
        - grant_type
        - refresh_token
      properties:
        grant_type:
          type: string
          enum:
            - refresh_token
        refresh_token:
          type: string
        client_id:
          type: string
        client_secret:
          type: string
        scope:
          type: string
    PasswordGrant:
      type: object
      required:
        - grant_type
        - username
        - password
      properties:
        grant_type:
          type: string
          enum:
            - password
        username:
          type: string
        password:
          type: string
          format: password
        client_id:
          type: string
        scope:
          type: string
    TokenResponse:
      type: object
      required:
        - access_token
        - token_type
        - expires_in
      properties:
        access_token:
          type: string
          description: JWT access token
        token_type:
          type: string
          example: Bearer
        expires_in:
          type: integer
          description: Token lifetime in seconds
          example: 3600
        refresh_token:
          type: string
          description: Refresh token (optional)
        scope:
          type: string
          description: Granted scopes
          example: crypto:read stock:read
    OAuth2Error:
      type: object
      required:
        - error
      properties:
        error:
          type: string
          enum:
            - invalid_request
            - invalid_client
            - invalid_grant
            - unauthorized_client
            - unsupported_grant_type
            - invalid_scope
        error_description:
          type: string
        error_uri:
          type: string
          format: uri
    TokenIntrospection:
      type: object
      required:
        - active
      properties:
        active:
          type: boolean
          description: Whether the token is active
        scope:
          type: string
        client_id:
          type: string
        username:
          type: string
        token_type:
          type: string
        exp:
          type: integer
          format: int64
          description: Expiration timestamp
        iat:
          type: integer
          format: int64
          description: Issued at timestamp
        sub:
          type: string
          description: Subject (user ID)
    UserInfo:
      type: object
      properties:
        sub:
          type: string
          description: User ID
        email:
          type: string
          format: email
        email_verified:
          type: boolean
        name:
          type: string
        given_name:
          type: string
        family_name:
          type: string
        picture:
          type: string
          format: uri
    OAuth2Metadata:
      type: object
      properties:
        issuer:
          type: string
          format: uri
        authorization_endpoint:
          type: string
          format: uri
        token_endpoint:
          type: string
          format: uri
        revocation_endpoint:
          type: string
          format: uri
        introspection_endpoint:
          type: string
          format: uri
        userinfo_endpoint:
          type: string
          format: uri
        jwks_uri:
          type: string
          format: uri
        grant_types_supported:
          type: array
          items:
            type: string
        response_types_supported:
          type: array
          items:
            type: string
        scopes_supported:
          type: array
          items:
            type: string
    OpenIDConfiguration:
      allOf:
        - $ref: "#/components/schemas/OAuth2Metadata"
        - type: object
          properties:
            id_token_signing_alg_values_supported:
              type: array
              items:
                type: string
    JWKS:
      type: object
      properties:
        keys:
          type: array
          items:
            type: object
            properties:
              kty:
                type: string
              use:
                type: string
              kid:
                type: string
              alg:
                type: string
              "n":
                type: string
              e:
                type: string
    ClientRegistration:
      type: object
      required:
        - client_name
        - redirect_uris
      properties:
        client_name:
          type: string
        redirect_uris:
          type: array
          items:
            type: string
            format: uri
        grant_types:
          type: array
          items:
            type: string
          default:
            - authorization_code
            - refresh_token
        response_types:
          type: array
          items:
            type: string
          default:
            - code
        scope:
          type: string
        token_endpoint_auth_method:
          type: string
          enum:
            - client_secret_basic
            - client_secret_post
            - none
          default: client_secret_basic
    ClientInformation:
      allOf:
        - $ref: "#/components/schemas/ClientRegistration"
        - type: object
          properties:
            client_id:
              type: string
            client_secret:
              type: string
            client_id_issued_at:
              type: integer
              format: int64
            client_secret_expires_at:
              type: integer
              format: int64
    ApiKey:
      type: object
      properties:
        id:
          type: string
          example: key_abc123xyz
        name:
          type: string
          example: Production Server Key
        prefix:
          type: string
          example: wn_prod_
          description: First few characters of the key for identification
        scopes:
          type: array
          items:
            type: string
          example:
            - crypto:read
            - stock:read
        createdAt:
          type: string
          format: date-time
        expiresAt:
          type: string
          format: date-time
          nullable: true
        lastUsedAt:
          type: string
          format: date-time
          nullable: true
    ApiKeyWithSecret:
      allOf:
        - $ref: "#/components/schemas/ApiKey"
        - type: object
          required:
            - secret
          properties:
            secret:
              type: string
              description: Full API key (shown only once during creation)
              example: wn_prod_abcdefghijklmnopqrstuvwxyz123456
    ApiKeyUsage:
      type: object
      properties:
        keyId:
          type: string
        period:
          type: string
        totalRequests:
          type: integer
        requestsByEndpoint:
          type: object
          additionalProperties:
            type: integer
        requestsByDay:
          type: array
          items:
            type: object
            properties:
              date:
                type: string
                format: date
              count:
                type: integer
    DexMidrateResponse:
      type: object
      description: DEX aggregate midrate with average and best execution prices derived from on-chain pool fee tiers
      properties:
        mid:
          type: number
          format: double
          example: 1990.158
          description: Aggregate midrate in USD (weighted median across DEX pools, adaptive EMA smoothed)
        avgBuy:
          type: number
          format: double
          example: 1990.655
          description: Mid + half of weighted average fee spread across all contributing pools (market quality indicator)
        avgSell:
          type: number
          format: double
          example: 1989.661
          description: Mid - half of weighted average fee spread (aggregate market sell price)
        bestBuy:
          type: number
          format: double
          example: 1990.408
          description: Mid + half of tightest pool fee (best execution via smart routing)
        bestSell:
          type: number
          format: double
          example: 1989.908
          description: Mid - half of tightest pool fee (best achievable sell price)
        symbol:
          type: string
          example: ETH/USD
          description: Token pair symbol
        ts:
          type: integer
          format: int64
          example: 1774862182356
          description: Unix timestamp in milliseconds
        vol:
          type: number
          format: double
          example: 245000000
          description: >-
            Aggregate 24h trading volume in USD across all DEX pools contributing to this midrate. Updated every 15
            minutes from GeckoTerminal.
    RateResponse:
      type: object
      properties:
        token:
          type: string
          example: BTC
        term:
          type: string
          example: USD
        rate:
          type: number
          format: double
          example: 95000
        timestamp:
          type: integer
          format: int64
          example: 1701234567890
        sources:
          type: array
          items:
            type: string
          example:
            - binance
            - coinbase
            - kraken
        dataPoints:
          type: integer
          example: 5
          description: Number of data points used in calculation
    Fiat247RateResponse:
      type: object
      required:
        - symbol
        - rate
      properties:
        symbol:
          type: string
          example: GBP/USD
          description: Currency pair symbol
        rate:
          type: number
          format: double
          example: 1.3588
        bid:
          type: number
          format: double
          example: 1.3585
        ask:
          type: number
          format: double
          example: 1.359
        vol:
          type: number
          format: double
          example: 0
          description: Volume
        ts:
          type: integer
          format: int64
          example: 1770571785425
          description: Timestamp in milliseconds
        ts_iso:
          type: string
          format: date-time
          example: "2026-02-08T17:29:45.425Z"
          description: ISO 8601 timestamp (optional, may not always be available)
    PairRateResponse:
      type: object
      properties:
        base:
          type: string
          example: BTC
        term:
          type: string
          example: USD
        rate:
          type: number
          format: double
          example: 95000
        timestamp:
          type: integer
          format: int64
        bid:
          type: number
          format: double
        ask:
          type: number
          format: double
        spread:
          type: number
          format: double
    HistoricalRate:
      type: object
      properties:
        timestamp:
          type: integer
          format: int64
        rate:
          type: number
          format: double
    TickerResponse:
      type: object
      properties:
        symbol:
          type: string
          example: BTC/USDT
        exchange:
          type: string
          example: binance
        timestamp:
          type: integer
          format: int64
        datetime:
          type: string
          format: date-time
        high:
          type: number
          format: double
        low:
          type: number
          format: double
        bid:
          type: number
          format: double
        bidVolume:
          type: number
          format: double
        ask:
          type: number
          format: double
        askVolume:
          type: number
          format: double
        vwap:
          type: number
          format: double
        open:
          type: number
          format: double
        close:
          type: number
          format: double
        last:
          type: number
          format: double
        previousClose:
          type: number
          format: double
        change:
          type: number
          format: double
        percentage:
          type: number
          format: double
        baseVolume:
          type: number
          format: double
        quoteVolume:
          type: number
          format: double
    AggregatedTickerResponse:
      type: object
      properties:
        symbol:
          type: string
        exchanges:
          type: object
          additionalProperties:
            $ref: "#/components/schemas/TickerResponse"
        summary:
          type: object
          properties:
            avgPrice:
              type: number
              format: double
            highestBid:
              type: number
              format: double
            lowestAsk:
              type: number
              format: double
            totalVolume:
              type: number
              format: double
    OrderBookLevel:
      type: array
      description: Order book price level — `[price, amount]`
      minItems: 2
      maxItems: 2
      items:
        type: number
        format: double
      example:
        - 87400.5
        - 1.234
    AggregatedOrderBookLevel:
      type: array
      description: |
        Aggregated price level — `[price, total_amount, [exchanges]]`.
        Exchanges sorted by amount contributed (highest first).
      minItems: 3
      maxItems: 3
      example:
        - 87400.5
        - 2.345
        - - binance
          - kraken
    OrderBookResponse:
      type: object
      description: Per-exchange order book snapshot read on-demand from Redis
      properties:
        exchange:
          type: string
          example: binance
        symbol:
          type: string
          example: BTC/USDT
        base:
          type: string
          example: BTC
        term:
          type: string
          example: USDT
        timestamp:
          type: integer
          format: int64
          description: Last update timestamp from the exchange (Unix ms)
          example: 1778163535840
        nonce:
          type: integer
          format: int64
          nullable: true
          description: Exchange-supplied update sequence (when available)
        best_bid:
          type: number
          format: double
          example: 87400.5
        best_ask:
          type: number
          format: double
          example: 87401
        best_bid_amount:
          type: number
          format: double
          nullable: true
        best_ask_amount:
          type: number
          format: double
          nullable: true
        depth:
          type: integer
          description: Total levels available in the underlying sorted set (may exceed `?depth` cap)
          example: 114
        bids:
          type: array
          description: Bid levels ordered highest price first
          items:
            $ref: "#/components/schemas/OrderBookLevel"
        asks:
          type: array
          description: Ask levels ordered lowest price first
          items:
            $ref: "#/components/schemas/OrderBookLevel"
    AggregatedOrderBookResponse:
      type: object
      description: Order book aggregated across all exchanges trading a given pair
      properties:
        symbol:
          type: string
          example: BTC/USDT
        base:
          type: string
          example: BTC
        term:
          type: string
          example: USDT
        best_bid:
          type: number
          format: double
          nullable: true
          description: Highest bid across all exchanges
          example: 87400.5
        best_ask:
          type: number
          format: double
          nullable: true
          description: Lowest ask across all exchanges
          example: 87401
        spread:
          type: number
          format: double
          nullable: true
          description: |
            `best_ask - best_bid` in term currency.
            **Can be negative** if markets are crossed (cross-exchange arbitrage opportunity).
          example: 0.5
        spread_bps:
          type: number
          format: double
          nullable: true
          description: Spread in basis points (negative = crossed market)
          example: 0.057
        exchangeCount:
          type: integer
          description: Number of exchanges contributing data
          example: 12
        exchanges:
          type: array
          description: Exchanges contributing to this aggregated book (sorted alphabetically)
          items:
            type: string
          example:
            - binance
            - coinbase
            - kraken
        timestamp:
          type: integer
          format: int64
          nullable: true
          description: Newest meta timestamp across exchanges (Unix ms)
          example: 1778163535840
        bids:
          type: array
          description: Aggregated bid levels — highest price first
          items:
            $ref: "#/components/schemas/AggregatedOrderBookLevel"
        asks:
          type: array
          description: Aggregated ask levels — lowest price first
          items:
            $ref: "#/components/schemas/AggregatedOrderBookLevel"
    LiquidityScoreResponse:
      type: object
      properties:
        symbol:
          type: string
          example: BTC/USDT
        score:
          type: integer
          minimum: 0
          maximum: 100
          example: 94
          description: "Liquidity score (0-100): depth at 10bps (0-80pts log-scaled) + spread tightness (0-20pts)"
        rating:
          type: string
          enum:
            - Excellent
            - Good
            - Moderate
            - Thin
            - Very Thin
          example: Excellent
          description: 80-100 Excellent, 60-79 Good, 40-59 Moderate, 20-39 Thin, 0-19 Very Thin
        depth:
          type: object
          description: USD depth at each bps threshold
          properties:
            1bps:
              $ref: "#/components/schemas/LiquidityDepthBucket"
            5bps:
              $ref: "#/components/schemas/LiquidityDepthBucket"
            10bps:
              $ref: "#/components/schemas/LiquidityDepthBucket"
            50bps:
              $ref: "#/components/schemas/LiquidityDepthBucket"
        spread:
          type: object
          properties:
            absolute:
              type: number
              format: double
            bps:
              type: number
              format: double
        exchangeCount:
          type: integer
          example: 25
        midPrice:
          type: number
          format: double
        timestamp:
          type: integer
          format: int64
    LiquidityDepthBucket:
      type: object
      properties:
        bids:
          type: number
          format: double
          description: Bid-side USD depth within threshold
        asks:
          type: number
          format: double
          description: Ask-side USD depth within threshold
        total:
          type: number
          format: double
          description: Combined bid + ask depth
    SpreadExchangeRow:
      type: object
      properties:
        exchange:
          type: string
          example: binance
        bid:
          type: number
          format: double
          example: 87399.4
        ask:
          type: number
          format: double
          example: 87400
        mid:
          type: number
          format: double
          example: 87399.7
        spread:
          type: number
          format: double
          description: Absolute spread (ask - bid) in quote currency
          example: 0.6
        spreadBps:
          type: number
          format: double
          description: Spread in basis points = (ask - bid) / mid × 10000
          example: 0.0687
        timestamp:
          type: integer
          format: int64
          description: Exchange-reported ticker timestamp (ms since epoch)
    SpreadResponse:
      type: object
      properties:
        symbol:
          type: string
          example: BTC/USDT
        count:
          type: integer
          description: Number of exchanges with valid bid/ask data
          example: 24
        summary:
          type: object
          properties:
            tightestExchange:
              type: string
              example: binance
            tightestBps:
              type: number
              format: double
              example: 0.0687
            widestExchange:
              type: string
              example: p2b
            widestBps:
              type: number
              format: double
              example: 28.4
            averageBps:
              type: number
              format: double
            medianBps:
              type: number
              format: double
        exchanges:
          type: array
          description: Per-exchange bid/ask snapshot, ranked tightest first
          items:
            $ref: "#/components/schemas/SpreadExchangeRow"
    ExchangeComparisonResponse:
      type: object
      properties:
        base:
          type: string
        rowCount:
          type: integer
        freshCount:
          type: integer
          description: Rows with last update under 60 seconds old
        totalVolumeUsd:
          type: number
          format: double
        sampledQuotes:
          type: array
          items:
            type: string
          example:
            - USD
            - USDT
            - USDC
            - EUR
        rows:
          type: array
          items:
            type: object
            properties:
              exchange:
                type: string
              pair:
                type: string
              quote:
                type: string
              last:
                type: number
                format: double
                nullable: true
              mid:
                type: number
                format: double
                nullable: true
              bid:
                type: number
                format: double
                nullable: true
              ask:
                type: number
                format: double
                nullable: true
              spreadBps:
                type: number
                format: double
                nullable: true
              change24hPercent:
                type: number
                format: double
                nullable: true
              volumeUsd:
                type: number
                format: double
                nullable: true
              baseVolume:
                type: number
                format: double
                nullable: true
              timestamp:
                type: integer
                format: int64
                nullable: true
              ageSeconds:
                type: number
                format: double
                nullable: true
              fresh:
                type: boolean
    AuditMidrateResponse:
      type: object
      properties:
        symbol:
          type: string
        requestedTs:
          type: string
        archivedTimestamp:
          type: string
          description: Timestamp of the archived row used (may differ from requested if backfilled)
        rate:
          type: number
          format: double
        bid:
          type: number
          format: double
          nullable: true
        ask:
          type: number
          format: double
          nullable: true
        volume:
          type: number
          format: double
          nullable: true
        dataPoints:
          type: integer
          description: Number of constituent exchange data points contributing to the aggregate
        methodology:
          type: object
          properties:
            method:
              type: string
              example: cross_exchange_volume_weighted
            description:
              type: string
            constituentField:
              type: string
            archivePipeline:
              type: string
            version:
              type: string
    FundingAggregateResponse:
      type: object
      properties:
        symbol:
          type: string
        exchangeCount:
          type: integer
        summary:
          type: object
          properties:
            avgFundingRate:
              type: number
              format: double
            avgApr:
              type: number
              format: double
              description: Annualised, assuming 8h funding intervals (rate × 3 × 365 × 100)
            positiveCount:
              type: integer
            negativeCount:
              type: integer
            highestExchange:
              type: string
            highestFundingRate:
              type: number
              format: double
            lowestExchange:
              type: string
            lowestFundingRate:
              type: number
              format: double
            spread:
              type: number
              format: double
        exchanges:
          type: array
          items:
            type: object
            properties:
              exchange:
                type: string
              fundingRate:
                type: number
                format: double
              fundingRatePercent:
                type: number
                format: double
              apr:
                type: number
                format: double
              nextFundingRate:
                type: number
                format: double
                nullable: true
              nextFundingTimestamp:
                type: integer
                format: int64
                nullable: true
              markPrice:
                type: number
                format: double
                nullable: true
              indexPrice:
                type: number
                format: double
                nullable: true
              timestamp:
                type: integer
                format: int64
                nullable: true
    OpenInterestAggregateResponse:
      type: object
      properties:
        symbol:
          type: string
        exchangeCount:
          type: integer
        totalOpenInterestAmount:
          type: number
          format: double
        totalOpenInterestValue:
          type: number
          format: double
        summary:
          type: object
          properties:
            largestExchange:
              type: string
            largestSharePercent:
              type: number
              format: double
              nullable: true
        exchanges:
          type: array
          items:
            type: object
            properties:
              exchange:
                type: string
              openInterestAmount:
                type: number
                format: double
                nullable: true
              openInterestValue:
                type: number
                format: double
                nullable: true
              timestamp:
                type: integer
                format: int64
                nullable: true
    LiquidationAggregateResponse:
      type: object
      properties:
        symbol:
          type: string
        exchangeCount:
          type: integer
        totalEvents:
          type: integer
        returned:
          type: integer
        summary:
          type: object
          properties:
            longLiquidationsCount:
              type: integer
            shortLiquidationsCount:
              type: integer
            longLiquidationsValue:
              type: number
              format: double
            shortLiquidationsValue:
              type: number
              format: double
            totalValue:
              type: number
              format: double
            longShare:
              type: number
              format: double
              nullable: true
            shortShare:
              type: number
              format: double
              nullable: true
            dominantSide:
              type: string
              enum:
                - long
                - short
                - balanced
        events:
          type: array
          items:
            type: object
            additionalProperties: true
    LiquidationHeatmapResponse:
      type: object
      properties:
        symbol:
          type: string
        midPrice:
          type: number
          format: double
        bucketBps:
          type: integer
        bucketSize:
          type: number
          format: double
        sampleEvents:
          type: integer
        buckets:
          type: array
          items:
            type: object
            properties:
              priceLow:
                type: number
                format: double
              priceHigh:
                type: number
                format: double
              offsetBps:
                type: integer
              longLiquidationsValue:
                type: number
                format: double
              shortLiquidationsValue:
                type: number
                format: double
              totalValue:
                type: number
                format: double
              count:
                type: integer
    DerivativesSentimentResponse:
      type: object
      properties:
        base:
          type: string
        score:
          type: number
          format: double
          example: 32
        label:
          type: string
          enum:
            - extreme_bullish
            - bullish
            - neutral
            - bearish
            - extreme_bearish
        components:
          type: array
          items:
            type: object
            properties:
              name:
                type: string
              weight:
                type: number
                format: double
              contribution:
                type: number
                format: double
              raw:
                type: number
                format: double
        inputs:
          type: object
          properties:
            avgFunding:
              type: number
              format: double
              nullable: true
            fundingExchangeCount:
              type: integer
            totalOpenInterest:
              type: number
              format: double
            oiExchangeCount:
              type: integer
            longLiquidationsValue:
              type: number
              format: double
            shortLiquidationsValue:
              type: number
              format: double
        note:
          type: string
    FundingArbResponse:
      type: object
      properties:
        symbol:
          type: string
        exchangeCount:
          type: integer
        best:
          type: object
          properties:
            shortExchange:
              type: string
            shortFundingRate:
              type: number
              format: double
            longExchange:
              type: string
            longFundingRate:
              type: number
              format: double
            spread:
              type: number
              format: double
            aprPickupPercent:
              type: number
              format: double
        rates:
          type: array
          items:
            type: object
            properties:
              exchange:
                type: string
              fundingRate:
                type: number
                format: double
              apr:
                type: number
                format: double
              timestamp:
                type: integer
                format: int64
                nullable: true
        note:
          type: string
    SectorIndexResponse:
      type: object
      properties:
        sector:
          type: string
          example: rwa
        sectorName:
          type: string
          example: RWA / Tokenized Real-World Assets
        constituentCount:
          type: integer
          example: 11
        constituentsRequested:
          type: integer
          example: 13
        index:
          type: object
          properties:
            equalWeighted24hPercent:
              type: number
              format: double
              example: 2.4
            volWeighted24hPercent:
              type: number
              format: double
              nullable: true
              example: 1.8
            sentiment:
              type: string
              enum:
                - strong_bullish
                - bullish
                - neutral
                - bearish
                - strong_bearish
        constituents:
          type: array
          items:
            type: object
            properties:
              base:
                type: string
              quote:
                type: string
              avgPercent:
                type: number
                format: double
              volWeightedPercent:
                type: number
                format: double
                nullable: true
              lastPrice:
                type: number
                format: double
                nullable: true
              volumeUsd:
                type: number
                format: double
              exchangeCount:
                type: integer
    RiskOnScoreResponse:
      type: object
      properties:
        score:
          type: number
          format: double
          example: 64
        label:
          type: string
          enum:
            - strong_risk_on
            - risk_on
            - neutral
            - risk_off
            - strong_risk_off
        components:
          type: array
          items:
            type: object
            properties:
              name:
                type: string
              rawValue:
                type: number
                format: double
              weight:
                type: number
                format: double
              contribution:
                type: number
                format: double
        note:
          type: string
    MacroDashboardResponse:
      type: object
      properties:
        base:
          type: string
        quote:
          type: string
        snapshot:
          type: object
          properties:
            mid:
              type: number
              format: double
            avg24hPercent:
              type: number
              format: double
            volumeUsd:
              type: number
              format: double
            exchangeCount:
              type: integer
        crossAsset:
          type: object
          properties:
            ratioVsBtc:
              type: number
              format: double
              nullable: true
            ratioVsEth:
              type: number
              format: double
              nullable: true
            btc24hPercent:
              type: number
              format: double
              nullable: true
            eth24hPercent:
              type: number
              format: double
              nullable: true
        note:
          type: string
    StablecoinPegRow:
      type: object
      properties:
        symbol:
          type: string
          example: USDT
        peg:
          type: string
          example: USD
        target:
          type: number
          format: double
          example: 1
        aggregatedMid:
          type: number
          format: double
          example: 0.9998
        deviationBps:
          type: number
          format: double
          example: -2
        deviationPercent:
          type: number
          format: double
          example: -0.02
        crossVenueSpreadBps:
          type: number
          format: double
          example: 38
        weighting:
          type: string
          enum:
            - volume-weighted
            - equal-weighted
        stressScore:
          type: number
          format: double
          description: 0 (healthy) to 100 (critical)
          example: 12
        stressLabel:
          type: string
          enum:
            - healthy
            - watch
            - elevated
            - critical
        exchangeCount:
          type: integer
          example: 18
        exchanges:
          type: array
          items:
            type: object
            properties:
              exchange:
                type: string
              mid:
                type: number
                format: double
              deviationBps:
                type: number
                format: double
              volume:
                type: number
                format: double
                nullable: true
    StablecoinPegResponse:
      $ref: "#/components/schemas/StablecoinPegRow"
    StablecoinPegAllResponse:
      type: object
      properties:
        count:
          type: integer
        worstStressSymbol:
          type: string
          nullable: true
        worstStressScore:
          type: number
          format: double
        stablecoins:
          type: array
          items:
            $ref: "#/components/schemas/StablecoinPegRow"
    StablecoinDominanceResponse:
      type: object
      properties:
        sampledBases:
          type: array
          items:
            type: string
          example:
            - BTC
            - ETH
            - SOL
            - BNB
            - XRP
            - DOGE
            - ADA
            - TRX
        totalVolumeUsd:
          type: number
          format: double
        leader:
          type: string
          nullable: true
          example: USDT
        stablecoins:
          type: array
          items:
            type: object
            properties:
              symbol:
                type: string
              volumeUsd:
                type: number
                format: double
              sharePercent:
                type: number
                format: double
              perBase:
                type: object
                additionalProperties:
                  type: number
                  format: double
    StablecoinRatingResponse:
      type: object
      properties:
        count:
          type: integer
        methodology:
          type: string
        ratings:
          type: array
          items:
            type: object
            properties:
              symbol:
                type: string
              rating:
                type: string
                enum:
                  - AAA
                  - AA
                  - A
                  - BBB
                  - BB
                  - B
                  - C
              ratingScore:
                type: number
                format: double
                description: 0-100
              pegMid:
                type: number
                format: double
              deviationBps:
                type: number
                format: double
              crossVenueSpreadBps:
                type: number
                format: double
              stressScore:
                type: number
                format: double
              volumeSharePercent:
                type: number
                format: double
    StablecoinFlowResponse:
      type: object
      properties:
        note:
          type: string
        totalVolumeUsd:
          type: number
          format: double
        stablecoins:
          type: array
          items:
            type: object
            properties:
              symbol:
                type: string
              volumeUsd:
                type: number
                format: double
              sharePercent:
                type: number
                format: double
              stressScore:
                type: number
                format: double
                nullable: true
              deviationBps:
                type: number
                format: double
                nullable: true
              flowDirection:
                type: string
                enum:
                  - inflow_destination
                  - outflow_pressure
                  - neutral
    AggressiveResponse:
      type: object
      properties:
        symbol:
          type: string
          example: BTC/USDT
        window:
          type: string
          example: 5m
        windowMs:
          type: integer
          example: 300000
        scannedExchanges:
          type: integer
        contributingExchanges:
          type: integer
          description: Exchanges that had at least one trade in the window
        summary:
          type: object
          properties:
            buyNotional:
              type: number
              format: double
            sellNotional:
              type: number
              format: double
            buyCount:
              type: integer
            sellCount:
              type: integer
            buyPercent:
              type: number
              format: double
              example: 67
            sellPercent:
              type: number
              format: double
              example: 33
            buySellRatio:
              type: number
              format: double
              nullable: true
              example: 2.03
            mood:
              type: string
              enum:
                - bullish
                - mildly_bullish
                - neutral
                - mildly_bearish
                - bearish
              example: bullish
        exchanges:
          type: array
          items:
            type: object
            properties:
              exchange:
                type: string
              buyNotional:
                type: number
                format: double
              sellNotional:
                type: number
                format: double
              buyCount:
                type: integer
              sellCount:
                type: integer
              buyPercent:
                type: number
                format: double
              sellPercent:
                type: number
                format: double
    WhaleResponse:
      type: object
      properties:
        symbol:
          type: string
          example: BTC/USDT
        minNotional:
          type: number
          format: double
          example: 1000000
        scannedExchanges:
          type: integer
          example: 24
        totalMatches:
          type: integer
          example: 47
        returned:
          type: integer
          example: 25
        summary:
          type: object
          properties:
            buyCount:
              type: integer
            sellCount:
              type: integer
            buyNotional:
              type: number
              format: double
            sellNotional:
              type: number
              format: double
            netNotional:
              type: number
              format: double
              description: buyNotional - sellNotional
            netSide:
              type: string
              enum:
                - buy
                - sell
                - neutral
        trades:
          type: array
          items:
            type: object
            properties:
              exchange:
                type: string
              timestamp:
                type: integer
                format: int64
              datetime:
                type: string
                nullable: true
              side:
                type: string
                enum:
                  - buy
                  - sell
              price:
                type: number
                format: double
              amount:
                type: number
                format: double
              cost:
                type: number
                format: double
              takerOrMaker:
                type: string
                nullable: true
    ArbitrageResponse:
      type: object
      properties:
        symbol:
          type: string
          example: BTC/USDT
        exchangeCount:
          type: integer
          example: 24
        best:
          type: object
          properties:
            buyExchange:
              type: string
              description: Exchange with the lowest ask
              example: kraken
            buyAsk:
              type: number
              format: double
              example: 87401.5
            sellExchange:
              type: string
              description: Exchange with the highest bid
              example: upbit
            sellBid:
              type: number
              format: double
              example: 87478.2
            spread:
              type: number
              format: double
              description: sellBid - buyAsk (positive = arb candidate)
              example: 76.7
            spreadBps:
              type: number
              format: double
              example: 8.77
            spreadPercent:
              type: number
              format: double
              example: 0.088
            profitable:
              type: boolean
              description: True if buy and sell exchanges differ and spread > 0
              example: true
        opportunities:
          type: array
          description: Up to 10 cross-exchange (buy, sell) pairs ranked by spreadBps
          items:
            type: object
            properties:
              buyExchange:
                type: string
              buyAsk:
                type: number
                format: double
              sellExchange:
                type: string
              sellBid:
                type: number
                format: double
              spread:
                type: number
                format: double
              spreadBps:
                type: number
                format: double
              spreadPercent:
                type: number
                format: double
        note:
          type: string
          example: Raw spread only — fees, withdrawal costs, and transfer-time risk are not modelled.
    DexShareResponse:
      type: object
      properties:
        base:
          type: string
          example: ETH
        cexVolumeUsd:
          type: number
          format: double
          description: Combined USD-denominated 24h volume across CEXes for BASE/USD,USDT,USDC
          example: 8210000000
        dexVolumeUsd:
          type: number
          format: double
          description: 24h on-chain DEX volume in USD for BASE
          example: 1230000000
        combinedVolumeUsd:
          type: number
          format: double
          example: 9440000000
        cexSharePercent:
          type: number
          format: double
          example: 86.97
        dexSharePercent:
          type: number
          format: double
          example: 13.03
        cexExchangeCount:
          type: integer
          example: 24
        breakdown:
          type: object
          properties:
            cexUsd:
              type: number
              format: double
            cexUsdt:
              type: number
              format: double
            cexUsdc:
              type: number
              format: double
    PremiumResponse:
      type: object
      properties:
        symbol:
          type: string
          example: BTC/USDT
        count:
          type: integer
          example: 24
        globalMid:
          type: number
          format: double
          example: 87412.3
        weighting:
          type: string
          enum:
            - volume-weighted
            - equal-weighted
          example: volume-weighted
        summary:
          type: object
          properties:
            highestExchange:
              type: string
              example: upbit
            highestPremiumBps:
              type: number
              format: double
              example: 78.4
            lowestExchange:
              type: string
              example: p2b
            lowestPremiumBps:
              type: number
              format: double
              example: -32.1
            spreadBps:
              type: number
              format: double
              example: 110.5
        exchanges:
          type: array
          description: Per-exchange premium rows, sorted highest premium first
          items:
            type: object
            properties:
              exchange:
                type: string
                example: upbit
              mid:
                type: number
                format: double
              bid:
                type: number
                format: double
                nullable: true
              ask:
                type: number
                format: double
                nullable: true
              volume:
                type: number
                format: double
                nullable: true
              premiumBps:
                type: number
                format: double
              premiumPercent:
                type: number
                format: double
              timestamp:
                type: integer
                format: int64
                nullable: true
    CexDexPremiumResponse:
      type: object
      properties:
        symbol:
          type: string
          example: ETH/USD
        cex:
          type: object
          nullable: true
          description: Aggregated CEX side snapshot. Null if no CEX data.
          properties:
            mid:
              type: number
              format: double
              example: 3485.4
            bid:
              type: number
              format: double
              nullable: true
            ask:
              type: number
              format: double
              nullable: true
            volume:
              type: number
              format: double
              nullable: true
            timestamp:
              type: integer
              format: int64
              description: Unix epoch milliseconds
              nullable: true
        dex:
          type: object
          nullable: true
          description: Aggregated on-chain DEX snapshot. Null if no DEX data.
          properties:
            mid:
              type: number
              format: double
              example: 3491.2
            avgBuy:
              type: number
              format: double
              nullable: true
            avgSell:
              type: number
              format: double
              nullable: true
            bestBuy:
              type: number
              format: double
              nullable: true
            bestSell:
              type: number
              format: double
              nullable: true
            volume:
              type: number
              format: double
              nullable: true
            timestamp:
              type: integer
              format: int64
              nullable: true
        premium:
          type: object
          nullable: true
          description: Delta DEX vs CEX. Null when one side is missing.
          properties:
            absolute:
              type: number
              format: double
              description: dex.mid - cex.mid in price units
              example: 5.8
            bps:
              type: number
              format: double
              description: Premium in basis points (positive = DEX higher)
              example: 16.6
            percent:
              type: number
              format: double
              example: 0.166
            higherSide:
              type: string
              enum:
                - cex
                - dex
                - neutral
              example: dex
        warning:
          type: string
          nullable: true
          description: Set when one side is missing — e.g. "dex midrate missing".
    SessionBucket:
      type: object
      description: Aggregate for a single weekday over the lookback window.
      properties:
        count:
          type: integer
          description: Number of days contributing
          example: 30
        avgReturnBps:
          type: number
          format: double
          nullable: true
          description: Mean daily return in basis points (1 bp = 0.01%). Null when no data.
          example: 0.8
        volatilityBps:
          type: number
          format: double
          nullable: true
          description: Sample standard deviation of daily returns in basis points. Null when fewer than 2 observations.
          example: 12.4
    SessionWindowBucket:
      type: object
      description: |
        Aggregate for a single trading session, plus the session's recurring UTC window.
        `startUtc` / `endUtc` describe the window as ISO 8601 timestamps anchored to today's
        UTC date — the window itself repeats every day.
      properties:
        startUtc:
          type: string
          format: date-time
          description: Session window start (today's UTC date)
          example: "2026-05-07T00:00:00Z"
        endUtc:
          type: string
          format: date-time
          description: Session window end. For the US session, this rolls into the next UTC day at 00:00Z.
          example: "2026-05-07T08:00:00Z"
        count:
          type: integer
          description: Number of hourly observations contributing
          example: 240
        avgReturnBps:
          type: number
          format: double
          nullable: true
          description: Mean hourly return in basis points (1 bp = 0.01%). Null when no data.
          example: 0.8
        volatilityBps:
          type: number
          format: double
          nullable: true
          description: Sample standard deviation of hourly returns in basis points. Null when fewer than 2 observations.
          example: 12.4
    SessionAnalyticsResponse:
      type: object
      properties:
        symbol:
          type: string
          example: BTC/USD
        timeframe:
          type: string
          example: 1h
          description: Granularity used for the session breakdown
        lookback:
          type: object
          description: The window the statistics were computed over
          properties:
            from:
              type: integer
              format: int64
              description: Window start (Unix ms)
            to:
              type: integer
              format: int64
              description: Window end (Unix ms)
            ms:
              type: integer
              format: int64
              description: Window length in milliseconds
        barsAnalyzed:
          type: integer
          description: Number of hourly observations included in the session breakdown
          example: 720
        sessions:
          type: object
          description: Return statistics for each UTC trading session, each tagged with its recurring daily window
          properties:
            asia:
              $ref: "#/components/schemas/SessionWindowBucket"
            europe:
              $ref: "#/components/schemas/SessionWindowBucket"
            us:
              $ref: "#/components/schemas/SessionWindowBucket"
        dayOfWeek:
          type: object
          description: Daily return statistics grouped by UTC weekday
          properties:
            monday:
              $ref: "#/components/schemas/SessionBucket"
            tuesday:
              $ref: "#/components/schemas/SessionBucket"
            wednesday:
              $ref: "#/components/schemas/SessionBucket"
            thursday:
              $ref: "#/components/schemas/SessionBucket"
            friday:
              $ref: "#/components/schemas/SessionBucket"
            saturday:
              $ref: "#/components/schemas/SessionBucket"
            sunday:
              $ref: "#/components/schemas/SessionBucket"
    AggregatedDepthResponse:
      type: object
      properties:
        symbol:
          type: string
          example: BTC/USDT
        midPrice:
          type: number
          format: double
          example: 87400
          description: Mid-price computed from global best bid and best ask across all exchanges
        spread:
          type: object
          properties:
            absolute:
              type: number
              format: double
              example: 2.5
              description: Spread in term currency (negative indicates crossed market)
            bps:
              type: number
              format: double
              example: 0.29
              description: Spread in basis points (negative indicates crossed market — arbitrage opportunity)
        bids:
          type: object
          description: Cumulative bid-side depth at each bps threshold from mid-price
          properties:
            1bps:
              $ref: "#/components/schemas/DepthBucket"
            5bps:
              $ref: "#/components/schemas/DepthBucket"
            10bps:
              $ref: "#/components/schemas/DepthBucket"
            25bps:
              $ref: "#/components/schemas/DepthBucket"
            50bps:
              $ref: "#/components/schemas/DepthBucket"
            100bps:
              $ref: "#/components/schemas/DepthBucket"
        asks:
          type: object
          description: Cumulative ask-side depth at each bps threshold from mid-price
          properties:
            1bps:
              $ref: "#/components/schemas/DepthBucket"
            5bps:
              $ref: "#/components/schemas/DepthBucket"
            10bps:
              $ref: "#/components/schemas/DepthBucket"
            25bps:
              $ref: "#/components/schemas/DepthBucket"
            50bps:
              $ref: "#/components/schemas/DepthBucket"
            100bps:
              $ref: "#/components/schemas/DepthBucket"
        exchanges:
          type: array
          description: Per-exchange depth contribution (sorted by total depth)
          items:
            type: object
            properties:
              exchange:
                type: string
                example: binance
              pctOfDepth:
                type: number
                format: double
                example: 38.2
                description: Percentage of total depth within 100bps
              bidDepth:
                type: number
                format: double
                description: Total bid-side USD depth within 100bps
              askDepth:
                type: number
                format: double
                description: Total ask-side USD depth within 100bps
        exchangeCount:
          type: integer
          example: 27
        timestamp:
          type: integer
          format: int64
    DepthBucket:
      type: object
      properties:
        depth:
          type: number
          format: double
          description: Cumulative USD depth within this bps threshold
        levels:
          type: integer
          description: Number of order book price levels within this threshold
    ExecutionSimulationResponse:
      type: object
      properties:
        symbol:
          type: string
          example: BTC/USDT
        side:
          type: string
          enum:
            - buy
            - sell
        requestedAmount:
          type: number
          example: 500000
        smartRoute:
          type: object
          description: Simulated execution across all exchanges (optimal routing)
          properties:
            avgPrice:
              type: number
              format: double
              example: 87404.8
            bestPrice:
              type: number
              format: double
              example: 87400
            worstPrice:
              type: number
              format: double
              example: 87415
            slippageBps:
              type: number
              format: double
              example: 0.5
              description: Slippage from best price in basis points
            totalBaseQty:
              type: number
              format: double
              example: 5.7208
            totalQuoteCost:
              type: number
              format: double
              example: 500000
            exchangeCount:
              type: integer
              example: 12
            levelsConsumed:
              type: integer
              example: 28
            partial:
              type: boolean
              description: True if insufficient liquidity to fill full amount
            filledPct:
              type: number
              description: Percentage filled (only present when partial)
        bestSingleExchange:
          type: object
          description: Simulated execution on the single best exchange (for comparison)
          properties:
            exchange:
              type: string
              example: binance
            avgPrice:
              type: number
              format: double
              example: 87412.3
            slippageBps:
              type: number
              format: double
              example: 1.4
            filledPct:
              type: number
              example: 100
            totalBaseQty:
              type: number
              format: double
            totalQuoteCost:
              type: number
              format: double
            levelsConsumed:
              type: integer
        savings:
          type: object
          description: Savings from smart routing vs best single exchange
          properties:
            vsExchange:
              type: string
              example: binance
            priceDiff:
              type: number
              format: double
              description: Price improvement per unit
            savingsUsd:
              type: number
              format: double
              example: 37.5
              description: Total USD saved on the trade
            slippageReductionBps:
              type: number
              format: double
              example: 0.9
              description: Basis points of slippage reduction
        exchanges:
          type: array
          description: Per-exchange fill breakdown (sorted by contribution)
          items:
            type: object
            properties:
              exchange:
                type: string
                example: binance
              avgPrice:
                type: number
                format: double
              baseQty:
                type: number
                format: double
              quoteCost:
                type: number
                format: double
              levelsConsumed:
                type: integer
              pctOfOrder:
                type: number
                format: double
                description: Percentage of total order filled by this exchange
        timestamp:
          type: integer
          format: int64
    CryptoAssetsAllResponse:
      type: object
      description: All-categories response (default shape — when `?type=` is omitted)
      properties:
        totalUnique:
          type: integer
          description: Number of distinct symbols across every category
          example: 1240
        categoryCounts:
          type: object
          description: Pre-pagination count per category
          properties:
            basecoin:
              type: integer
              example: 5
            altcoin:
              type: integer
              example: 1100
            stablecoin:
              type: integer
              example: 22
            ohlc:
              type: integer
              example: 950
            refrate:
              type: integer
              example: 12
        limit:
          type: integer
          description: Per-category page size used for the `categories` payload
          example: 1000
        categories:
          type: object
          description: Sorted symbol list per category (each capped at `limit`)
          properties:
            basecoin:
              type: array
              items:
                type: string
              example:
                - BTC
                - ETH
                - LTC
                - SOL
                - XRP
            altcoin:
              type: array
              items:
                type: string
            stablecoin:
              type: array
              items:
                type: string
              example:
                - DAI
                - FDUSD
                - USDC
                - USDT
            ohlc:
              type: array
              items:
                type: string
            refrate:
              type: array
              items:
                type: string
              example:
                - BTC-USD
                - ETH-USD
                - SOL-USD
    CryptoAssetsByTypeResponse:
      type: object
      description: Single-category response (returned when `?type=` is supplied)
      properties:
        type:
          type: string
          enum:
            - basecoin
            - altcoin
            - stablecoin
            - ohlc
            - refrate
          example: basecoin
        total:
          type: integer
          description: Total symbols in this category before pagination
          example: 5
        count:
          type: integer
          description: Symbols actually returned in this page
          example: 5
        offset:
          type: integer
          example: 0
        limit:
          type: integer
          example: 1000
        symbols:
          type: array
          items:
            type: string
          example:
            - BTC
            - ETH
            - LTC
            - SOL
            - XRP
    Fiat247AssetsResponse:
      type: object
      properties:
        total:
          type: integer
          example: 30
        count:
          type: integer
          example: 30
        offset:
          type: integer
          example: 0
        limit:
          type: integer
          example: 500
        symbols:
          type: array
          items:
            type: string
          example:
            - AUD
            - CAD
            - CHF
            - EUR
            - GBP
            - JPY
            - NZD
            - USD
    Trade:
      type: object
      properties:
        id:
          type: string
          example: "6167846175"
        symbol:
          type: string
          example: BTC/USDT
        timestamp:
          type: integer
          format: int64
          example: 1774903862132
        datetime:
          type: string
          format: date-time
          example: "2026-03-30T20:51:02.132Z"
        side:
          type: string
          enum:
            - buy
            - sell
        price:
          type: number
          format: double
          example: 66628.82
        amount:
          type: number
          format: double
          example: 0.00284
        cost:
          type: number
          format: double
          description: price * amount
          example: 189.2258488
        fee:
          type: object
        fees:
          type: object
        info:
          type: object
          description: Raw exchange-specific trade data
    FundingRate:
      type: object
      description: Funding rate sample for a perpetual contract
      properties:
        id:
          type: string
          description: Unique entry identifier (format `<unix-ms>-<seq>`). Useful for pagination and de-duplication.
          example: 1741551003000-0
        timestamp:
          type: integer
          format: int64
          description: Sample timestamp (Unix ms)
          example: 1741551003000
        symbol:
          type: string
          example: BTC/USDT:USDT
        fundingRate:
          type: number
          format: double
          description: Current funding rate (decimal, not percent)
          example: 0.0001
        nextFundingRate:
          type: number
          format: double
          nullable: true
          description: Predicted next funding rate (may be null)
        fundingTimestamp:
          type: integer
          format: int64
          description: Timestamp of the current funding period (Unix ms)
        nextFundingTimestamp:
          type: integer
          format: int64
          nullable: true
          description: Timestamp of the next funding period (Unix ms)
        previousFundingRate:
          type: number
          format: double
          nullable: true
          description: Previous funding rate (looked up from stream history)
        previousFundingTimestamp:
          type: integer
          format: int64
          nullable: true
          description: Timestamp of the previous funding period (Unix ms)
        markPrice:
          type: number
          format: double
          nullable: true
        indexPrice:
          type: number
          format: double
          nullable: true
        interestRate:
          type: number
          format: double
          nullable: true
        exchange:
          type: string
          example: binance
        dataset:
          type: string
          example: funding
        info:
          type: object
          description: Raw exchange-specific funding payload
    FundingRateHistory:
      type: object
      properties:
        exchange:
          type: string
          example: binance
        dataset:
          type: string
          example: funding
        symbol:
          type: string
          example: BTC-USDT
        count:
          type: integer
          example: 100
        entries:
          type: array
          items:
            $ref: "#/components/schemas/FundingRate"
    OpenInterest:
      type: object
      description: Open interest sample for a perpetual contract
      properties:
        id:
          type: string
          example: 1741551003000-0
        timestamp:
          type: integer
          format: int64
          example: 1741551003000
        symbol:
          type: string
          example: BTC/USDT:USDT
        openInterestAmount:
          type: number
          format: double
          description: Open interest in base asset units
          example: 12345.67
        openInterestValue:
          type: number
          format: double
          description: Open interest notional value in quote asset
          example: 813456789.12
        baseVolume:
          type: number
          format: double
          nullable: true
          description: 24h base asset volume
        quoteVolume:
          type: number
          format: double
          nullable: true
          description: 24h quote asset volume (enriched from ticker hash)
        exchange:
          type: string
          example: binance
        dataset:
          type: string
          example: open-interest
        info:
          type: object
          description: Raw exchange-specific OI payload
    OpenInterestHistory:
      type: object
      properties:
        exchange:
          type: string
          example: binance
        dataset:
          type: string
          example: open-interest
        symbol:
          type: string
          example: BTC-USDT
        count:
          type: integer
          example: 100
        entries:
          type: array
          items:
            $ref: "#/components/schemas/OpenInterest"
    Liquidation:
      type: object
      description: Liquidation event for a perpetual contract
      properties:
        id:
          type: string
          example: 1741551003000-0
        timestamp:
          type: integer
          format: int64
          example: 1741551003000
        symbol:
          type: string
          example: BTC/USDT:USDT
        side:
          type: string
          enum:
            - buy
            - sell
          description: |
            Side of the liquidated position.
            `buy` = a short position was liquidated (forced buy).
            `sell` = a long position was liquidated (forced sell).
        price:
          type: number
          format: double
          example: 66628.82
        baseValue:
          type: number
          format: double
          description: Liquidated amount in base asset
          example: 0.5
        quoteValue:
          type: number
          format: double
          description: Liquidated notional in quote asset
          example: 33314.41
        contracts:
          type: number
          format: double
          nullable: true
        contractSize:
          type: number
          format: double
          nullable: true
        exchange:
          type: string
          example: binance
        dataset:
          type: string
          example: liquidation
        info:
          type: object
          description: Raw exchange-specific liquidation payload
    LiquidationHistory:
      type: object
      properties:
        exchange:
          type: string
          example: binance
        dataset:
          type: string
          example: liquidation
        symbol:
          type: string
          example: BTC-USDT
        count:
          type: integer
          example: 50
        entries:
          type: array
          items:
            $ref: "#/components/schemas/Liquidation"
    RefRateFixing:
      type: object
      properties:
        product:
          type: string
          enum:
            - fix
            - tcut
            - twap
        symbol:
          type: string
          example: BTC-USD
        rate:
          type: number
          format: double
          description: Reference rate (USD)
        bid:
          type: number
          format: double
        ask:
          type: number
          format: double
        timestamp:
          type: integer
          format: int64
          description: Fixing timestamp (ms)
        fixingTime:
          type: string
          format: date-time
          description: Scheduled fixing time (ISO 8601)
        interval:
          type: string
          enum:
            - 1h
            - eod
        method:
          type: string
          description: Calculation method (fix only)
          example: volume_weighted_median
        exchanges:
          type: integer
          description: Exchanges included (fix only)
        excluded:
          type: integer
          description: Exchanges excluded as outliers (fix only)
        samples:
          type: integer
          description: Stream samples in TWAP window (twap only)
        twapWindowMs:
          type: integer
          description: TWAP window duration in ms (twap only)
    OHLCResponse:
      type: object
      required:
        - pair
        - base
        - term
        - type
        - timeframe
        - count
        - candles
      properties:
        pair:
          type: string
          example: BTC-USD
        base:
          type: string
          example: BTC
          description: Base asset symbol
        term:
          type: string
          example: USD
          description: Quote asset symbol
        type:
          type: string
          example: crypto
          description: Asset type (crypto, stock, forex)
        timeframe:
          type: string
          example: h1
        count:
          type: integer
          example: 60
          description: Number of candles returned
        candles:
          type: array
          items:
            type: object
            properties:
              timestamp:
                type: integer
                format: int64
              open:
                type: number
                format: double
              high:
                type: number
                format: double
              low:
                type: number
                format: double
              close:
                type: number
                format: double
              volume:
                type: number
                format: double
    IndicatorResponse:
      type: object
      description: Response for SMA/EMA indicator calculations
      required:
        - indicator
        - window
        - type
        - pair
        - base
        - term
        - timeframe
        - count
        - values
      properties:
        indicator:
          type: string
          enum:
            - sma
            - ema
          example: sma
          description: Indicator type
        window:
          type: integer
          example: 20
          description: Window/period size used for calculation
        type:
          type: string
          enum:
            - crypto
            - fiat247
          example: crypto
          description: Data type (crypto or fiat247)
        pair:
          type: string
          example: BTC-USD
          description: Trading pair
        base:
          type: string
          example: BTC
          description: Base currency symbol
        term:
          type: string
          example: USD
          description: Quote currency symbol
        timeframe:
          type: string
          enum:
            - m1
            - m5
            - m15
            - m30
            - h1
            - h4
            - d1
            - w1
            - mo1
          example: h1
          description: Timeframe for data aggregation
        count:
          type: integer
          example: 100
          description: Number of indicator values returned
        values:
          type: array
          description: Indicator values (newest first)
          items:
            type: object
            required:
              - timestamp
              - value
            properties:
              timestamp:
                oneOf:
                  - type: integer
                    format: int64
                    example: 1705398600000
                    description: Unix timestamp in milliseconds (when timestamp_format=unix)
                  - type: string
                    example: "2024-01-16T09:30:00Z"
                    description: ISO 8601 timestamp (when timestamp_format=iso)
              value:
                type: number
                format: double
                example: 42750.12345678
                description: Indicator value (rounded to 8 decimal places)
        underlying:
          type: object
          description: Raw OHLC candles (only included when expand_underlying=true)
          properties:
            count:
              type: integer
              example: 119
              description: Number of underlying candles
            candles:
              type: array
              items:
                type: object
                properties:
                  timestamp:
                    oneOf:
                      - type: integer
                        format: int64
                      - type: string
                  open:
                    type: number
                    format: double
                  high:
                    type: number
                    format: double
                  low:
                    type: number
                    format: double
                  close:
                    type: number
                    format: double
    ErrorResponse:
      type: object
      required:
        - error
        - message
      properties:
        error:
          type: string
          example: invalid_window
          description: Error code
        message:
          type: string
          example: "Valid window sizes: 5, 7, 9, 10, 12, 14, 20, 21, 25, 26, 50, 100, 200"
          description: Human-readable error message
    RSIResponse:
      type: object
      description: Response for RSI indicator calculations
      required:
        - indicator
        - window
        - type
        - pair
        - base
        - term
        - timeframe
        - count
        - values
      properties:
        indicator:
          type: string
          enum:
            - rsi
          example: rsi
        window:
          type: integer
          example: 14
          description: RSI period
        type:
          type: string
          enum:
            - crypto
            - fiat247
          example: crypto
        pair:
          type: string
          example: BTC-USD
        base:
          type: string
          example: BTC
        term:
          type: string
          example: USD
        timeframe:
          type: string
          example: h1
        count:
          type: integer
          example: 100
        values:
          type: array
          description: RSI values (0-100, newest first)
          items:
            type: object
            properties:
              timestamp:
                oneOf:
                  - type: integer
                    format: int64
                  - type: string
              value:
                type: number
                format: double
                minimum: 0
                maximum: 100
                description: RSI value (0-100)
        underlying:
          type: object
          description: Raw OHLC candles (only if expand_underlying=true)
          properties:
            count:
              type: integer
            candles:
              type: array
              items:
                type: object
    MACDResponse:
      type: object
      description: Response for MACD indicator calculations
      required:
        - indicator
        - parameters
        - type
        - pair
        - base
        - term
        - timeframe
        - count
        - values
      properties:
        indicator:
          type: string
          enum:
            - macd
          example: macd
        parameters:
          type: object
          properties:
            fast:
              type: integer
              example: 12
            slow:
              type: integer
              example: 26
            signal:
              type: integer
              example: 9
        type:
          type: string
          enum:
            - crypto
            - fiat247
          example: crypto
        pair:
          type: string
          example: BTC-USD
        base:
          type: string
          example: BTC
        term:
          type: string
          example: USD
        timeframe:
          type: string
          example: h1
        count:
          type: integer
          example: 100
        values:
          type: array
          description: MACD values (newest first)
          items:
            type: object
            properties:
              timestamp:
                oneOf:
                  - type: integer
                    format: int64
                  - type: string
              macd:
                type: number
                format: double
                description: MACD line value
              signal:
                type: number
                format: double
                description: Signal line value
              histogram:
                type: number
                format: double
                description: MACD histogram (macd - signal)
        underlying:
          type: object
          description: Raw OHLC candles (only if expand_underlying=true)
          properties:
            count:
              type: integer
            candles:
              type: array
              items:
                type: object
    BollingerBandsResponse:
      type: object
      description: Response for Bollinger Bands indicator calculations
      required:
        - indicator
        - window
        - stddev
        - type
        - pair
        - base
        - term
        - timeframe
        - count
        - values
      properties:
        indicator:
          type: string
          enum:
            - bbands
          example: bbands
        window:
          type: integer
          example: 20
          description: SMA period for middle band
        stddev:
          type: number
          example: 2
          description: Standard deviation multiplier
        type:
          type: string
          enum:
            - crypto
            - fiat247
          example: crypto
        pair:
          type: string
          example: BTC-USD
        base:
          type: string
          example: BTC
        term:
          type: string
          example: USD
        timeframe:
          type: string
          example: h1
        count:
          type: integer
          example: 100
        values:
          type: array
          description: Bollinger Bands values (newest first)
          items:
            type: object
            properties:
              timestamp:
                oneOf:
                  - type: integer
                    format: int64
                  - type: string
              upper:
                type: number
                format: double
                description: Upper band
              middle:
                type: number
                format: double
                description: Middle band (SMA)
              lower:
                type: number
                format: double
                description: Lower band
              bandwidth:
                type: number
                format: double
                description: Bandwidth percentage ((upper-lower)/middle * 100)
              percentB:
                type: number
                format: double
                description: "%B indicator ((price-lower)/(upper-lower))"
        underlying:
          type: object
          description: Raw OHLC candles (only if expand_underlying=true)
          properties:
            count:
              type: integer
            candles:
              type: array
              items:
                type: object
    SystemStatus:
      type: object
      properties:
        status:
          type: string
          enum:
            - healthy
            - degraded
            - down
        uptime:
          type: integer
          description: Uptime in seconds
        connections:
          type: object
          properties:
            redis:
              type: string
              enum:
                - connected
                - disconnected
            exchanges:
              type: object
              additionalProperties:
                type: string
                enum:
                  - connected
                  - disconnected
        stats:
          type: object
          properties:
            tickersPerSecond:
              type: number
            tradesPerSecond:
              type: number
            activeSubscriptions:
              type: integer
    ApiStats:
      type: object
      properties:
        totalRequests:
          type: integer
        requestsByEndpoint:
          type: object
          additionalProperties:
            type: integer
        requestsByStatus:
          type: object
          additionalProperties:
            type: integer
        averageResponseTime:
          type: number
          description: Average response time in milliseconds
        period:
          type: string
    Error:
      type: object
      required:
        - error
        - message
      properties:
        error:
          type: string
          example: invalid_request
        message:
          type: string
          example: Invalid parameter value
        details:
          type: object
          additionalProperties: true
        timestamp:
          type: integer
          format: int64
    MarketCalendarStatus:
      type: object
      properties:
        timestamp:
          type: string
          format: date-time
        forex:
          type: object
          properties:
            sessions:
              type: array
              items:
                $ref: "#/components/schemas/ForexSessionStatus"
            activeSessions:
              type: array
              items:
                type: string
                enum:
                  - sydney
                  - tokyo
                  - london
                  - new_york
            nextSessionChange:
              type: object
              nullable: true
              properties:
                session:
                  type: string
                action:
                  type: string
                  enum:
                    - opens
                    - closes
                at:
                  type: string
                  format: date-time
        exchanges:
          type: array
          items:
            $ref: "#/components/schemas/StockExchangeStatus"
    AllForexSessionsResponse:
      type: object
      properties:
        timestamp:
          type: string
          format: date-time
        sessions:
          type: array
          items:
            $ref: "#/components/schemas/ForexSessionStatus"
        activeSessions:
          type: array
          items:
            type: string
            enum:
              - sydney
              - tokyo
              - london
              - new_york
    ForexSessionStatus:
      type: object
      properties:
        session:
          type: string
          enum:
            - sydney
            - tokyo
            - london
            - new_york
        displayName:
          type: string
          example: Sydney Session
        isOpen:
          type: boolean
        currentTimeUtc:
          type: string
          format: date-time
        localTime:
          type: string
          example: "2025-01-01 08:30:00"
        timezone:
          type: string
          example: Australia/Sydney
        opensAt:
          type: string
          format: date-time
          nullable: true
        closesAt:
          type: string
          format: date-time
          nullable: true
        timeUntilOpenMs:
          type: integer
          nullable: true
        timeUntilCloseMs:
          type: integer
          nullable: true
        overlappingSessions:
          type: array
          items:
            type: string
            enum:
              - sydney
              - tokyo
              - london
              - new_york
        dstInfo:
          $ref: "#/components/schemas/DstInfo"
    ForexSchedule:
      type: object
      properties:
        session:
          type: string
          enum:
            - sydney
            - tokyo
            - london
            - new_york
        displayName:
          type: string
        timezone:
          type: string
        weeklySchedule:
          type: array
          items:
            type: object
            properties:
              dayOfWeek:
                type: integer
                minimum: 1
                maximum: 7
              dayName:
                type: string
              openLocal:
                type: string
                example: "07:00"
              closeLocal:
                type: string
                example: "16:00"
              openUtc:
                type: string
                example: "21:00"
              closeUtc:
                type: string
                example: "06:00"
        dstInfo:
          $ref: "#/components/schemas/DstInfo"
    AllExchangesResponse:
      type: object
      properties:
        timestamp:
          type: string
          format: date-time
        exchanges:
          type: array
          items:
            $ref: "#/components/schemas/StockExchangeStatus"
        openExchanges:
          type: array
          items:
            type: string
    StockExchangeStatus:
      type: object
      properties:
        exchange:
          type: string
          example: NYSE
        name:
          type: string
          example: New York Stock Exchange
        country:
          type: string
          example: United States
        isOpen:
          type: boolean
        phase:
          type: string
          enum:
            - pre_market
            - regular
            - lunch_break
            - after_hours
            - closed
        currentTimeUtc:
          type: string
          format: date-time
        localTime:
          type: string
        timezone:
          type: string
          example: America/New_York
        regularHours:
          $ref: "#/components/schemas/TradingHours"
        opensAt:
          type: string
          format: date-time
          nullable: true
        closesAt:
          type: string
          format: date-time
          nullable: true
        nextTradingDay:
          type: string
          format: date
          nullable: true
        isHoliday:
          type: boolean
        holidayName:
          type: string
          nullable: true
        dstInfo:
          $ref: "#/components/schemas/DstInfo"
    ExchangeSchedule:
      type: object
      properties:
        exchange:
          type: string
        name:
          type: string
        timezone:
          type: string
        regularHours:
          $ref: "#/components/schemas/TradingHours"
        preMarket:
          $ref: "#/components/schemas/TradingHours"
        afterHours:
          $ref: "#/components/schemas/TradingHours"
        lunchBreak:
          $ref: "#/components/schemas/TradingHours"
        tradingDays:
          type: array
          items:
            type: string
        upcomingDays:
          type: array
          items:
            $ref: "#/components/schemas/UpcomingTradingDay"
        dstInfo:
          $ref: "#/components/schemas/DstInfo"
    UpcomingTradingDay:
      type: object
      properties:
        date:
          type: string
          format: date
        dayName:
          type: string
        isOpen:
          type: boolean
        isHoliday:
          type: boolean
        holidayName:
          type: string
          nullable: true
        openUtc:
          type: string
          format: date-time
          nullable: true
        closeUtc:
          type: string
          format: date-time
          nullable: true
    TradingHours:
      type: object
      properties:
        open:
          type: string
          example: "09:30"
        close:
          type: string
          example: "16:00"
    DstInfo:
      type: object
      properties:
        inDst:
          type: boolean
        abbreviation:
          type: string
          example: EST
        offsetMinutes:
          type: integer
          example: -300
        offsetString:
          type: string
          example: "-05:00"
        nextTransition:
          type: string
          format: date-time
          nullable: true
        nextTransitionType:
          type: string
          enum:
            - start
            - end
          nullable: true
    CountryHolidays:
      type: object
      properties:
        countryCode:
          type: string
          example: US
        countryName:
          type: string
          example: United States
        year:
          type: integer
          example: 2025
        timezone:
          type: string
        holidays:
          type: array
          items:
            $ref: "#/components/schemas/Holiday"
    Holiday:
      type: object
      properties:
        date:
          type: string
          format: date
        name:
          type: string
          example: New Year's Day
        type:
          type: string
          enum:
            - public
            - bank
            - observance
            - optional
            - school
        start:
          type: string
          format: date-time
        end:
          type: string
          format: date-time
    MarketHoliday:
      type: object
      properties:
        date:
          type: string
          format: date
        name:
          type: string
        type:
          type: string
          enum:
            - public
            - bank
            - observance
            - optional
            - school
        affectedExchanges:
          type: array
          items:
            type: string
        marketStatus:
          type: string
          enum:
            - closed
            - early_close
            - late_open
        earlyCloseTime:
          type: string
          nullable: true
x-tagGroups:
  - name: Authentication
    tags:
      - OAuth 2.0
      - API Keys
  - name: Cryptocurrency
    tags:
      - Cryptocurrency
      - Crypto Aggregated Rates
      - Crypto OHLC
      - Crypto Exchanges
      - Crypto Order Books
      - Crypto RefRate
      - Crypto Assets
      - Crypto Market
      - Crypto Indicators
      - Crypto Analytics
      - Crypto Streaming
  - name: Stocks
    tags:
      - Stocks
      - Stock Rates
      - Stock Tickers
      - Stock OHLC
      - Stock Indicators
      - Stock Trades
      - Stock Assets
      - Stock Market
      - Stock Streaming
  - name: Forex
    tags:
      - Forex
      - Forex Rates
      - Forex OHLC
      - Forex Indicators
      - Forex Assets
      - Forex Streaming
  - name: Fiat247
    tags:
      - Fiat247
      - Fiat247 Rates
      - Fiat247 OHLC
      - Fiat247 Indicators
  - name: DEX
    tags:
      - DEX
      - DEX Midrate
  - name: Options
    tags:
      - Options
      - Option Rates
      - Option Assets
  - name: User Features
    tags:
      - User Features
      - User Alerts
      - User Watchlist
      - User Portfolio
  - name: Market Calendar
    tags:
      - Market Calendar
  - name: System
    tags:
      - System
      - OpenServer
