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

# Get Key Usage

> Everything the console's Requests page draws, per key.

Four series, all read from counters that already exist rather than derived
from an estimate:

* ``days`` / ``month_to_date`` — the daily counter written by
  ``auth._check_rate_limit`` on the pipeline that already runs for every
  keyed request. Backs the 30-day view and the monthly quota.
* ``hours`` — the hourly request and error counters, for the traffic chart
  and its error strip.
* ``latency`` — six fixed buckets summed over the same hourly window.
  Percentiles are bucket UPPER BOUNDS, never interpolated; see
  :class:`LatencySummary`.
* ``recent`` — the per-key ring of the last ``RECENT_MAX`` requests, newest
  first. Route TEMPLATES only, so no request identifiers are retained.

**Only the caller's own keys.** The prefixes are read from ``api_keys``
filtered by ``user_id`` and never from user input, so there is no way to
address another tenant's telemetry by asking for it.

Fails SOFT: a Redis outage yields zeroes and empty lists, not a 500. This is
a dashboard panel — a broken chart must not take down the page that also
shows someone their API key. A zero here is visibly a zero; it is not
presented as a measured absence of traffic.



## OpenAPI

````yaml /openapi.json get /v1/keys/usage
openapi: 3.1.0
info:
  title: Polysimulator API
  summary: HFT-style paper-trading API for Polymarket simulation.
  description: >-
    PolySimulator HFT API v1 — Virtual trading environment for Polymarket
    prediction markets. Practice trading with real market data using paper
    money, then switch to live trading by changing only your API credentials.
  termsOfService: https://polysimulator.com/legal/terms
  contact:
    name: PolySimulator
    url: https://polysimulator.com
  license:
    name: Proprietary — usage subject to Polysimulator Terms of Service
    url: https://polysimulator.com/legal/terms
  version: 1.0.0-beta
servers:
  - url: https://api.polysimulator.com
    description: Production
  - url: https://staging-api.polysimulator.com
    description: Staging
security:
  - ApiKeyAuth: []
tags:
  - name: API Keys
    description: >-
      Bootstrap, create, list, revoke API keys, mint short-lived WebSocket
      tokens, list rate-limit tiers.
  - name: Account
    description: >-
      Balance, equity curve, portfolio composition, open positions, trade
      history.
  - name: Export
    description: >-
      Pro data export — streamed CSV downloads for offline analysis,
      backtesting, and tax/accounting. v1: GET /v1/export/trades.csv (FILLED
      trades, keyset-paginated). Dual session + API-key auth.
  - name: Profile Analysis
    description: >-
      Trading-profile analytics — Sharpe, win-rate, drawdown, holding-period
      histograms.
  - name: Wallets
    description: >-
      Multi-wallet management (MAIN / SANDBOX / API / COMPETITION). List, switch
      active wallet, per-wallet balance + history.
  - name: Trading
    description: >-
      Place, cancel, batch, and list orders. Cancel-all + cancel-market-orders
      sweep endpoints. PolySimulator-native order surface.
  - name: Market Data
    description: >-
      Polymarket market metadata + live prices (POST /v1/prices/batch,
      /v1/markets, /v1/markets/{condition_id}/candles).
  - name: CLOB Read (Public)
    description: >-
      Polymarket-shape read endpoints (book, midpoint, spread, price,
      last-trade-price, tick-size, neg-risk, time). Wire-compatible with
      py-clob-client.
  - name: CLOB Compat
    description: >-
      Polymarket-shape order surface (POST /v1/order with nested body, POST
      /v1/orders batch, GET /v1/data/orders PM-envelope). Use these for drop-in
      py-clob-client compatibility.
  - name: WebSocket
    description: >-
      WebSocket subscription endpoints — /v1/ws/prices for live market data,
      /v1/ws/executions for order-state updates.
  - name: Billing
    description: >-
      Stripe-backed subscriptions, top-ups, customer portal, refund policy,
      paid-tier resets.
  - name: Status
    description: System-status surface — uptime, component health, recent incident markers.
  - name: Health
    description: >-
      Health, liveness, readiness, and authenticated-identity probes
      (/v1/health, /v1/health/live, /v1/health/ready, /v1/me).
  - name: Football
    description: >-
      Football / World-Cup 2026 enrichment — live score, minute, momentum,
      possession, xG, shotmap, commentary, lineups, group standings, knockout
      bracket, and head-to-head. Public read-only sports facts the UI merges
      with tradable Polymarket prices; degrades to empty shapes on upstream
      failure.
  - name: Simulation
    description: >-
      Historical fill simulation, archive coverage, and curated backtests. Dark
      until FEATURE_SIMULATION_API_ENABLED is on.
  - name: Integrations
    description: >-
      Outbound alert delivery integrations (Discord) — per-user subscriptions
      managed under /v1/integrations/*. Mirrors the /me/webhook + /me/push
      routes for the older channels.
paths:
  /v1/keys/usage:
    get:
      tags:
        - API Keys
        - API Keys
      summary: Get Key Usage
      description: >-
        Everything the console's Requests page draws, per key.


        Four series, all read from counters that already exist rather than
        derived

        from an estimate:


        * ``days`` / ``month_to_date`` — the daily counter written by
          ``auth._check_rate_limit`` on the pipeline that already runs for every
          keyed request. Backs the 30-day view and the monthly quota.
        * ``hours`` — the hourly request and error counters, for the traffic
        chart
          and its error strip.
        * ``latency`` — six fixed buckets summed over the same hourly window.
          Percentiles are bucket UPPER BOUNDS, never interpolated; see
          :class:`LatencySummary`.
        * ``recent`` — the per-key ring of the last ``RECENT_MAX`` requests,
        newest
          first. Route TEMPLATES only, so no request identifiers are retained.

        **Only the caller's own keys.** The prefixes are read from ``api_keys``

        filtered by ``user_id`` and never from user input, so there is no way to

        address another tenant's telemetry by asking for it.


        Fails SOFT: a Redis outage yields zeroes and empty lists, not a 500.
        This is

        a dashboard panel — a broken chart must not take down the page that also

        shows someone their API key. A zero here is visibly a zero; it is not

        presented as a measured absence of traffic.
      operationId: getKeyUsage
      parameters:
        - name: days
          in: query
          required: false
          schema:
            type: integer
            default: 30
            title: Days
        - name: hours
          in: query
          required: false
          schema:
            type: integer
            default: 24
            title: Hours
        - name: recent
          in: query
          required: false
          schema:
            type: integer
            default: 50
            title: Recent
        - name: authorization
          in: header
          required: false
          schema:
            anyOf:
              - type: string
              - type: 'null'
            title: Authorization
        - name: X-API-Key
          in: header
          required: false
          schema:
            anyOf:
              - type: string
              - type: 'null'
            title: X-Api-Key
        - name: POLY_API_KEY
          in: header
          required: false
          schema:
            anyOf:
              - type: string
              - type: 'null'
            title: Poly Api Key
        - name: Poly-API-Key
          in: header
          required: false
          schema:
            anyOf:
              - type: string
              - type: 'null'
            title: Poly-Api-Key
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/KeyUsage'
                title: Response Getkeyusage
          headers:
            X-RateLimit-Limit:
              description: >-
                Requests permitted in the current minute window for this key's
                tier.
              schema:
                type: string
            X-RateLimit-Remaining:
              description: Requests remaining in the current minute window.
              schema:
                type: string
            X-RateLimit-Reset:
              description: Unix-seconds timestamp when the current minute window resets.
              schema:
                type: string
            X-RateLimit-Limit-Per-Second:
              description: Requests permitted per second for this key's tier.
              schema:
                type: string
            X-RateLimit-Remaining-Per-Second:
              description: Requests remaining in the current one-second window.
              schema:
                type: string
            X-RateLimit-Tier:
              description: Rate-limit tier name applied to this request (free, pro, ...).
              schema:
                type: string
            X-Polysim-RateLimit-Limit:
              description: Alias of X-RateLimit-Limit (requests per minute for this tier).
              schema:
                type: string
            X-Polysim-RateLimit-Remaining:
              description: Alias of X-RateLimit-Remaining (requests remaining this minute).
              schema:
                type: string
            X-Polysim-RateLimit-Reset:
              description: Alias of X-RateLimit-Reset (minute-window reset, unix seconds).
              schema:
                type: string
            X-Polysim-RateLimit-Limit-Per-Second:
              description: Alias of X-RateLimit-Limit-Per-Second.
              schema:
                type: string
            X-Polysim-RateLimit-Remaining-Per-Second:
              description: Alias of X-RateLimit-Remaining-Per-Second.
              schema:
                type: string
            X-Polysim-RateLimit-Tier:
              description: Alias of X-RateLimit-Tier (tier name applied to this request).
              schema:
                type: string
            X-Request-Id:
              description: >-
                Request id for log correlation. Echoes the caller's
                ``X-Request-Id`` when supplied, otherwise a server-minted UUID.
                Stamped on every response (success and error).
              schema:
                type: string
        '401':
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
          headers:
            X-Polysim-Code:
              description: >-
                Stable short code identifying the error class. SDK consumers
                should branch on this header rather than the body text. Domain
                codes (INVALID_KEY, MARKET_NOT_FOUND, RATE_LIMIT_EXCEEDED, …)
                are preferred; HTTP_<status> fallbacks ship when no domain code
                applies. The full list is mirrored in /llms.txt under ‘Error
                Format’.
              schema:
                type: string
                enum:
                  - INVALID_KEY
                  - MISSING_API_KEY
                  - INSUFFICIENT_PERMISSION
                  - INSUFFICIENT_BALANCE
                  - MARKET_CLOSED
                  - INVALID_ORDER_MIN_TICK_SIZE
                  - MARKET_NOT_FOUND
                  - ORDER_NOT_FOUND
                  - RATE_LIMIT_EXCEEDED
                  - BOOK_UNAVAILABLE
                  - INVALID_TOKEN_ID
                  - VALIDATION_FAILED
                  - UPGRADE_REQUIRED
                  - ACCESS_RESTRICTED
                  - COHORT_FULL
                  - AUTH_STATE_INCOMPLETE
                  - INTERNAL_ERROR
                  - TOKEN_NOT_FOUND
                  - INVALID_CURSOR
                  - UPSTREAM_UNAVAILABLE
                  - UNSUPPORTED_ORDER_TYPE
                  - DUPLICATE_CLIENT_ORDER_ID
                  - ORDER_EXECUTION_FAILED
                  - DEADLINE_OVERSHOT_BUT_PERSISTED
                  - PERSISTENCE_UNKNOWN
                  - INVALID_BODY
                  - INVALID_SOURCE
                  - CLOSED_BETA
                  - API_PRO_COMING_SOON
                  - TIER_KEY_LIMIT_EXCEEDED
                  - INVALID_REQUEST
                  - INVALID_WINDOW
                  - BACKTEST_MONTHLY_CAP
                  - BACKTEST_MARKET_CAP
                  - BACKTEST_WINDOW_CAP
                  - SIMULATION_HOURS_EXCEEDED
                  - METERING_UNAVAILABLE
                  - JOB_STORE_UNAVAILABLE
                  - CONDITION_HOUR_NOT_COVERED
                  - ARCHIVE_UNAVAILABLE
                  - ARCHIVE_NOT_FOUND
                  - UNIVERSE_EXCLUDED
                  - IDEMPOTENCY_KEY_REUSE
                  - IDEMPOTENCY_CONFLICT_PENDING
                  - NOT_FOUND
                  - HTTP_400
                  - HTTP_401
                  - HTTP_403
                  - HTTP_404
                  - HTTP_409
                  - HTTP_422
                  - HTTP_429
                  - HTTP_500
                  - HTTP_502
                  - HTTP_503
            X-Request-Id:
              description: >-
                Request id for log correlation. Echoes the caller's
                ``X-Request-Id`` when supplied, otherwise a server-minted UUID.
                Stamped on every response (success and error).
              schema:
                type: string
        '403':
          description: Insufficient permission or access restricted.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
          headers:
            X-Polysim-Code:
              description: >-
                Stable short code identifying the error class. SDK consumers
                should branch on this header rather than the body text. Domain
                codes (INVALID_KEY, MARKET_NOT_FOUND, RATE_LIMIT_EXCEEDED, …)
                are preferred; HTTP_<status> fallbacks ship when no domain code
                applies. The full list is mirrored in /llms.txt under ‘Error
                Format’.
              schema:
                type: string
                enum:
                  - INVALID_KEY
                  - MISSING_API_KEY
                  - INSUFFICIENT_PERMISSION
                  - INSUFFICIENT_BALANCE
                  - MARKET_CLOSED
                  - INVALID_ORDER_MIN_TICK_SIZE
                  - MARKET_NOT_FOUND
                  - ORDER_NOT_FOUND
                  - RATE_LIMIT_EXCEEDED
                  - BOOK_UNAVAILABLE
                  - INVALID_TOKEN_ID
                  - VALIDATION_FAILED
                  - UPGRADE_REQUIRED
                  - ACCESS_RESTRICTED
                  - COHORT_FULL
                  - AUTH_STATE_INCOMPLETE
                  - INTERNAL_ERROR
                  - TOKEN_NOT_FOUND
                  - INVALID_CURSOR
                  - UPSTREAM_UNAVAILABLE
                  - UNSUPPORTED_ORDER_TYPE
                  - DUPLICATE_CLIENT_ORDER_ID
                  - ORDER_EXECUTION_FAILED
                  - DEADLINE_OVERSHOT_BUT_PERSISTED
                  - PERSISTENCE_UNKNOWN
                  - INVALID_BODY
                  - INVALID_SOURCE
                  - CLOSED_BETA
                  - API_PRO_COMING_SOON
                  - TIER_KEY_LIMIT_EXCEEDED
                  - INVALID_REQUEST
                  - INVALID_WINDOW
                  - BACKTEST_MONTHLY_CAP
                  - BACKTEST_MARKET_CAP
                  - BACKTEST_WINDOW_CAP
                  - SIMULATION_HOURS_EXCEEDED
                  - METERING_UNAVAILABLE
                  - JOB_STORE_UNAVAILABLE
                  - CONDITION_HOUR_NOT_COVERED
                  - ARCHIVE_UNAVAILABLE
                  - ARCHIVE_NOT_FOUND
                  - UNIVERSE_EXCLUDED
                  - IDEMPOTENCY_KEY_REUSE
                  - IDEMPOTENCY_CONFLICT_PENDING
                  - NOT_FOUND
                  - HTTP_400
                  - HTTP_401
                  - HTTP_403
                  - HTTP_404
                  - HTTP_409
                  - HTTP_422
                  - HTTP_429
                  - HTTP_500
                  - HTTP_502
                  - HTTP_503
            X-Request-Id:
              description: >-
                Request id for log correlation. Echoes the caller's
                ``X-Request-Id`` when supplied, otherwise a server-minted UUID.
                Stamped on every response (success and error).
              schema:
                type: string
        '404':
          description: Resource not found (market / order / token).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
          headers:
            X-Polysim-Code:
              description: >-
                Stable short code identifying the error class. SDK consumers
                should branch on this header rather than the body text. Domain
                codes (INVALID_KEY, MARKET_NOT_FOUND, RATE_LIMIT_EXCEEDED, …)
                are preferred; HTTP_<status> fallbacks ship when no domain code
                applies. The full list is mirrored in /llms.txt under ‘Error
                Format’.
              schema:
                type: string
                enum:
                  - INVALID_KEY
                  - MISSING_API_KEY
                  - INSUFFICIENT_PERMISSION
                  - INSUFFICIENT_BALANCE
                  - MARKET_CLOSED
                  - INVALID_ORDER_MIN_TICK_SIZE
                  - MARKET_NOT_FOUND
                  - ORDER_NOT_FOUND
                  - RATE_LIMIT_EXCEEDED
                  - BOOK_UNAVAILABLE
                  - INVALID_TOKEN_ID
                  - VALIDATION_FAILED
                  - UPGRADE_REQUIRED
                  - ACCESS_RESTRICTED
                  - COHORT_FULL
                  - AUTH_STATE_INCOMPLETE
                  - INTERNAL_ERROR
                  - TOKEN_NOT_FOUND
                  - INVALID_CURSOR
                  - UPSTREAM_UNAVAILABLE
                  - UNSUPPORTED_ORDER_TYPE
                  - DUPLICATE_CLIENT_ORDER_ID
                  - ORDER_EXECUTION_FAILED
                  - DEADLINE_OVERSHOT_BUT_PERSISTED
                  - PERSISTENCE_UNKNOWN
                  - INVALID_BODY
                  - INVALID_SOURCE
                  - CLOSED_BETA
                  - API_PRO_COMING_SOON
                  - TIER_KEY_LIMIT_EXCEEDED
                  - INVALID_REQUEST
                  - INVALID_WINDOW
                  - BACKTEST_MONTHLY_CAP
                  - BACKTEST_MARKET_CAP
                  - BACKTEST_WINDOW_CAP
                  - SIMULATION_HOURS_EXCEEDED
                  - METERING_UNAVAILABLE
                  - JOB_STORE_UNAVAILABLE
                  - CONDITION_HOUR_NOT_COVERED
                  - ARCHIVE_UNAVAILABLE
                  - ARCHIVE_NOT_FOUND
                  - UNIVERSE_EXCLUDED
                  - IDEMPOTENCY_KEY_REUSE
                  - IDEMPOTENCY_CONFLICT_PENDING
                  - NOT_FOUND
                  - HTTP_400
                  - HTTP_401
                  - HTTP_403
                  - HTTP_404
                  - HTTP_409
                  - HTTP_422
                  - HTTP_429
                  - HTTP_500
                  - HTTP_502
                  - HTTP_503
            X-Request-Id:
              description: >-
                Request id for log correlation. Echoes the caller's
                ``X-Request-Id`` when supplied, otherwise a server-minted UUID.
                Stamped on every response (success and error).
              schema:
                type: string
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
          headers:
            X-Polysim-Code:
              description: >-
                Stable short code identifying the error class. SDK consumers
                should branch on this header rather than the body text. Domain
                codes (INVALID_KEY, MARKET_NOT_FOUND, RATE_LIMIT_EXCEEDED, …)
                are preferred; HTTP_<status> fallbacks ship when no domain code
                applies. The full list is mirrored in /llms.txt under ‘Error
                Format’.
              schema:
                type: string
                enum:
                  - INVALID_KEY
                  - MISSING_API_KEY
                  - INSUFFICIENT_PERMISSION
                  - INSUFFICIENT_BALANCE
                  - MARKET_CLOSED
                  - INVALID_ORDER_MIN_TICK_SIZE
                  - MARKET_NOT_FOUND
                  - ORDER_NOT_FOUND
                  - RATE_LIMIT_EXCEEDED
                  - BOOK_UNAVAILABLE
                  - INVALID_TOKEN_ID
                  - VALIDATION_FAILED
                  - UPGRADE_REQUIRED
                  - ACCESS_RESTRICTED
                  - COHORT_FULL
                  - AUTH_STATE_INCOMPLETE
                  - INTERNAL_ERROR
                  - TOKEN_NOT_FOUND
                  - INVALID_CURSOR
                  - UPSTREAM_UNAVAILABLE
                  - UNSUPPORTED_ORDER_TYPE
                  - DUPLICATE_CLIENT_ORDER_ID
                  - ORDER_EXECUTION_FAILED
                  - DEADLINE_OVERSHOT_BUT_PERSISTED
                  - PERSISTENCE_UNKNOWN
                  - INVALID_BODY
                  - INVALID_SOURCE
                  - CLOSED_BETA
                  - API_PRO_COMING_SOON
                  - TIER_KEY_LIMIT_EXCEEDED
                  - INVALID_REQUEST
                  - INVALID_WINDOW
                  - BACKTEST_MONTHLY_CAP
                  - BACKTEST_MARKET_CAP
                  - BACKTEST_WINDOW_CAP
                  - SIMULATION_HOURS_EXCEEDED
                  - METERING_UNAVAILABLE
                  - JOB_STORE_UNAVAILABLE
                  - CONDITION_HOUR_NOT_COVERED
                  - ARCHIVE_UNAVAILABLE
                  - ARCHIVE_NOT_FOUND
                  - UNIVERSE_EXCLUDED
                  - IDEMPOTENCY_KEY_REUSE
                  - IDEMPOTENCY_CONFLICT_PENDING
                  - NOT_FOUND
                  - HTTP_400
                  - HTTP_401
                  - HTTP_403
                  - HTTP_404
                  - HTTP_409
                  - HTTP_422
                  - HTTP_429
                  - HTTP_500
                  - HTTP_502
                  - HTTP_503
            X-Request-Id:
              description: >-
                Request id for log correlation. Echoes the caller's
                ``X-Request-Id`` when supplied, otherwise a server-minted UUID.
                Stamped on every response (success and error).
              schema:
                type: string
        '429':
          description: Rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
          headers:
            X-Polysim-Code:
              description: >-
                Stable short code identifying the error class. SDK consumers
                should branch on this header rather than the body text. Domain
                codes (INVALID_KEY, MARKET_NOT_FOUND, RATE_LIMIT_EXCEEDED, …)
                are preferred; HTTP_<status> fallbacks ship when no domain code
                applies. The full list is mirrored in /llms.txt under ‘Error
                Format’.
              schema:
                type: string
                enum:
                  - INVALID_KEY
                  - MISSING_API_KEY
                  - INSUFFICIENT_PERMISSION
                  - INSUFFICIENT_BALANCE
                  - MARKET_CLOSED
                  - INVALID_ORDER_MIN_TICK_SIZE
                  - MARKET_NOT_FOUND
                  - ORDER_NOT_FOUND
                  - RATE_LIMIT_EXCEEDED
                  - BOOK_UNAVAILABLE
                  - INVALID_TOKEN_ID
                  - VALIDATION_FAILED
                  - UPGRADE_REQUIRED
                  - ACCESS_RESTRICTED
                  - COHORT_FULL
                  - AUTH_STATE_INCOMPLETE
                  - INTERNAL_ERROR
                  - TOKEN_NOT_FOUND
                  - INVALID_CURSOR
                  - UPSTREAM_UNAVAILABLE
                  - UNSUPPORTED_ORDER_TYPE
                  - DUPLICATE_CLIENT_ORDER_ID
                  - ORDER_EXECUTION_FAILED
                  - DEADLINE_OVERSHOT_BUT_PERSISTED
                  - PERSISTENCE_UNKNOWN
                  - INVALID_BODY
                  - INVALID_SOURCE
                  - CLOSED_BETA
                  - API_PRO_COMING_SOON
                  - TIER_KEY_LIMIT_EXCEEDED
                  - INVALID_REQUEST
                  - INVALID_WINDOW
                  - BACKTEST_MONTHLY_CAP
                  - BACKTEST_MARKET_CAP
                  - BACKTEST_WINDOW_CAP
                  - SIMULATION_HOURS_EXCEEDED
                  - METERING_UNAVAILABLE
                  - JOB_STORE_UNAVAILABLE
                  - CONDITION_HOUR_NOT_COVERED
                  - ARCHIVE_UNAVAILABLE
                  - ARCHIVE_NOT_FOUND
                  - UNIVERSE_EXCLUDED
                  - IDEMPOTENCY_KEY_REUSE
                  - IDEMPOTENCY_CONFLICT_PENDING
                  - NOT_FOUND
                  - HTTP_400
                  - HTTP_401
                  - HTTP_403
                  - HTTP_404
                  - HTTP_409
                  - HTTP_422
                  - HTTP_429
                  - HTTP_500
                  - HTTP_502
                  - HTTP_503
            X-Request-Id:
              description: >-
                Request id for log correlation. Echoes the caller's
                ``X-Request-Id`` when supplied, otherwise a server-minted UUID.
                Stamped on every response (success and error).
              schema:
                type: string
components:
  schemas:
    KeyUsage:
      properties:
        key_prefix:
          type: string
          title: Key Prefix
        days:
          items:
            $ref: '#/components/schemas/UsageDay'
          type: array
          title: Days
        month_to_date:
          type: integer
          title: Month To Date
          description: Sum over the current UTC calendar month
        monthly_request_cap:
          type: integer
          title: Monthly Request Cap
          description: >-
            Requests this key may make in one UTC calendar month, from its
            rate-limit tier. Reported so a caller can see the headroom before it
            matters; NOT enforced yet.
        hours:
          items:
            $ref: '#/components/schemas/UsageHour'
          type: array
          title: Hours
          description: Hourly buckets, oldest first, over the requested `hours` window
        latency:
          $ref: '#/components/schemas/LatencySummary'
          description: Approximate latency over the same window
        recent:
          items:
            $ref: '#/components/schemas/RecentRequest'
          type: array
          title: Recent
          description: Most recent requests for this key, newest first
      type: object
      required:
        - key_prefix
        - days
        - month_to_date
        - monthly_request_cap
        - latency
      title: KeyUsage
    ApiError:
      properties:
        error:
          type: string
          title: Error
          description: Stable machine-readable error code; also returned in X-Polysim-Code.
        message:
          anyOf:
            - type: string
            - type: 'null'
          title: Message
          description: Human-readable error description. Never branch on this value.
        details:
          anyOf:
            - additionalProperties: true
              type: object
            - type: 'null'
          title: Details
          description: Additional context populated for verbose responses.
        request_id:
          anyOf:
            - type: string
            - type: 'null'
          title: Request Id
          description: Support correlation id; always returned in X-Request-Id.
      type: object
      required:
        - error
      title: ApiError
      description: |-
        Structured error response for all API v1 endpoints.

        ``error`` is the stable machine-readable code and ``message`` is human
        prose. SDK consumers must branch on ``error`` (or the identical
        ``X-Polysim-Code`` header), never on ``message``. Diagnostic ``details``
        and the in-body ``request_id`` are added only when callers opt in with
        ``X-Polysim-Verbose: true``; ``X-Request-Id`` is always present.
    UsageDay:
      properties:
        date:
          type: string
          title: Date
          description: UTC day, YYYY-MM-DD
        requests:
          type: integer
          title: Requests
          description: Requests counted against this key that day
      type: object
      required:
        - date
        - requests
      title: UsageDay
    UsageHour:
      properties:
        hour:
          type: string
          title: Hour
          description: Start of the UTC hour, ISO-8601 (YYYY-MM-DDTHH:00:00Z)
        requests:
          type: integer
          title: Requests
          description: Requests counted against this key in that hour
        errors:
          type: integer
          title: Errors
          description: Responses with status >= 400 in that hour
      type: object
      required:
        - hour
        - requests
        - errors
      title: UsageHour
    LatencySummary:
      properties:
        samples:
          type: integer
          title: Samples
          description: Requests with a latency bucket in the window
        p50_ms:
          anyOf:
            - type: integer
            - type: 'null'
          title: P50 Ms
          description: >-
            Upper bound of the bucket holding the p50; null if >= 1000 ms or no
            samples
        p99_ms:
          anyOf:
            - type: integer
            - type: 'null'
          title: P99 Ms
          description: >-
            Upper bound of the bucket holding the p99; null if >= 1000 ms or no
            samples
        buckets:
          additionalProperties:
            type: integer
          type: object
          title: Buckets
          description: >-
            Counts per bucket, keyed by exclusive upper bound in ms ('50',
            '100', '250', '500', '1000') plus 'inf' for >= 1000 ms
      type: object
      required:
        - samples
      title: LatencySummary
      description: >-
        Approximate latency over the returned hourly window.


        Six fixed counters, not a histogram, so the percentiles are **bucket
        upper

        bounds** rather than measured values: ``p50_ms: 250`` means "the median
        is

        at most 250 ms". ``null`` means the percentile falls in the >= 1000 ms

        overflow bucket, where there is no upper bound, or that there were no

        samples. ``buckets`` is returned so a client can render the true range

        instead of inferring a false precision from a single number.
    RecentRequest:
      properties:
        status:
          type: integer
          title: Status
          description: HTTP status code
        method:
          type: string
          title: Method
          description: HTTP method
        route:
          type: string
          title: Route
          description: >-
            Route template, e.g. /v1/markets/{condition_id} — never the raw
            path, so no request identifiers are retained
        latency_ms:
          type: integer
          title: Latency Ms
          description: Server-side duration in milliseconds
        at:
          type: string
          title: At
          description: When the request completed, ISO-8601 UTC to the second
      type: object
      required:
        - status
        - method
        - route
        - latency_ms
        - at
      title: RecentRequest
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
      description: Issue from /v1/keys (or admin-issued for enterprise tier).

````