> ## 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 trader's PnL windows, win/loss, ROI distribution and daily PnL calendar

> Returns the trader profile's analysis panel: realized PnL and buy count over the 1D, 7D, 30D and ALL windows (whole UTC days ending today; 1D is today only), lifetime winning/losing closed positions and win rate, the distribution of closed positions by ROI (realized PnL over the cost bought for the position), and daily realized PnL for the last 90 UTC days that have activity. Only venues whose trades flow through the lot allocator (Predict.fun) are supported; for any other venue `supported` is false and no figures are returned. **Public endpoint — no authentication required** (trader data is public). Rate-limited per client IP. Cached per wallet for up to a minute.




## OpenAPI

````yaml /openapi/data-api.yaml get /trader-stats/analysis/{wallet_address}
openapi: 3.1.0
info:
  title: Kairos Data API
  version: 1.0.0
  summary: >-
    The full Kairos data plane — markets, candles, trades, search, discover,
    sports, trader analytics, and PnL.
  description: |
    The Kairos Data API at `data.kairos.trade` is the platform's primary data
    plane: market metadata and prices, OHLCV candles, live venue trade proxies,
    normalized trade history, full-text search, discovery feeds, the sports
    catalog, public trader analytics, and account PnL.

    ## Authentication

    Most endpoints accept a Kairos **API key** (`X-Client-Id` + `X-Api-Key` +
    `X-Api-Secret`, all three) or a first-party session JWT. Endpoints tagged
    `public` (trader analytics, provider configs, several sports feeds) need
    no credentials at all. Some endpoints additionally require an API-key
    **scope** (`trade:read`, `position:read`) — stated per operation.

    For high-volume market-data consumption (candles/trades/metadata at
    scale), prefer the dedicated **Market Data API** at `md.kairos.trade` —
    it has higher budgets, ETag caching, and a binary candle format.

    ## Rate limits

    Rate limits use a sliding window keyed on the authenticated user (JWT
    `sub`) or, for anonymous callers, the trusted client IP. Routes belong to
    a named **bucket** (`x-kairos-bucket`) whose per-minute budget is shared
    by every route in it; routes with no bucket run under the service default
    of 100/minute. `x-kairos-rate-limit` states the bucket's compile-time
    default — operators can raise or lower a bucket at runtime, so treat the
    documented number as the baseline, not a contract. 429 responses carry
    `Retry-After` and `X-RateLimit-*`.

    ## Conventions

    - Prices are on the **0–100 cents scale** unless a field says otherwise
      (trader-analytics position/trade prices use the 0–1 scale; each field's
      description states its scale).
    - Errors: `{"detail": "<message>"}` for handler errors; FastAPI's
      standard validation envelope for 422s. Errors surfaced from a venue
      adapter instead use `{"error", "provider", "operation", "message"}` —
      see `DataProviderError`. Unhandled failures always return the generic
      500 body; internal details are logged, never returned.
    - Every request body is capped at 8 MiB service-wide (413).
  contact:
    name: Kairos
    url: https://app.kairos.trade/docs/api-reference
  termsOfService: https://kairos.trade/terms
servers:
  - url: https://data.kairos.trade
    description: Production
  - url: https://staging-data.kairos.trade
    description: Staging
security:
  - apiKeyClientId: []
    apiKeyKey: []
    apiKeySecret: []
paths:
  /trader-stats/analysis/{wallet_address}:
    get:
      tags:
        - Trader Analytics
      summary: >-
        Get a trader's PnL windows, win/loss, ROI distribution and daily PnL
        calendar
      description: >
        Returns the trader profile's analysis panel: realized PnL and buy count
        over the 1D, 7D, 30D and ALL windows (whole UTC days ending today; 1D is
        today only), lifetime winning/losing closed positions and win rate, the
        distribution of closed positions by ROI (realized PnL over the cost
        bought for the position), and daily realized PnL for the last 90 UTC
        days that have activity. Only venues whose trades flow through the lot
        allocator (Predict.fun) are supported; for any other venue `supported`
        is false and no figures are returned. **Public endpoint — no
        authentication required** (trader data is public). Rate-limited per
        client IP. Cached per wallet for up to a minute.
      operationId: getTraderAnalysis
      parameters:
        - name: wallet_address
          in: path
          required: true
          schema:
            type: string
          description: Ethereum or Solana wallet address.
          example: '0x1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b'
        - name: provider
          in: query
          required: false
          schema:
            type: string
          description: >-
            Provider override (polymarket, kalshi, opinion, predictfun).
            Auto-detected if omitted.
          example: predictfun
      responses:
        '200':
          description: >-
            The analysis panel, or `supported` false for a venue without
            allocator data.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TraderAnalysisResponse'
        '400':
          description: Malformed wallet address or unrecognized provider.
        '422':
          $ref: '#/components/responses/DataValidationError'
        '429':
          $ref: '#/components/responses/DataRateLimited'
        '500':
          description: Unexpected error fetching trader analysis.
      security: []
components:
  schemas:
    TraderAnalysisResponse:
      type: object
      description: >
        A trader profile's analysis panel. `supported` is false, with empty
        `windows` and `daily` and null `win_loss` and `roi_distribution`, for a
        venue whose trades do not flow through the lot allocator.
      required:
        - wallet_address
        - supported
        - windows
        - daily
        - win_loss
        - roi_distribution
      properties:
        wallet_address:
          type: string
          example: '0x1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b'
        provider:
          type: string
          nullable: true
          example: predictfun
        supported:
          type: boolean
        windows:
          type: array
          items:
            $ref: '#/components/schemas/TraderAnalysisWindow'
        daily:
          type: array
          description: The last 90 UTC days that have activity, oldest first.
          items:
            $ref: '#/components/schemas/TraderAnalysisDay'
        win_loss:
          nullable: true
          allOf:
            - $ref: '#/components/schemas/TraderAnalysisWinLoss'
        roi_distribution:
          nullable: true
          description: >-
            Null when unsupported, or when the ROI read failed and the rest of
            the panel was served without it.
          allOf:
            - $ref: '#/components/schemas/TraderRoiDistribution'
    TraderAnalysisWindow:
      type: object
      description: Realized PnL and buys over whole UTC days ending today.
      required:
        - window
        - realized_pnl
        - buy_count
      properties:
        window:
          type: string
          enum:
            - 1D
            - 7D
            - 30D
            - ALL
        realized_pnl:
          type: number
          description: Realized PnL in USD.
          example: 15.3
        buy_count:
          type: integer
          minimum: 0
          example: 16
    TraderAnalysisDay:
      type: object
      required:
        - day
        - realized_pnl
      properties:
        day:
          type: string
          format: date
          example: '2026-09-28'
        realized_pnl:
          type: number
          description: Realized PnL in USD booked that UTC day.
          example: -25.82
    TraderAnalysisWinLoss:
      type: object
      description: >-
        Lifetime closed-position counts. `win_rate` is winning over winning plus
        losing, 0 when none has closed.
      required:
        - winning_positions
        - losing_positions
        - win_rate
      properties:
        winning_positions:
          type: integer
          minimum: 0
          example: 13
        losing_positions:
          type: integer
          minimum: 0
          example: 11
        win_rate:
          type: number
          minimum: 0
          maximum: 1
          example: 0.5417
    TraderRoiDistribution:
      type: object
      description: >-
        Closed positions counted by ROI, the position's realized PnL over the
        total cost bought for it. Positions with no bought cost are left out.
      required:
        - gt_500
        - between_200_500
        - between_0_200
        - between_neg_50_0
        - lt_neg_50
      properties:
        gt_500:
          type: integer
          minimum: 0
          description: ROI above 500%.
        between_200_500:
          type: integer
          minimum: 0
          description: ROI above 200% up to 500%.
        between_0_200:
          type: integer
          minimum: 0
          description: ROI from 0% to 200%.
        between_neg_50_0:
          type: integer
          minimum: 0
          description: ROI from -50% up to, but not including, 0%.
        lt_neg_50:
          type: integer
          minimum: 0
          description: ROI below -50%.
  responses:
    DataValidationError:
      description: Request failed FastAPI parameter validation.
      content:
        application/json:
          schema:
            type: object
            required:
              - detail
            properties:
              detail:
                type: array
                description: >-
                  One entry per failed field, with location, message, and error
                  type.
                items:
                  type: object
                  additionalProperties: true
    DataRateLimited:
      description: >
        Rate limit exceeded for this route's sliding window, keyed on the
        session `sub` when

        authenticated and on the trusted client IP otherwise. Honor
        `Retry-After`. A per-API-key

        data ceiling (set per credential) rejects with `{"detail": "API key data
        rate limit

        exceeded"}` instead of the `error` envelope below.
      headers:
        Retry-After:
          schema:
            type: integer
        X-RateLimit-Limit:
          schema:
            type: integer
        X-RateLimit-Remaining:
          schema:
            type: integer
        X-RateLimit-Reset:
          schema:
            type: integer
      content:
        application/json:
          schema:
            type: object
            properties:
              error:
                type: string
                example: 'Rate limit exceeded: 100 per 1 minute'
  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.
    apiKeySecret:
      type: apiKey
      in: header
      name: X-Api-Secret
      description: 64-char hex API secret.

````

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