> ## 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.

# Read a wallet's unpaid trading fees per venue

> Preview: available on staging (`https://staging-execution.kairos.trade`); not yet released in production, where trade plans — the only source of this fee debt — return `503`.

Trades placed through **trade plans** on Polymarket and Predict.fun accrue the Kairos fee and the partner fee as a debt per wallet and collateral asset; nothing is deducted inside the order. This read returns the debt per venue, the threshold at which `POST /v3/trade-plans` refuses new trades with `FEE_SETTLEMENT_REQUIRED`, and any open settlement.

`owedRaw` is a signed integer string in token base units: it is **negative** when confirmed payments exceed the fees booked so far (a credit carried against later fees). The threshold is set by Kairos per partner. A venue whose settlement rail is not offered is omitted.

Reading also advances settlements: it refreshes the open settlement from chain evidence and credits late payments. Hyperliquid has no fee debt on this API.



## OpenAPI

````yaml /openapi/wallet-api.json get /v3/fees
openapi: 3.1.0
info:
  title: Kairos Partner API
  version: 1.0.0
  description: >-
    Self-custody trading for wallets and apps: Kairos builds each step, the
    user's wallet signs it. Every operation is under `/v3`. Guides:
    https://docs.kairos.trade/wallets/overview
servers:
  - url: https://execution.kairos.trade
    description: Production
  - url: https://staging-execution.kairos.trade
    description: Staging
security: []
tags:
  - name: Actions
    description: >-
      Start `setup`, `order`, `cancel` and `login` actions and answer their
      steps. Live. Send `X-Kairos-Wallet-Api: 2`.
  - name: Reads
    description: >-
      Wallet readiness and balances per venue (partner id or API key, no wallet
      proof), and the wallet's orders and positions (also needs `Authorization:
      SIWE <token>` from a `login` action). Live.
  - name: Trade plans (preview)
    description: >-
      One buy order authorized up front in one signature batch, with a fee
      ceiling and deadlines, optionally funded by bridging the exact shortfall
      from Polygon or Arbitrum USDC. Preview: staging only; production returns
      `503` until release.
  - name: Fees (preview)
    description: >-
      Trading fees from trade plans accrue as a debt per wallet and are paid in
      one settlement — a gasless signature on Polymarket, a USDT transfer on
      Predict.fun. Preview: staging only.
  - name: On-chain intents (preview)
    description: >-
      Split, merge or redeem conditional tokens on a Polymarket deposit wallet
      with two signatures and no gas; Kairos confirms from the finalized
      receipt. Preview: staging only; production returns `503` until release.
paths:
  /v3/fees:
    get:
      tags:
        - Fees (preview)
      summary: Read a wallet's unpaid trading fees per venue
      description: >-
        Preview: available on staging
        (`https://staging-execution.kairos.trade`); not yet released in
        production, where trade plans — the only source of this fee debt —
        return `503`.


        Trades placed through **trade plans** on Polymarket and Predict.fun
        accrue the Kairos fee and the partner fee as a debt per wallet and
        collateral asset; nothing is deducted inside the order. This read
        returns the debt per venue, the threshold at which `POST
        /v3/trade-plans` refuses new trades with `FEE_SETTLEMENT_REQUIRED`, and
        any open settlement.


        `owedRaw` is a signed integer string in token base units: it is
        **negative** when confirmed payments exceed the fees booked so far (a
        credit carried against later fees). The threshold is set by Kairos per
        partner. A venue whose settlement rail is not offered is omitted.


        Reading also advances settlements: it refreshes the open settlement from
        chain evidence and credits late payments. Hyperliquid has no fee debt on
        this API.
      operationId: getWalletFees
      parameters:
        - $ref: '#/components/parameters/WalletAddressQuery'
      responses:
        '200':
          description: Debt per venue.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WalletFeeSummary'
        '400':
          description: >-
            `wallet must be a 0x address`. Plain text for a missing `wallet` or
            any other query parameter. With API-key wallet proof a malformed
            `wallet` is `404 wallet not found` instead.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WalletApiError'
            text/plain:
              schema:
                $ref: '#/components/schemas/WalletPlainTextError'
        '401':
          $ref: '#/components/responses/WalletSignInUnauthorized'
        '403':
          $ref: '#/components/responses/WalletScopeForbidden'
        '404':
          $ref: '#/components/responses/WalletNotFound'
        '429':
          $ref: '#/components/responses/WalletRateLimited'
        '500':
          $ref: '#/components/responses/WalletInternalError'
        '503':
          $ref: '#/components/responses/WalletFeesUnavailable'
      security:
        - walletPartnerId: []
          walletSignIn: []
        - apiKeyClientId: []
          apiKeyKey: []
          apiKeySecret: []
          walletSignIn: []
        - apiKeyClientId: []
          apiKeyKey: []
          apiKeySecret: []
        - walletPartnerId: []
          apiKeyClientId: []
          apiKeyKey: []
          apiKeySecret: []
        - walletPartnerId: []
          bearerAuth: []
components:
  parameters:
    WalletAddressQuery:
      name: wallet
      in: query
      required: true
      description: The wallet's EVM address. No other query parameter is accepted.
      schema:
        type: string
        pattern: ^0x[0-9a-fA-F]{40}$
      example: '0x8ba1f109551bd432803012645ac136ddd64dba72'
  schemas:
    WalletFeeSummary:
      type: object
      description: Response of `GET /v3/fees`.
      required:
        - venues
      properties:
        venues:
          type: array
          items:
            $ref: '#/components/schemas/WalletFeeVenue'
      example:
        venues:
          - venue: polymarket
            holdingWallet: '0x2f9c4b8e1d7a6c5b4a3f2e1d0c9b8a7f6e5d4c3b'
            assetKey: evm:137:0xc011a7e12a19f7b1f670d46f03b03f3342e82dfb
            decimals: 6
            owedRaw: '400000'
            thresholdRaw: '10000000'
            settlement: null
          - venue: predictfun
            holdingWallet: '0x8ba1f109551bd432803012645ac136ddd64dba72'
            assetKey: evm:56:0x55d398326f99059ff775485246999027b3197955
            decimals: 18
            owedRaw: '0'
            thresholdRaw: '10000000000000000000'
            settlement: null
    WalletApiError:
      type: object
      description: >-
        Wallet API error body. `error` is a human-readable message; `code` is
        set on a few structured refusals (e.g. `CLIENT_ORDER_ID_CONFLICT`,
        `POLYMARKET_V2_TRADING_DISABLED`, `SIGNATURE_EXPIRED`); `errorCode`
        mirrors `code` where the same refusal can also surface on a failed step.
        Most `/v3` errors carry only `error`. Framework rejections (malformed
        JSON, wrong shape, missing content type) are plain text, not this body.
      required:
        - error
      properties:
        error:
          type: string
          description: Human-readable message.
        code:
          type: string
          description: Stable code, present on structured refusals only.
        errorCode:
          type: string
          description: >-
            Same as `code`; present where the refusal can also appear as a
            failed step's `errorCode`.
      example:
        error: unknown or expired action
    WalletPlainTextError:
      type: string
      description: >-
        A plain-text (non-JSON) rejection from request parsing — malformed JSON,
        a body of the wrong shape, a missing `Content-Type`, a malformed path id
        or query. Do not JSON-parse it.
      example: >-
        Failed to deserialize the JSON body into the target type: action.price:
        invalid type: floating point `0.52`, expected a string
    WalletFeeVenue:
      type: object
      description: Fee debt on one venue. Values are integer strings in token base units.
      required:
        - venue
        - holdingWallet
        - assetKey
        - decimals
        - owedRaw
        - thresholdRaw
        - settlement
      properties:
        venue:
          type: string
          enum:
            - polymarket
            - predictfun
        holdingWallet:
          type: string
        assetKey:
          type: string
          example: evm:137:0xc011a7e12a19f7b1f670d46f03b03f3342e82dfb
        decimals:
          type: integer
          example: 6
        owedRaw:
          type: string
          description: >-
            Unpaid Kairos and partner fees, minus confirmed payments. **May be
            negative** (a credit against later fees).
          example: '-250000'
        thresholdRaw:
          type: string
          description: >-
            At or above this, new trade plans are refused with
            `FEE_SETTLEMENT_REQUIRED`.
          example: '10000000'
        settlement:
          description: >-
            The settlement that was open when this read started, refreshed by it
            — so it may already be `confirmed`, `failed` or `expired`. `null`
            when none was open.
          oneOf:
            - $ref: '#/components/schemas/WalletFeeSettlement'
            - type: 'null'
    WalletFeeSettlement:
      type: object
      description: >-
        A payment of a wallet's unpaid fees on one venue. The amount is frozen
        when the settlement opens.
      required:
        - id
        - venue
        - status
        - holdingWallet
        - assetKey
        - chainId
        - token
        - treasury
        - decimals
        - amountRaw
        - transactionHash
        - expiresAt
        - failure
        - walletRequest
      properties:
        id:
          type: string
          format: uuid
        venue:
          type: string
          enum:
            - polymarket
            - predictfun
        status:
          type: string
          enum:
            - awaiting_signature
            - submitted
            - confirmed
            - failed
            - expired
          description: >-
            `awaiting_signature` → `submitted` → `confirmed`. Terminal:
            `confirmed` and `failed`. `expired` is final unless it is a
            Predict.fun settlement whose reported transaction lands within 7
            days of expiring: `GET /v3/fees` or `POST /v3/fees/settlements` then
            credits it and it becomes `confirmed` (`GET
            /v3/fees/settlements/{id}` does not re-check an expired settlement).
        holdingWallet:
          type: string
          description: >-
            Address the fee is paid from — Polymarket's trading wallet, or the
            wallet itself on Predict.fun.
        assetKey:
          type: string
          example: evm:137:0xc011a7e12a19f7b1f670d46f03b03f3342e82dfb
        chainId:
          type: string
          description: Chain id as a **decimal** string (`walletRequest.chainId` is hex).
          example: '137'
        token:
          type: string
          description: Fee token (pUSD on Polygon, USDT on BNB Chain).
        treasury:
          type: string
          description: The payee address.
        decimals:
          type: integer
          description: Token decimals (6 for pUSD, 18 for BNB Chain USDT).
        amountRaw:
          type: string
          description: Amount to pay, integer string in token base units.
        transactionHash:
          type:
            - string
            - 'null'
          description: The payment transaction, once known.
        expiresAt:
          type:
            - string
            - 'null'
          format: date-time
          description: >-
            Polymarket — sign before this (30 minutes after opening). `null` on
            Predict.fun.
        failure:
          type:
            - string
            - 'null'
          description: >-
            Why the settlement failed or expired. Kept when a late Predict.fun
            payment later confirms an `expired` settlement.
        walletRequest:
          description: Present only while `awaiting_signature`.
          oneOf:
            - $ref: '#/components/schemas/WalletFeeWalletRequest'
            - type: 'null'
      example:
        id: 4e1d2c3b-5a6f-4b7c-8d9e-0f1a2b3c4d5e
        venue: polymarket
        status: awaiting_signature
        holdingWallet: '0x2f9c4b8e1d7a6c5b4a3f2e1d0c9b8a7f6e5d4c3b'
        assetKey: evm:137:0xc011a7e12a19f7b1f670d46f03b03f3342e82dfb
        chainId: '137'
        token: '0xc011a7e12a19f7b1f670d46f03b03f3342e82dfb'
        treasury: '0x3333333333333333333333333333333333333333'
        decimals: 6
        amountRaw: '12500000'
        transactionHash: null
        expiresAt: '2026-10-28T12:30:00Z'
        failure: null
        walletRequest:
          kind: signature
          chainId: '0x89'
          request:
            method: eth_signTypedData_v4
            params:
              - '0x8ba1f109551bd432803012645ac136ddd64dba72'
              - >-
                {"types":{"EIP712Domain":[…],"Batch":[{"name":"wallet","type":"address"},{"name":"nonce","type":"uint256"},{"name":"deadline","type":"uint256"},{"name":"calls","type":"Call[]"}],"Call":[…]},"domain":{"name":"DepositWallet","version":"1","chainId":"137","verifyingContract":"0x2f9c…4c3b"},"primaryType":"Batch","message":{…}}
    WalletFeeWalletRequest:
      type: object
      description: >-
        What the wallet runs to pay a settlement. `kind: signature` (Polymarket)
        — sign it and answer with `signature`; `kind: transaction` (Predict.fun)
        — send it unchanged and answer with `transactionHash`.
      required:
        - kind
        - chainId
        - request
      properties:
        kind:
          type: string
          enum:
            - signature
            - transaction
        chainId:
          type: string
          description: Chain to switch to, **hex** (`0x89` or `0x38`).
        request:
          $ref: '#/components/schemas/WalletEip1193Request'
      example:
        kind: transaction
        chainId: '0x38'
        request:
          method: eth_sendTransaction
          params:
            - from: '0x8ba1f109551bd432803012645ac136ddd64dba72'
              to: '0x55d398326f99059ff775485246999027b3197955'
              value: '0x0'
              data: >-
                0xa9059cbb0000000000000000000000003333333333333333333333333333333333333333000000000000000000000000000000000000000000000000ad78ebc5ac620000
              chainId: '0x38'
    WalletEip1193Request:
      type: object
      description: >-
        An EIP-1193 request to run through the wallet's provider exactly as
        given (`provider.request({method, params})`).

        - `eth_signTypedData_v4`: `params` = `[address, typedData]` —
        `typedData` is a **JSON string**; pass it unchanged.

        - `personal_sign`: `params` = `[hexMessage, address]`.

        - `wallet_sendCalls` (EIP-5792): `params` = `[{version, chainId, from,
        atomicRequired, calls}]`; the wallet pays gas.

        - `eth_sendTransaction`: `params` = `[{from, to, data, value,
        chainId?}]`; the wallet pays gas.
      required:
        - method
        - params
      properties:
        method:
          type: string
          enum:
            - eth_signTypedData_v4
            - personal_sign
            - wallet_sendCalls
            - eth_sendTransaction
        params:
          type: array
          items: {}
      example:
        method: personal_sign
        params:
          - 0x6b6169726f732e7472616465207761…
          - '0x8ba1f109551bD432803012645Ac136ddd64DBA72'
  responses:
    WalletSignInUnauthorized:
      description: >-
        Tenant failures (`send X-Kairos-Partner-Id or your API key (X-Client-Id,
        X-Api-Key, X-Api-Secret)`, `invalid API key`), or the wallet proof
        failed:

        - `malformed sign-in token` — not `SIWE <token>` as issued, over 4096
        bytes, or an invalid lifetime

        - `sign-in token was issued for another partner or node` — issued for
        another partner or environment

        - `sign-in token has expired; run a login action`

        - `sign-in token signature is not from its wallet`

        - `Missing authorization` — no `Authorization` header and no API key to
        prove the wallet; `Invalid API credentials`, `API credential has been
        revoked` or `Invalid token` when the proving credential is not `SIWE`
        and fails
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/WalletApiError'
          example:
            error: sign-in token has expired; run a login action
    WalletScopeForbidden:
      description: >-
        `API key missing trade:read scope` (reads) or `API key missing
        trade:execute scope` (writes) when an API key is the caller —
        `trade:execute` does not imply `trade:read`; or a tenant refusal:
        `unknown partner id`, `this partner id is used with its API key; send
        the key instead of X-Kairos-Partner-Id`, `this API key lacks the
        trade:execute scope`, `the wallet API is not enabled for this account`.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/WalletApiError'
          example:
            error: API key missing trade:read scope
    WalletNotFound:
      description: >-
        `wallet not found` — the sign-in token was signed by a different wallet,
        the API key's account does not own the wallet, or the wallet has never
        been set up.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/WalletApiError'
          example:
            error: wallet not found
    WalletRateLimited:
      description: >-
        `rate limit exceeded for this endpoint; retry later`. The default limit
        is 120 requests per minute per client IP per path (1000 when
        `X-Client-Id` is sent), over a sliding 60 s window; `GET` and `POST` on
        one path share it. No `Retry-After` header is sent.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/WalletApiError'
          example:
            error: rate limit exceeded for this endpoint; retry later
    WalletInternalError:
      description: '`internal error`.'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/WalletApiError'
          example:
            error: internal error
    WalletFeesUnavailable:
      description: >-
        `fee settlement storage is unavailable`; `the BNB Chain treasury is
        unavailable`; another settlement dependency is unavailable; `the chain
        RPC is unavailable`; `partner registry unavailable; retry shortly`;
        `rate limiter unavailable`. Retry later.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/WalletApiError'
  securitySchemes:
    walletPartnerId:
      type: apiKey
      in: header
      name: X-Kairos-Partner-Id
      description: >-
        Wallet API partner id, issued by Kairos together with the partner's base
        URL. Identifies the partner (tenant) on every `/v3` call; sent instead
        of an API key. Letters, digits and `._:-`, at most 64 characters,
        case-insensitive. A partner id issued for an individual account cannot
        be sent this way — that account sends its API key triple instead.
    walletSignIn:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        Wallet sign-in token: `SIWE <token>`, where `<token>` is `result.token`
        from a `login` action (exactly one space after `SIWE`). Proves the
        wallet on reads of its orders and positions, and on trade plans, fee
        settlements and on-chain intents. The token is bound to the partner and
        the environment that issued it and lasts 24 hours; run a new `login`
        action to renew it.
    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.
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >-
        First-party Kairos session JWT (web app sessions). Not issued to API
        consumers.

````

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