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

# Propose a swap

> Quotes the swap on the Uniswap Trading API, builds the batch (an approval for exactly the sell amount when needed, then the swap) and proposes it like `/propose`. Base and Ethereum wallets only. One credit when the judge runs.



## OpenAPI

````yaml /openapi.json post /api/v1/wallets/{id}/swap
openapi: 3.0.3
info:
  title: Chance API
  version: 1.0.0
  description: >-
    Verify an agent's proposed action against its rules, manage escrow wallets,
    and buy credits. Every verification returns a signed, hash-chained receipt.
servers:
  - url: https://harness.chance.cc
    description: Production
security:
  - ApiKeyAuth: []
  - BearerAuth: []
tags:
  - name: Verification
    description: Check an action against its rules and fetch past verdicts.
  - name: Credits
    description: Balance and x402 top-ups.
  - name: Escrow wallets
    description: Wallets that only move funds through a verified proposal.
  - name: Trader
    description: Liveness reports from trader containers.
  - name: Gas sponsorship
    description: Sponsored gas for trader instances on Polygon.
  - name: Status
    description: Public deployment facts for checking receipts.
paths:
  /api/v1/wallets/{id}/swap:
    post:
      tags:
        - Escrow wallets
      summary: Propose a swap
      description: >-
        Quotes the swap on the Uniswap Trading API, builds the batch (an
        approval for exactly the sell amount when needed, then the swap) and
        proposes it like `/propose`. Base and Ethereum wallets only. One credit
        when the judge runs.
      operationId: proposeSwap
      parameters:
        - name: id
          in: path
          required: true
          description: The wallet's id (UUID) or its name.
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SwapRequest'
      responses:
        '200':
          description: The proposal outcome and the quote.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SwapResult'
        '400':
          description: >-
            Invalid body, token, amount or slippage, or the wallet is on another
            chain.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                e0:
                  summary: invalid JSON body
                  value:
                    error: invalid JSON body
                e1:
                  summary: sell, buy and amount are required
                  value:
                    error: sell, buy and amount are required
                e2:
                  summary: chain must be "ethereum" or "base"
                  value:
                    error: chain must be "ethereum" or "base"
                e3:
                  summary: swap_failed
                  value:
                    error: swap_failed
                    message: unknown token "ABC" …
        '401':
          description: No API key, or the key is unknown or revoked.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                e0:
                  summary: missing API key (send x-api-key)
                  value:
                    error: missing API key (send x-api-key)
                e1:
                  summary: invalid or revoked API key
                  value:
                    error: invalid or revoked API key
        '402':
          description: Out of credits. The proposal is recorded as blocked.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: propose_failed
                message: No credits remaining. …
        '404':
          description: No such wallet on this account.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: not_found
        '409':
          description: >-
            The wallet cannot transact: archived, or a safe wallet from before
            self-custodial safe mode.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: propose_failed
                message: wallet is not active
        '500':
          description: Unexpected failure.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: swap_failed
                message: …
        '502':
          description: The quote service or the judge failed.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                e0:
                  summary: swap_failed
                  value:
                    error: swap_failed
                    message: 'Uniswap quote failed: …'
                e1:
                  summary: propose_failed
                  value:
                    error: propose_failed
                    message: …
        '503':
          description: Swaps are not configured on this deployment.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: swap_failed
                message: >-
                  Uniswap swaps are not configured on this deployment
                  (UNISWAP_API_KEY is not set)
components:
  schemas:
    SwapRequest:
      type: object
      required:
        - sell
        - buy
        - amount
        - chain
      properties:
        sell:
          type: string
          description: >-
            0x token address, `ETH`, `WETH`, `USDC`, or a symbol the wallet
            holds on this chain.
        buy:
          type: string
          description: 0x token address, `ETH`, `WETH` or `USDC`.
        amount:
          type: string
          description: Amount to sell, in the sell token's units.
        chain:
          type: string
          enum:
            - ethereum
            - base
          description: Must be the wallet's chain.
        slippageBps:
          type: integer
          minimum: 1
          maximum: 1000
          default: 50
        note:
          type: string
          description: Context for the judge, treated as untrusted narration.
      example:
        sell: USDC
        buy: WETH
        amount: '25'
        chain: base
        slippageBps: 50
    SwapResult:
      allOf:
        - $ref: '#/components/schemas/ProposalResult'
        - type: object
          properties:
            swap:
              $ref: '#/components/schemas/SwapQuote'
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: string
          description: >-
            An error code (for example `out_of_credits`) or a short sentence
            (for example `intent is required`).
        message:
          type: string
          description: Detail, when present.
    ProposalResult:
      type: object
      properties:
        txId:
          type: string
          description: >-
            Escrow transaction id. Poll it at
            `/api/v1/escrow-transactions/{id}`.
        status:
          type: string
          enum:
            - blocked
            - awaiting_user
            - executing
            - executed
            - failed
        verdict:
          type: string
          nullable: true
          description: >-
            ALLOW, BLOCK or ESCALATE. `BLOCK` without a `scanId` means the
            wallet's limits refused it before the judge ran.
        reasoning:
          type: string
          nullable: true
        requestHash:
          type: string
          description: >-
            Hash of the canonical payload the wallet will sign. Execution
            recomputes it and refuses on a mismatch.
        simulation:
          type: object
          allOf:
            - $ref: '#/components/schemas/SimulationReport'
          nullable: true
        approvalUrl:
          type: string
          nullable: true
          description: >-
            Set when the proposal waits for the owner. Send it to them; an API
            key cannot confirm.
        txHash:
          type: string
          nullable: true
          description: Set when the proposal executed.
        scanId:
          type: string
          nullable: true
          description: Verification id. Null when no judge ran.
        creditsRemaining:
          type: integer
          nullable: true
          description: Null when no credit was charged.
        proof:
          type: object
          allOf:
            - $ref: '#/components/schemas/CreatedProof'
          nullable: true
          description: Null when no judge ran.
    SwapQuote:
      type: object
      properties:
        routing:
          type: string
        sell:
          $ref: '#/components/schemas/SwapToken'
        buy:
          $ref: '#/components/schemas/SwapToken'
        amountIn:
          type: string
          nullable: true
          description: Base units.
        amountOut:
          type: string
          nullable: true
        minimumOut:
          type: string
          nullable: true
        amountInHuman:
          type: string
          nullable: true
        amountOutHuman:
          type: string
          nullable: true
        minimumOutHuman:
          type: string
          nullable: true
          description: The floor written into the signed swap.
        priceImpactPct:
          type: number
          nullable: true
        slippagePct:
          type: number
          nullable: true
        gasFeeUSD:
          type: string
          nullable: true
        routeString:
          type: string
          nullable: true
        approvalNeeded:
          type: boolean
          description: >-
            True when the batch includes an approval for exactly the sell
            amount.
        approvalSpender:
          type: string
          nullable: true
    SimulationReport:
      type: object
      properties:
        ok:
          type: boolean
        status:
          type: string
          enum:
            - clean
            - reverted
            - unavailable
          description: Only `clean` can execute without the owner.
        declared:
          type: boolean
          description: >-
            True when the effects come from a named transfer rather than a
            trace.
        wouldRevert:
          type: boolean
          nullable: true
        error:
          type: string
          nullable: true
        caip2:
          type: string
        changes:
          type: array
          items:
            $ref: '#/components/schemas/AssetChange'
        totalUsdOut:
          type: number
          nullable: true
        totalUsdIn:
          type: number
          nullable: true
        gasUsed:
          type: string
          nullable: true
        logsExcerpt:
          type: array
          items:
            type: string
        warnings:
          type: array
          items:
            type: string
        simulatedAt:
          type: string
          format: date-time
        provider:
          type: string
          nullable: true
          enum:
            - tatum
            - alchemy
            - starknet-rpc
            - null
    CreatedProof:
      type: object
      properties:
        transcriptRoot:
          type: string
          nullable: true
          description: Head of the transcript hash chain.
        outputHash:
          type: string
          nullable: true
          description: keccak256 of the judge's full output text.
        signature:
          type: string
          nullable: true
          description: EIP-191 signature by the judge key over the run digest.
        judge:
          type: string
          nullable: true
          description: Address of the judge key.
        attested:
          type: boolean
          description: True when the signing key's attestation mode is Azure SEV-SNP.
        anchorTx:
          type: string
          nullable: true
          description: Anchor transaction hash. Null when anchoring was skipped or failed.
        anchorVerified:
          type: boolean
          description: >-
            True when the registry confirmed the record after the anchor
            transaction.
        transcriptUri:
          type: string
          description: >-
            `/api/runs/{runId}/transcript`. Owner-only: send the owning
            account's API key, or open `/verify/{runId}` signed in.
        explorerTx:
          type: string
          nullable: true
          description: >-
            Explorer link for the anchor: basescan.org for Base, voyager.online
            for Starknet.
    SwapToken:
      type: object
      properties:
        address:
          type: string
        decimals:
          type: integer
        symbol:
          type: string
    AssetChange:
      type: object
      properties:
        direction:
          type: string
          enum:
            - in
            - out
        assetType:
          type: string
          enum:
            - native
            - erc20
            - erc721
            - erc1155
            - spl
        changeType:
          type: string
          nullable: true
          enum:
            - transfer
            - approve
            - null
        symbol:
          type: string
          nullable: true
        name:
          type: string
          nullable: true
        contractAddress:
          type: string
          nullable: true
        rawAmount:
          type: string
        decimals:
          type: integer
          nullable: true
        amount:
          type: string
          nullable: true
        usdValue:
          type: number
          nullable: true
        counterparty:
          type: string
          nullable: true
        logoUrl:
          type: string
          nullable: true
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: An API key (`chance_sk_live_…`) from https://harness.chance.cc/keys.
    BearerAuth:
      type: http
      scheme: bearer
      description: >-
        The same API key sent as `Authorization: Bearer <key>`. If both headers
        are sent, `x-api-key` is used.

````