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

# Exit check

> Quotes several fractions of a position and reports the realized rate at each size.

The headline price of a token tells you what the FIRST token sells for; this tells you what the LAST one does. Read `rungs[].realizedImpactPct` top to bottom, and treat `summary.maxCleanFraction` as the actionable number.

Costs ONE PER LADDER RUNG against the 300/min quote budget.

A thin book that stops routing at size is data, not an error: you get a 200 with a `no_route` verdict. A non-2xx means the ladder could not be produced at all.



## OpenAPI

````yaml https://www.oceanx.trade/api/v1/openapi.json post /api/v1/spot/exit-check
openapi: 3.1.0
info:
  title: OceanX Developer API
  version: 1.0.0
  description: >-
    Public API for the OceanX trading platform. Currently in beta and free to
    use while in beta.


    This spec covers the **spot quote** domain. The wallet **tracker** and
    **perps** domains are documented at https://docs.oceanx.trade/api/overview
    and are not yet described here.
  contact:
    url: https://docs.oceanx.trade
  termsOfService: https://www.oceanx.trade/legal/terms
  license:
    name: Proprietary
    url: https://www.oceanx.trade/legal/terms
servers:
  - url: https://www.oceanx.trade
    description: Production
security:
  - bearerAuth: []
tags:
  - name: Market Data
    description: Read-only OceanX market context sourced and cached by VM producers.
  - name: Spot
    description: >-
      Executable Solana swap quotes off OceanX's own router, and the exit
      checker that reports whether a whole position can be sold.
  - name: Callouts
    description: >-
      Public token callouts — user-posted token calls with live click/volume
      attribution stats. Read-only.
paths:
  /api/v1/spot/exit-check:
    post:
      tags:
        - Spot
      summary: Exit check
      description: >-
        Quotes several fractions of a position and reports the realized rate at
        each size.


        The headline price of a token tells you what the FIRST token sells for;
        this tells you what the LAST one does. Read `rungs[].realizedImpactPct`
        top to bottom, and treat `summary.maxCleanFraction` as the actionable
        number.


        Costs ONE PER LADDER RUNG against the 300/min quote budget.


        A thin book that stops routing at size is data, not an error: you get a
        200 with a `no_route` verdict. A non-2xx means the ladder could not be
        produced at all.
      operationId: postSpotExitCheck
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - mint
              properties:
                mint:
                  type: string
                  pattern: ^[1-9A-HJ-NP-Za-km-z]{32,44}$
                  description: The token you are exiting.
                quoteMint:
                  type: string
                  pattern: ^[1-9A-HJ-NP-Za-km-z]{32,44}$
                  description: What you are exiting into. Must differ from `mint`.
                  default: So11111111111111111111111111111111111111112
                amount:
                  type: string
                  pattern: ^\d+$
                  description: Bag size. Required unless you pass `uiAmount` + `decimals`.
                  example: '1000000000'
                uiAmount:
                  type: number
                  exclusiveMinimum: 0
                decimals:
                  type: integer
                  minimum: 0
                  maximum: 18
                quoteDecimals:
                  type: integer
                  minimum: 0
                  maximum: 18
                slippageBps:
                  type: integer
                  minimum: 1
                  maximum: 1000
                  default: 50
                ladder:
                  type: array
                  items:
                    type: number
                    exclusiveMinimum: 0
                    maximum: 1
                  minItems: 1
                  maxItems: 8
                  default:
                    - 0.1
                    - 0.25
                    - 0.5
                    - 1
                  description: >-
                    Fractions of the position to quote. Impact is measured
                    against the SMALLEST rung, so pass a small first rung —
                    [0.01, 0.1, 0.25, 0.5, 1] gives a much tighter baseline than
                    the default, and the response warns you via
                    `coarse_baseline` when yours is too coarse.
            examples:
              tightBaseline:
                summary: A memecoin position, quoted into USDC with a 1% baseline
                value:
                  mint: DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263
                  uiAmount: 500000000
                  decimals: 5
                  quoteMint: EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v
                  quoteDecimals: 6
                  ladder:
                    - 0.01
                    - 0.1
                    - 0.25
                    - 0.5
                    - 1
      responses:
        '200':
          description: The ladder, including any rungs that had no route.
          headers:
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Requests allowed per window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests left.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Unix seconds when the window resets.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExitCheckResult'
        '400':
          description: Failed validation before reaching the engine.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Missing, malformed or revoked API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: The key is valid but lacks the required scope.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: Rate limited. Honour `Retry-After`.
          headers:
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Requests allowed per window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests left.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Unix seconds when the window resets.
            Retry-After:
              schema:
                type: integer
              description: Seconds to wait.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '503':
          description: The routing engine is unreachable or timed out. Retry.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      security:
        - bearerAuth: []
components:
  schemas:
    ExitCheckResult:
      type: object
      required:
        - mint
        - quoteMint
        - amount
        - slippageBps
        - ladder
        - summary
        - rungs
      properties:
        mint:
          type: string
        quoteMint:
          type: string
        amount:
          type: string
          pattern: ^\d+$
          description: >-
            Atomic (base-unit) amount as a decimal integer string. A string, not
            a number, because a large 9-decimal balance exceeds
            Number.MAX_SAFE_INTEGER and would be corrupted by JSON float
            parsing.
          example: '1000000000'
        uiAmount:
          type:
            - number
            - 'null'
        decimals:
          type:
            - integer
            - 'null'
        quoteDecimals:
          type:
            - integer
            - 'null'
        slippageBps:
          type: integer
        ladder:
          type: array
          items:
            type: number
        summary:
          $ref: '#/components/schemas/ExitSummary'
        rungs:
          type: array
          items:
            $ref: '#/components/schemas/ExitRung'
        units:
          type: object
          description: >-
            Self-describing unit notes, safe to ignore once you've read them
            once.
          additionalProperties: true
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
              description: Stable machine-readable code. Branch on this, not the message.
              example: no_route
            message:
              type: string
              description: Human-readable detail. May change.
    ExitSummary:
      type: object
      required:
        - verdict
        - venues
        - warnings
      properties:
        verdict:
          type: string
          enum:
            - clean
            - thin
            - trapped
            - no_route
          description: >-
            clean = full size exits within 2% realized impact; thin = 2–10%;
            trapped = over 10%, hit the liquidity floor, or no route; no_route =
            nothing routed at any rung.
        fullExitImpactPct:
          type:
            - number
            - 'null'
        fullExitPrice:
          type:
            - number
            - 'null'
        fullExitOutAmount:
          type:
            - string
            - 'null'
        fullExitOutUiAmount:
          type:
            - number
            - 'null'
        maxCleanFraction:
          type:
            - number
            - 'null'
          description: >-
            Largest QUOTED fraction that stayed inside 2%. This is ladder
            resolution, not a solved optimum — pass a denser ladder for a
            tighter answer.
        maxCleanUiAmount:
          type:
            - number
            - 'null'
        venues:
          type: array
          items:
            type: string
        warnings:
          type: array
          description: >-
            Caveats to surface verbatim. Each entry is 'code: message'; split on
            the first colon for the stable code.
          items:
            type: string
            example: >-
              negative_marginal_proceeds: the 0.5 rung returns LESS than the 0.1
              rung — selling more of this bag nets you less
    ExitRung:
      type: object
      description: One fraction of the position, quoted independently.
      required:
        - fraction
        - amount
        - isBaseline
      properties:
        fraction:
          type: number
          description: Fraction of the position this rung represents. 1 is the whole thing.
        amount:
          type: string
          pattern: ^\d+$
          description: >-
            Atomic (base-unit) amount as a decimal integer string. A string, not
            a number, because a large 9-decimal balance exceeds
            Number.MAX_SAFE_INTEGER and would be corrupted by JSON float
            parsing.
          example: '1000000000'
        uiAmount:
          type:
            - number
            - 'null'
        quote:
          oneOf:
            - $ref: '#/components/schemas/Quote'
            - type: 'null'
          description: Null when this rung had no route; `error` then says why.
        error:
          type:
            - string
            - 'null'
          description: 'Set when this rung failed: no_route, dust_rung, or an engine code.'
        outAmount:
          type:
            - string
            - 'null'
        outUiAmount:
          type:
            - number
            - 'null'
        realizedPrice:
          type:
            - number
            - 'null'
          description: >-
            quoteMint units per whole input token — the realized price for
            selling THIS size. Requires both decimals.
        realizedImpactPct:
          type:
            - number
            - 'null'
          description: >-
            OUR measurement: this rung's rate against the smallest rung's rate,
            in percent. May be NEGATIVE — the router re-solves per size and a
            different pool can win, which is a real outcome and not an error.
        upstreamImpactPct:
          type:
            - number
            - 'null'
          description: The engine's own impact figure for this rung. Unusable below 0.1%.
        isBaseline:
          type: boolean
          description: >-
            The rung every other rung is measured against. Its realizedImpactPct
            is 0 BY DEFINITION, not by measurement — do not read it as evidence
            that this size is cheap to exit.
    Quote:
      type: object
      required:
        - inputMint
        - outputMint
        - inAmount
        - outAmount
        - minOutAmount
        - slippageBps
        - impactMeasurable
        - clamped
        - route
        - venues
        - engine
      properties:
        inputMint:
          type: string
        outputMint:
          type: string
        inAmount:
          type: string
          pattern: ^\d+$
          description: >-
            Atomic (base-unit) amount as a decimal integer string. A string, not
            a number, because a large 9-decimal balance exceeds
            Number.MAX_SAFE_INTEGER and would be corrupted by JSON float
            parsing.
          example: '1000000000'
        outAmount:
          type: string
          pattern: ^\d+$
          description: >-
            Atomic (base-unit) amount as a decimal integer string. A string, not
            a number, because a large 9-decimal balance exceeds
            Number.MAX_SAFE_INTEGER and would be corrupted by JSON float
            parsing.
          example: '1000000000'
        minOutAmount:
          type: string
          pattern: ^\d+$
          description: Worst-case output after slippageBps, as enforced on-chain.
          example: '1000000000'
        slippageBps:
          type: integer
          minimum: 1
          maximum: 1000
        priceImpactPct:
          type:
            - number
            - 'null'
          description: >-
            Price impact in PERCENT (1.5 = 1.5%). NOTE: Jupiter's equivalent
            field is fractional (0.015), so code ported from Jupiter is off by
            100x — in the direction that makes an untradeable position look
            fine.
          example: 1.5
        impactMeasurable:
          type: boolean
          description: >-
            False when impact sits inside the engine's noise floor (~0.1%),
            where the figure is a cached mid rather than a measurement. Render
            '—' rather than the number.
        clamped:
          type: boolean
          description: >-
            True when this is the router's out-of-liquidity floor price rather
            than an executable fill. Returned with HTTP 200. NEVER present a
            clamped quote as proceeds.
        contextSlot:
          type:
            - integer
            - 'null'
        route:
          type: array
          items:
            $ref: '#/components/schemas/RouteLeg'
        venues:
          type: array
          items:
            type: string
        engineTimeMs:
          type:
            - number
            - 'null'
          description: Router compute time in milliseconds, typically 1–2.
        swapUsdValue:
          type:
            - number
            - 'null'
          description: >-
            Upstream USD notional when available; null on many pairs. Don't
            depend on it.
        requestId:
          type:
            - string
            - 'null'
          description: Quote id. Include it if you report a bad route to us.
        engine:
          type: string
          example: raptor
    RouteLeg:
      type: object
      description: One hop of the route the engine picked.
      required:
        - dex
        - inputMint
        - outputMint
      properties:
        dex:
          type: string
          example: Raydium CLMM
        pool:
          type:
            - string
            - 'null'
        inputMint:
          type: string
        outputMint:
          type: string
        percent:
          type:
            - number
            - 'null'
          description: Share of the input this leg carries, in percent.
        amountIn:
          type:
            - string
            - 'null'
        amountOut:
          type:
            - string
            - 'null'
        priceImpactPct:
          type:
            - number
            - 'null'
          description: This leg's impact, in PERCENT.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        An OceanX API key, created in the app under Settings → Developer API.
        Send it as `Authorization: Bearer ox_live_…`. These endpoints require
        the `md.read` scope, which is on every key by default.

````