> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kairos.trade/llms.txt
> Use this file to discover all available pages before exploring further.

# Get a live perpetual market-data snapshot

> Production beta, sourced directly from the selected venue by the Market Data API.
Returns a canonical ordered book, recent trades, one-minute candles,
funding observations, and typed market state. Financial values are
exact decimal strings. Prices are direct venue prices, never 0–100
prediction probabilities. Quantities and volumes retain the declared
`base_asset` or `contracts` unit. Do not derive notional for contract
quantities without authoritative instrument metadata, and never apply
the prediction-market `/ 100` formula. Each request costs 6 units in
the HEAVY rate-limit bucket because it fans out to multiple venue
resources.
Responses are never cacheable by clients; the Market Data API uses a bounded
one-second replica-local cache to coalesce bursts.




## OpenAPI

````yaml /openapi/market-data-api.yaml get /v1/perpetuals/{venue}/{instrument}/snapshot
openapi: 3.1.0
info:
  title: Kairos Market Data API
  version: 1.2.0
  summary: Read-only prediction and perpetual market data across venues.
  description: >
    The Kairos Market Data API provides read-only access

    to normalized prediction-market data across every venue Kairos integrates:

    OHLCV candles, the trade tape, market metadata, resolution lifecycles, and

    latest mark prices.


    ## No signup required


    Every endpoint works **without credentials** on the anonymous free tier,

    rate-limited per source IP (120 light units/min, 20 heavy units/min). Try
    any

    request from the interactive docs at

    [app.kairos.trade/docs/market-data](https://app.kairos.trade/docs/market-data)

    or straight from curl. For production budgets (1,200 light and 150 heavy

    units/min by default, raisable per credential), request an API key from the

    Kairos team.


    ## Authentication


    Three modes, resolved per request:


    - **Anonymous** — no credential headers at all. Free tier, IP-keyed limits.

    - **API key** — `X-Client-Id` + `X-Api-Key` + `X-Api-Secret` headers
      (all three; partial header sets are rejected with 401 rather than
      degrading to anonymous).
    - **First-party session** — `Authorization: Bearer` JWT (Kairos web app
      sessions only; not offered to API consumers).

    Resolution order is fixed: an `Authorization` header takes the bearer

    path, any of the three API-key headers takes the API-key path, and only

    a request carrying neither is eligible for the anonymous tier.


    On the API-key path, an unreachable credential store surfaces on **any**

    endpoint as `500` with `code: internal` and the message

    `authentication backend unavailable`. A source IP outside a credential's

    whitelist is `403 ip_not_whitelisted`; that is the only 403 this service

    emits.


    ## Rate limiting


    Weighted sliding-window budgets over one minute, in **units**, across two

    independent buckets: light (candles, metadata, resolutions, trade

    metrics) and heavy (trade history, marks, perpetual snapshots). Most

    requests cost 1 unit; larger requests may consume more of your quota —

    each operation's `x-kairos-rate-limit` states its exact cost model.

    Every admitted response carries `X-RateLimit-Bucket`, `X-RateLimit-Tier`,

    `X-RateLimit-Remaining`, and `X-RateLimit-Reset`; 429s add `Retry-After`.


    A separate per-IP admission gate runs *before* authentication to keep a

    flood off shared infrastructure. It also answers 429 `rate_limited`, but

    with `Retry-After: 60` and no `X-RateLimit-*` headers.


    Redis backs the weighted limiter and it fails **closed**: if it is

    unreachable the request is rejected with 503 `rate_limiter_unavailable`

    rather than let through unmetered.


    ## Conventions


    - **Prediction-market prices** are on the 0–100 scale (implied probability
      × 100) in the prediction candle, trade, and mark endpoints. Prediction
      USD notional = `size × price / 100`.
    - **Perpetual prices are direct venue prices**, not probabilities and not
      0–100 values. Perpetual quantities retain their declared native unit
      (`base_asset` or `contracts`). Never divide a perpetual price by 100 or
      compute contract notional without the instrument's authoritative contract
      multiplier; the snapshot does not synthesize a cross-venue notional.
    - **Hyperliquid is two products on one venue.** Its HIP-4 outcome markets
      are prediction markets, read with `provider=hyperliquid` on the
      prediction endpoints; its perpetuals are bare coins read under
      `/v1/perpetuals/hyperliquid/{instrument}/snapshot`, where the instrument
      is the canonical id `hl-mainnet-<symbol>-<quote>` (e.g.
      `hl-mainnet-btc-usdt`). Different id schemes, different price semantics;
      they are never interchangeable.
    - **Errors** all use one envelope:
      `{"error": {"code": "...", "message": "..."}}`.
    - **Providers** are case-insensitive; `kalshi_offchain` aliases `kalshi`,
      `dome` aliases `polymarket`, and `opinion` is resolvable for historic
      reads only.
  contact:
    name: Kairos
    url: https://app.kairos.trade/docs/market-data
  termsOfService: https://kairos.trade/terms
servers:
  - url: https://md.kairos.trade
    description: Production
  - url: https://staging-md.kairos.trade
    description: Staging
security:
  - {}
  - apiKeyClientId: []
    apiKeyKey: []
    apiKeySecret: []
tags:
  - name: Candles
    description: OHLCV candle series (1s → 1d), JSON or compact columnar binary.
  - name: Trades
    description: Trade tape and aggregate volume metrics.
  - name: Markets
    description: Market metadata, batch lookup, identifier resolution, and enumeration.
  - name: Resolutions
    description: Resolution outcomes and UMA-style lifecycle state/timelines.
  - name: Marks
    description: Latest mark (last trade price) per outcome token.
  - name: Perpetuals
    description: Live perpetual books, trades, candles, funding, and market state. Beta.
  - name: Status
    description: Health and readiness probes.
paths:
  /v1/perpetuals/{venue}/{instrument}/snapshot:
    get:
      tags:
        - Perpetuals
      summary: Get a live perpetual market-data snapshot
      description: >
        Production beta, sourced directly from the selected venue by the Market
        Data API.

        Returns a canonical ordered book, recent trades, one-minute candles,

        funding observations, and typed market state. Financial values are

        exact decimal strings. Prices are direct venue prices, never 0–100

        prediction probabilities. Quantities and volumes retain the declared

        `base_asset` or `contracts` unit. Do not derive notional for contract

        quantities without authoritative instrument metadata, and never apply

        the prediction-market `/ 100` formula. Each request costs 6 units in

        the HEAVY rate-limit bucket because it fans out to multiple venue

        resources.

        Responses are never cacheable by clients; the Market Data API uses a
        bounded

        one-second replica-local cache to coalesce bursts.
      operationId: getPerpetualSnapshot
      parameters:
        - name: venue
          in: path
          required: true
          schema:
            type: string
            enum:
              - hyperliquid
              - polymarket_perps
              - kalshi_margin
        - name: instrument
          in: path
          required: true
          description: >
            Venue-native instrument identifier, such as BTC, 6, or KXBTCPERP.

            Hyperliquid support is limited to standard main-dex perps in every

            environment; HIP-3 `dex:coin` identifiers are rejected. BTC and
            other

            standard listings are quoted in USDT, while HYPE and PURR are

            USDC-quoted exceptions. All three collateralize and settle in USDC.

            Their canonical identities are `hl-mainnet-btc-usdt`,

            `hl-mainnet-hype-usdc`, and `hl-mainnet-purr-usdc`.
          schema:
            type: string
        - name: depth
          in: query
          description: >
            Requested book depth per side. When omitted the default is the
            venue's own ceiling —

            20 for `hyperliquid` (its `l2Book` returns no more), 500 for
            `polymarket_perps` and

            `kalshi_margin`. A value outside [1, 500], or one that is not an
            integer, is rejected

            with 400.
          schema:
            type: integer
            minimum: 1
            maximum: 500
      responses:
        '200':
          description: Live canonical venue snapshot.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PerpetualSnapshot'
        '400':
          description: >
            `unsupported perpetual venue` (a `venue` outside the enum), `depth
            must be an integer`, `depth must be between 1 and 500`, or `invalid
            perpetual instrument` — the instrument is empty, longer than 128
            bytes, or does not match the venue's identifier grammar
            (`^[A-Za-z0-9][A-Za-z0-9._-]*$` for Hyperliquid, which is what
            rejects HIP-3 `dex:coin`; a positive integer for `polymarket_perps`;
            `^KX[A-Z0-9]+PERP$` for `kalshi_margin`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  code: invalid_request
                  message: invalid perpetual instrument
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/IPNotWhitelisted'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          description: >-
            `internal` / `authentication backend unavailable` — the API-key path
            could not reach the credential store.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  code: internal
                  message: authentication backend unavailable
        '502':
          description: >
            `upstream` / `perpetual venue data is unavailable or invalid`.
            Covers every non-validation failure: the venue returned a non-2xx
            status or an undecodable body, the 12s composite fetch deadline
            expired, or the assembled snapshot failed canonical validation
            (crossed or unsorted book, non-exact decimal, unknown market status,
            bad candle interval, unknown funding sign convention).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          $ref: '#/components/responses/RateLimiterUnavailable'
components:
  schemas:
    PerpetualSnapshot:
      type: object
      additionalProperties: false
      description: |
        Live perpetual snapshot, in beta. Prices are direct venue prices.
        Quantities retain native units. This object intentionally carries no
        synthesized notional: consumers must inspect `instrument_context` and
        must not convert contract quantities when `contract_multiplier` is null.
      required:
        - venue
        - environment
        - integration_id
        - canonical_instrument_id
        - venue_instrument_id
        - instrument_context
        - book
        - market_state
        - trades
        - candles
        - funding
        - source
        - fetched_at_ns
      properties:
        venue:
          type: string
          enum:
            - hyperliquid
            - polymarket_perps
            - kalshi_margin
        environment:
          type: string
          minLength: 1
          description: Venue environment for this source identity.
        integration_id:
          type: string
          minLength: 1
          description: Kairos integration and routing identity.
        canonical_instrument_id:
          type: string
          minLength: 1
          description: Stable Kairos perpetual instrument identity.
        venue_instrument_id:
          type: string
          description: Exact venue-native instrument identifier.
        instrument_context:
          $ref: '#/components/schemas/PerpetualInstrumentContext'
        book:
          $ref: '#/components/schemas/PerpetualOrderBookSnapshot'
        market_state:
          $ref: '#/components/schemas/PerpetualMarketState'
        trades:
          type: array
          items:
            $ref: '#/components/schemas/PerpetualPublicTrade'
          description: Recent public trades in venue-native quantity units.
        candles:
          type: array
          items:
            $ref: '#/components/schemas/PerpetualTradeCandle'
          description: One-minute trade candles in venue-native volume units.
        funding:
          type: array
          items:
            $ref: '#/components/schemas/PerpetualFundingRate'
          description: >-
            Final or estimated funding observations using positive_longs_pay
            sign convention.
        source:
          type: string
          const: venue_public_api
        fetched_at_ns:
          type: integer
          format: int64
          description: Kairos fetch completion time in Unix nanoseconds.
    ErrorResponse:
      type: object
      description: Canonical error envelope emitted by every Market Data API endpoint.
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
              description: Machine-readable error code.
              example: invalid_request
            message:
              type: string
              description: Human-readable detail.
              example: market_ids exceeds maximum 200
    PerpetualInstrumentContext:
      type: object
      additionalProperties: false
      required:
        - base_asset_id
        - quote_asset_id
        - collateral_asset_id
        - settlement_asset_id
        - price_unit
        - quantity_unit
        - contract_multiplier
        - notional_formula
      properties:
        base_asset_id:
          type: string
          minLength: 1
        quote_asset_id:
          type: string
          minLength: 1
          description: |
            Asset in which direct prices are expressed. Hyperliquid standard
            main-dex perpetuals use USDT.
        collateral_asset_id:
          type: string
          minLength: 1
          description: |
            Asset securing margin. This is independent of the quote asset;
            Hyperliquid standard main-dex perpetuals use USDC collateral.
        settlement_asset_id:
          type: string
          minLength: 1
          description: |
            Asset in which settlement or realized PnL is denominated.
            Hyperliquid uses USDC, Polymarket Perps uses pUSD, and Kalshi
            Margin uses USD.
        price_unit:
          type: string
          minLength: 1
          description: |
            Explicit unit relationship for every direct price in the snapshot.
            A perpetual price is never a 0–100 prediction probability.
        quantity_unit:
          type: string
          enum:
            - base_asset
            - contracts
          description: >
            Native quantity unit used by books and trades. Candle volume
            declares

            its own `native_volume_unit` and may differ; for example, a venue
            can

            quote book/trade quantities as contracts but kline volume as base
            asset.
        contract_multiplier:
          anyOf:
            - $ref: '#/components/schemas/PerpetualPositiveDecimalString'
            - type: 'null'
          description: |
            Authoritative venue contract multiplier, or null when unavailable.
            Consumers must not invent a multiplier.
        notional_formula:
          type: string
          minLength: 1
          description: |
            Machine-readable formula identity describing any supported notional
            conversion. It is not the prediction-market `size * price / 100`
            formula.
    PerpetualOrderBookSnapshot:
      type: object
      additionalProperties: false
      required:
        - bids
        - asks
        - event_time_ns
        - received_time_ns
        - source_sequence
        - sequence_domain
        - feed_mode
        - depth
        - requested_depth
        - source_depth_limit
        - depth_limited
        - native_volume_unit
      properties:
        bids:
          type: array
          description: Price levels ordered strictly highest to lowest.
          items:
            $ref: '#/components/schemas/PerpetualBookLevel'
        asks:
          type: array
          description: Price levels ordered strictly lowest to highest.
          items:
            $ref: '#/components/schemas/PerpetualBookLevel'
        event_time_ns:
          type:
            - integer
            - 'null'
          format: int64
          description: Venue event time in Unix nanoseconds, or null when unavailable.
        received_time_ns:
          type: integer
          format: int64
          description: Kairos receive time in Unix nanoseconds.
        source_sequence:
          type:
            - integer
            - 'null'
          format: int64
          description: Venue-native source sequence, or null for an unsequenced source.
        sequence_domain:
          type: string
          minLength: 1
          description: Scope in which `source_sequence` has meaning.
        feed_mode:
          type: string
          enum:
            - snapshot_only
          description: The preview exposes complete REST snapshots, not deltas.
        depth:
          type: integer
          minimum: 0
          maximum: 500
          description: Number of levels returned on the deeper populated side.
        requested_depth:
          type: integer
          minimum: 1
          maximum: 500
          description: Depth requested by the caller.
        source_depth_limit:
          type:
            - integer
            - 'null'
          minimum: 1
          description: |
            Authoritative maximum depth imposed by the source endpoint, or null
            when the source does not declare a fixed limit.
        depth_limited:
          type: boolean
          description: |
            True when the returned depth is below `requested_depth` because of
            an identified source limit. False does not imply both sides contain
            the requested number of populated levels.
        native_volume_unit:
          type: string
          enum:
            - base_asset
            - contracts
          description: Native quantity unit for every level in this book.
    PerpetualMarketState:
      type: object
      additionalProperties: false
      required:
        - event_time_ns
        - status
        - prices
        - measures
        - next_funding_time_ns
      properties:
        event_time_ns:
          type: integer
          format: int64
          description: Market-state event time in Unix nanoseconds.
        status:
          type: string
          enum:
            - active
            - inactive
            - delisted
            - unknown
        prices:
          type: array
          items:
            $ref: '#/components/schemas/PerpetualPriceObservation'
        measures:
          type: array
          items:
            $ref: '#/components/schemas/PerpetualMeasureObservation'
        next_funding_time_ns:
          type:
            - integer
            - 'null'
          format: int64
          description: Next funding time in Unix nanoseconds, or null when unavailable.
    PerpetualPublicTrade:
      type: object
      additionalProperties: false
      required:
        - trade_id
        - price
        - quantity
        - quantity_unit
        - side
        - event_time_ns
      properties:
        trade_id:
          type: string
          description: Venue-native public trade identifier.
        price:
          $ref: '#/components/schemas/PerpetualPositiveDecimalString'
          description: Direct venue execution price; never a 0–100 probability.
        quantity:
          $ref: '#/components/schemas/PerpetualPositiveDecimalString'
          description: Exact quantity in `quantity_unit`.
        quantity_unit:
          type: string
          enum:
            - base_asset
            - contracts
        side:
          type: string
          enum:
            - buy
            - sell
        event_time_ns:
          type: integer
          format: int64
          description: Venue trade time in Unix nanoseconds.
    PerpetualTradeCandle:
      type: object
      additionalProperties: false
      required:
        - interval
        - interval_start_ns
        - interval_end_ns
        - open
        - high
        - low
        - close
        - native_volume
        - native_volume_unit
        - trade_count
        - finality
      properties:
        interval:
          type: string
          description: Venue candle interval. The preview currently requests one minute.
          example: 1m
        interval_start_ns:
          type: integer
          format: int64
          description: >-
            Inclusive start of the candle's half-open interval, in Unix
            nanoseconds.
        interval_end_ns:
          type: integer
          format: int64
          description: >-
            Exclusive end of the candle's half-open interval, in Unix
            nanoseconds.
        open:
          $ref: '#/components/schemas/PerpetualPositiveDecimalString'
        high:
          $ref: '#/components/schemas/PerpetualPositiveDecimalString'
        low:
          $ref: '#/components/schemas/PerpetualPositiveDecimalString'
        close:
          $ref: '#/components/schemas/PerpetualPositiveDecimalString'
        native_volume:
          $ref: '#/components/schemas/PerpetualNonNegativeDecimalString'
          description: |
            Exact volume in this candle's `native_volume_unit`; no cross-venue
            notional is implied. This unit is independent of
            `instrument_context.quantity_unit`.
        native_volume_unit:
          type: string
          enum:
            - base_asset
            - contracts
          description: |
            Native unit reported by the candle source. It may differ from the
            book and trade quantity unit for the same instrument.
        trade_count:
          type:
            - integer
            - 'null'
          description: Venue-reported trade count, or null when unavailable.
        finality:
          type: string
          enum:
            - open
            - closed_unconfirmed
          description: |
            `open` means the interval has not closed. `closed_unconfirmed` means
            its half-open interval has ended, but the preview does not claim an
            immutable or venue-confirmed final candle.
    PerpetualFundingRate:
      type: object
      additionalProperties: false
      required:
        - rate
        - phase
        - effective_time_ns
        - calculated_time_ns
        - rate_period_seconds
        - payment_interval_seconds
        - sign_convention
        - funding_price
        - funding_price_type
      properties:
        rate:
          $ref: '#/components/schemas/PerpetualExactDecimalString'
          description: >
            Exact signed funding rate in the venue's reported period convention.

            Do not infer percentage scaling or annualize without the period
            fields.
        phase:
          type: string
          enum:
            - estimate
            - final
        effective_time_ns:
          type: integer
          format: int64
        calculated_time_ns:
          type:
            - integer
            - 'null'
          format: int64
          description: Calculation time in Unix nanoseconds, or null when unavailable.
        rate_period_seconds:
          type:
            - integer
            - 'null'
          description: >-
            Period represented by `rate`, or null when the venue does not
            provide it.
        payment_interval_seconds:
          type:
            - integer
            - 'null'
          description: Funding payment interval, or null when unavailable.
        sign_convention:
          type: string
          const: positive_longs_pay
        funding_price:
          anyOf:
            - $ref: '#/components/schemas/PerpetualPositiveDecimalString'
            - type: 'null'
          description: Venue funding price, or null when unavailable.
        funding_price_type:
          type:
            - string
            - 'null'
          description: Identity of `funding_price`, such as mark, or null with no price.
    PerpetualPositiveDecimalString:
      type: string
      pattern: ^(?:[1-9][0-9]*(?:\.[0-9]*[1-9])?|0\.[0-9]*[1-9])$
      description: Normalized, exact base-10 decimal strictly greater than zero.
      examples:
        - '0.001'
        - '65192.5'
    PerpetualBookLevel:
      type: object
      additionalProperties: false
      required:
        - price
        - quantity
        - order_count
      properties:
        price:
          $ref: '#/components/schemas/PerpetualPositiveDecimalString'
          description: Direct venue price. This is not a 0–100 probability.
        quantity:
          $ref: '#/components/schemas/PerpetualPositiveDecimalString'
          description: Quantity in the enclosing book's `native_volume_unit`.
        order_count:
          type:
            - integer
            - 'null'
          description: Venue-reported order count at this level, or null when unavailable.
    PerpetualPriceObservation:
      type: object
      additionalProperties: false
      required:
        - price_type
        - value
        - observed_time_ns
      properties:
        price_type:
          type: string
          minLength: 1
          description: Venue-backed price identity, such as mark, index, oracle, or mid.
        value:
          $ref: '#/components/schemas/PerpetualPositiveDecimalString'
          description: Direct venue price; never a prediction probability.
        observed_time_ns:
          type:
            - integer
            - 'null'
          format: int64
          description: Observation time in Unix nanoseconds, or null when unavailable.
    PerpetualMeasureObservation:
      type: object
      additionalProperties: false
      required:
        - measure_type
        - value
        - unit
      properties:
        measure_type:
          type: string
          minLength: 1
          description: Measure identity, such as open_interest or open_interest_notional.
        value:
          $ref: '#/components/schemas/PerpetualNonNegativeDecimalString'
        unit:
          type: string
          minLength: 1
          description: >-
            Explicit venue-native or derived unit, such as base_asset,
            contracts, or usd.
    PerpetualNonNegativeDecimalString:
      type: string
      pattern: ^(?:0|[1-9][0-9]*(?:\.[0-9]*[1-9])?|0\.[0-9]*[1-9])$
      description: Normalized, exact base-10 decimal greater than or equal to zero.
      examples:
        - '0'
        - '1250.75'
    PerpetualExactDecimalString:
      type: string
      pattern: ^(?:0|-?[1-9][0-9]*(?:\.[0-9]*[1-9])?|-?0\.[0-9]*[1-9])$
      description: |
        Normalized, exact base-10 decimal. No exponent notation, leading zeros,
        trailing fractional zeros, NaN, or infinity. May be negative.
      examples:
        - '0'
        - '-0.00025'
        - '65192.5'
  responses:
    Unauthorized:
      description: >
        No valid credential presented. Every path returns `code: unauthorized`;
        the triggers differ:


        - An `Authorization` header on a deployment where bearer auth is not
        enabled (`bearer authentication is not enabled`).

        - A bearer token that fails verification (`invalid or expired session`),
        or whose token/session has been revoked (`session has been revoked`).

        - An incomplete or wrong API-key header set. Sending *any* of
        `X-Client-Id`, `X-Api-Key`, `X-Api-Secret` commits the request to the
        API-key path, so a partial set is rejected rather than silently
        degrading to anonymous limits (`valid X-Client-Id, X-Api-Key, and
        X-Api-Secret headers are required`).

        - No credential material at all while the anonymous free tier is
        unavailable — switched off for the deployment, forced off through the
        runtime kill switch, or not yet resolvable on a replica that has never
        read the flag (it fails closed).
      headers:
        WWW-Authenticate:
          schema:
            type: string
          description: >-
            `Bearer realm="market-data-api"` on bearer-verification failure,
            `APIKey realm="market-data-api", header="X-Client-Id, X-Api-Key,
            X-Api-Secret"` on missing/invalid API-key credentials. Absent on the
            revoked-session and bearer-disabled paths.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: unauthorized
              message: >-
                valid X-Client-Id, X-Api-Key, and X-Api-Secret headers are
                required
    IPNotWhitelisted:
      description: API key presented from a source IP not in that credential's whitelist.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: ip_not_whitelisted
              message: source IP not in credential whitelist
    RateLimited:
      description: >
        Two different gates return this status, both with `code: rate_limited`:


        - **Per-credential (or per-IP, when anonymous) weighted budget
        exhausted.** The message is `rate limit exceeded`, or, for anonymous
        callers, `anonymous rate limit exceeded — request an API key for higher
        limits (…)`. `Retry-After` is the whole number of seconds until the
        current one-minute window rolls over, floored at 1. All four
        `X-RateLimit-*` headers are present.

        - **Per-IP admission gate.** An in-process, pre-authentication guard
        that keeps a flood off the shared credential cache and database. The
        message is `too many requests from this address` and `Retry-After` is a
        flat `60`. Because this fires *before* authentication, the response
        carries **no** `X-RateLimit-*` headers at all.
      headers:
        Retry-After:
          schema:
            type: integer
          description: >-
            Seconds until the caller may retry — window-rollover seconds for the
            weighted limiter, a flat 60 for the IP admission gate.
        X-RateLimit-Bucket:
          schema:
            type: string
            enum:
              - light
              - heavy
        X-RateLimit-Tier:
          schema:
            type: string
            enum:
              - anonymous
              - api-key
              - user
        X-RateLimit-Remaining:
          schema:
            type: integer
        X-RateLimit-Reset:
          schema:
            type: integer
            description: Unix timestamp (seconds) when the current window resets.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: rate_limited
              message: rate limit exceeded
    RateLimiterUnavailable:
      description: >
        The rate limiter is unreachable. Fails CLOSED — the request is rejected
        rather than let through unmetered.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: rate_limiter_unavailable
              message: rate limiter temporarily unavailable
  securitySchemes:
    apiKeyClientId:
      type: apiKey
      in: header
      name: X-Client-Id
      description: >-
        Credential client id (`kairos_ck_...`). Must be sent together with
        X-Api-Key and X-Api-Secret.
    apiKeyKey:
      type: apiKey
      in: header
      name: X-Api-Key
      description: >-
        64-char hex API key. Must be sent together with X-Client-Id and
        X-Api-Secret.
    apiKeySecret:
      type: apiKey
      in: header
      name: X-Api-Secret
      description: >-
        64-char hex API secret. Must be sent together with X-Client-Id and
        X-Api-Key.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.