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

# Read cached token execution legs

> Requires md.read and consumes the existing REST key limiter. Solana only; unsupported chains return 400 unsupported_chain. Unknown/repeated query parameters and URLs over 8 KiB are rejected. Responses use Cache-Control: no-store. No paid enrichment is started. Reads only the native source=cache, scope=all tape: retained memory, live ring or bounded captured-history objects; no RPC, enrichment lease, replay or history build. Newest first by default; sortDirection=asc reads oldest first. Stable execution-leg IDs. Default limit stays 100, maximum 500. Optional identity reads only native labels and reviewed profiles for displayed wallets; failure leaves identity null. Coverage is passed through in meta.coverage; partial means retained observations only. hasNextPage is nextCursor !== null, not proof of historical completeness. Uncached or unqualified empty pages return 503 tape_unavailable, with unavailable coverage when provided by the reader; only proven complete empty results succeed. Decimal strings come from exact source facts; unavailable fields remain null. Pinned cursors bind token, all filters, range, limit and correction revision, expire after 30 seconds, and do not include later inserts. Repeat wallet, pool, sortDirection, all other selectors and both bounds from meta.window when using nextCursor. Missing bounds return 400; changed filters return 409 cursor_mismatch; expiry returns 410 cursor_expired; corrections return 409 snapshot_reorg_restart.



## OpenAPI

````yaml https://www.oceanx.trade/api/v1/openapi.json get /api/v1/tokens/{chain}/{address}/trades
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: Router
    description: >-
      Read-only Raptor route quotes and public Solana transaction status. Build
      and execution remain separately gated.
  - 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.
  - name: Copy Trading
    description: Key-owner follow, fill and PnL reads; no execution authority.
  - name: Price Alerts
    description: Key-owner alert management through the existing evaluator; no webhooks.
paths:
  /api/v1/tokens/{chain}/{address}/trades:
    get:
      tags:
        - Market Data
      summary: Read cached token execution legs
      description: >-
        Requires md.read and consumes the existing REST key limiter. Solana
        only; unsupported chains return 400 unsupported_chain. Unknown/repeated
        query parameters and URLs over 8 KiB are rejected. Responses use
        Cache-Control: no-store. No paid enrichment is started. Reads only the
        native source=cache, scope=all tape: retained memory, live ring or
        bounded captured-history objects; no RPC, enrichment lease, replay or
        history build. Newest first by default; sortDirection=asc reads oldest
        first. Stable execution-leg IDs. Default limit stays 100, maximum 500.
        Optional identity reads only native labels and reviewed profiles for
        displayed wallets; failure leaves identity null. Coverage is passed
        through in meta.coverage; partial means retained observations only.
        hasNextPage is nextCursor !== null, not proof of historical
        completeness. Uncached or unqualified empty pages return 503
        tape_unavailable, with unavailable coverage when provided by the reader;
        only proven complete empty results succeed. Decimal strings come from
        exact source facts; unavailable fields remain null. Pinned cursors bind
        token, all filters, range, limit and correction revision, expire after
        30 seconds, and do not include later inserts. Repeat wallet, pool,
        sortDirection, all other selectors and both bounds from meta.window when
        using nextCursor. Missing bounds return 400; changed filters return 409
        cursor_mismatch; expiry returns 410 cursor_expired; corrections return
        409 snapshot_reorg_restart.
      operationId: getTokenTrades
      parameters:
        - name: chain
          in: path
          required: true
          schema:
            type: string
            enum:
              - solana
        - name: address
          in: path
          required: true
          schema:
            type: string
            pattern: ^[1-9A-HJ-NP-Za-km-z]{32,44}$
        - name: events
          in: query
          schema:
            type: string
            enum:
              - trades
              - all
              - liquidity
            default: trades
          description: >-
            Default preserves the trade contract. all/liquidity return
            TokenActivityResponse from our own captures, with eventType
            discriminators and partial LP coverage. side/minUsd are rejected for
            mixed/LP reads. No SolanaTracker. LP scopes admit 2 concurrent
            requests/IP, 60 starts/min/IP and 32 global; unavailable limiter
            fails closed.
        - name: pool
          in: query
          schema:
            type: string
        - name: wallet
          in: query
          schema:
            type: string
          description: >-
            Exact case-sensitive Solana signer. Combines with pool. Public
            execution filter, not an owned-wallet permission.
        - name: sortDirection
          in: query
          schema:
            type: string
            enum:
              - asc
              - desc
            default: desc
          description: Execution time order. Repeat on every cursor request.
        - name: side
          in: query
          schema:
            type: string
            enum:
              - buy
              - sell
        - name: minUsd
          in: query
          schema:
            type: string
            pattern: ^(0|[1-9]\d*)(\.\d+)?$
          description: >-
            Nonnegative decimal within native decimal precision/range;
            unsupported precision returns 400 invalid_min_usd. Unknown
            valuations are excluded by this filter.
        - name: fromMs
          in: query
          schema:
            type: integer
            minimum: 0
          description: Inclusive epoch milliseconds. Defaults to toMs minus one hour.
        - name: toMs
          in: query
          schema:
            type: integer
            minimum: 0
          description: >-
            Exclusive epoch milliseconds, no later than now; defaults to now
            rounded down to a second.
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 500
            default: 100
        - name: cursor
          in: query
          schema:
            type: string
            minLength: 20
            maxLength: 1024
          description: >-
            Opaque pinned cursor. Repeat fromMs, toMs, limit and filters from
            the first page. Restart on expiry or correction.
      responses:
        '200':
          description: >-
            Cached execution-leg page with explicit retained coverage; no empty
            partial success.
          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:
                oneOf:
                  - $ref: '#/components/schemas/TokenTapeResponse'
                  - $ref: '#/components/schemas/TokenActivityResponse'
        '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'
        '409':
          description: >-
            cursor_mismatch or snapshot_reorg_restart: repeat original selectors
            or restart pagination.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '410':
          description: >-
            cursor_expired: restart pagination; service pins live for 30
            seconds.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '422':
          description: 'range_too_large: use a window of at most 24 hours.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: >-
            rate_limited or snapshot_capacity: slow down and retry; every
            admitted read consumes the REST limiter.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Existing API-key verification dependency failed.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '503':
          description: >-
            tape_unavailable or rate_limit_unavailable. Native unavailable
            coverage is preserved in meta.coverage when present. No history/RPC
            work started.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TokenTapeUnavailable'
      security:
        - bearerAuth: []
components:
  schemas:
    TokenTapeResponse:
      type: object
      required:
        - data
        - nextCursor
        - hasNextPage
        - meta
      properties:
        data:
          type: array
          maxItems: 500
          items:
            $ref: '#/components/schemas/TokenTapeTrade'
        nextCursor:
          type:
            - string
            - 'null'
        hasNextPage:
          type: boolean
          description: >-
            Another page exists in this retained snapshot; false is not proof of
            complete token or wallet history. Equivalent to nextCursor !== null.
        meta:
          type: object
          required:
            - requestId
            - methodVersion
            - source
            - chain
            - address
            - asOfMs
            - snapshotRevision
            - cursorTtlMs
            - window
            - coverage
            - sortDirection
          properties:
            requestId:
              type: string
              format: uuid
            methodVersion:
              type: string
              const: public-token-tape-v1
            source:
              type: string
              const: cache
            chain:
              const: solana
              type: string
            address:
              type: string
            sortDirection:
              type: string
              enum:
                - asc
                - desc
            asOfMs:
              type: integer
              minimum: 0
              description: Pinned source refresh time; pagination does not renew it.
            snapshotRevision:
              type:
                - string
                - 'null'
              description: >-
                Source correction revision, not a transport sequence. Null if
                unsafe to represent.
            cursorTtlMs:
              type: integer
              const: 30000
              description: >-
                Lifetime from first pin, not renewed on pagination. Shorter than
                the proposed five-minute expansion target.
            window:
              type: object
              required:
                - fromMs
                - toMs
              properties:
                fromMs:
                  type: integer
                toMs:
                  type: integer
            coverage:
              $ref: '#/components/schemas/TokenTapeCoverage'
    TokenActivityResponse:
      type: object
      required:
        - data
        - nextCursor
        - hasNextPage
        - meta
      properties:
        data:
          type: array
          maxItems: 500
          items:
            oneOf:
              - $ref: '#/components/schemas/TokenLiquidityEvent'
              - allOf:
                  - $ref: '#/components/schemas/TokenTapeTrade'
                  - type: object
                    required:
                      - eventType
                    properties:
                      eventType:
                        type: string
                        const: trade
        nextCursor:
          type:
            - string
            - 'null'
        hasNextPage:
          type: boolean
        meta:
          type: object
          required:
            - source
            - methodVersion
            - chain
            - address
            - events
            - sortDirection
            - cursorTtlMs
            - window
            - coverage
          properties:
            source:
              const: native_activity
              type: string
            methodVersion:
              const: public-token-activity-v1
              type: string
            chain:
              const: solana
              type: string
            address:
              type: string
            requestId:
              type: string
            events:
              type: string
              enum:
                - all
                - liquidity
            sortDirection:
              type: string
              enum:
                - asc
                - desc
            cursorTtlMs:
              type: integer
              const: 30000
            window:
              type: object
              properties:
                fromMs:
                  type: integer
                toMs:
                  type: integer
            coverage:
              type: object
              properties:
                complete:
                  type: boolean
                  const: false
                reason:
                  const: retained_observations_only
                  type: string
                liquidityReason:
                  type:
                    - string
                    - 'null'
                decodedProtocols:
                  type: array
                  items:
                    type: string
    Error:
      type: object
      required:
        - error
      properties:
        requestId:
          type: string
          description: Request identifier on new token endpoints.
        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.
    TokenTapeUnavailable:
      allOf:
        - $ref: '#/components/schemas/Error'
        - type: object
          properties:
            meta:
              type: object
              properties:
                coverage:
                  $ref: '#/components/schemas/TokenTapeCoverage'
    TokenTapeTrade:
      type: object
      required:
        - id
        - signature
        - slot
        - instructionIndex
        - innerInstructionIndex
        - poolAddress
        - dex
        - maker
        - identity
        - side
        - tokenAmount
        - nativeAmount
        - baseAtomicAmount
        - quoteAtomicAmount
        - baseDecimals
        - quoteDecimals
        - priceUsd
        - volumeUsd
        - priceSource
        - eventAtMs
        - observedAtMs
        - finality
      properties:
        id:
          type: string
          description: >-
            Stable execution-leg identity: signature, pool, instruction and
            inner instruction.
        signature:
          type: string
        slot:
          type:
            - string
            - 'null'
          pattern: ^[0-9]+$
          description: >-
            Integer string; null if the source number exceeds safe integer
            precision.
        instructionIndex:
          type:
            - integer
            - 'null'
          minimum: 0
        innerInstructionIndex:
          type:
            - integer
            - 'null'
          minimum: 0
          description: Null for a top-level instruction (source -1) or unavailable index.
        poolAddress:
          type:
            - string
            - 'null'
        dex:
          type:
            - string
            - 'null'
        maker:
          type:
            - string
            - 'null'
        identity:
          type:
            - object
            - 'null'
          description: >-
            Optional own-data wallet identity, refreshed per page. Native role
            labels expire after 60 seconds; reviewed profile metadata expires
            after 30 days. Absence is unknown, not proof of safety. KOL
            metadata/platform remain null without an observed native source; a
            creator profile is not this token's dev.
          properties:
            label:
              type:
                - string
                - 'null'
            image:
              type:
                - string
                - 'null'
            twitter:
              type:
                - string
                - 'null'
            type:
              type:
                - string
                - 'null'
            platform:
              type:
                - string
                - 'null'
            flags:
              type: array
              maxItems: 23
              items:
                type: string
            source:
              type: string
              const: oceanx_wallet_labels
            asOf:
              type:
                - integer
                - 'null'
              minimum: 0
            profileAsOf:
              type:
                - integer
                - 'null'
              minimum: 0
            profileSource:
              type:
                - string
                - 'null'
              enum:
                - wallet_label_reviews
                - null
        side:
          type: string
          enum:
            - buy
            - sell
            - unknown
        tokenAmount:
          type:
            - string
            - 'null'
          pattern: ^(0|[1-9]\d*)(\.\d+)?$
          description: >-
            Exact decoded swap-leg token quantity, not atomic units or a wallet
            balance.
        nativeAmount:
          type:
            - string
            - 'null'
          pattern: ^(0|[1-9]\d*)(\.\d+)?$
          description: >-
            Exact decoded swap-leg native quantity; not an arbitrary quote-token
            amount.
        baseAtomicAmount:
          type: 'null'
          description: Not available in the qualified cache wire; never inferred.
        quoteAtomicAmount:
          type: 'null'
          description: Not available in the qualified cache wire; never inferred.
        baseDecimals:
          type: 'null'
          description: Not available in the qualified cache wire; never inferred.
        quoteDecimals:
          type: 'null'
          description: Not available in the qualified cache wire; never inferred.
        priceUsd:
          type:
            - string
            - 'null'
          pattern: ^(0|[1-9]\d*)(\.\d+)?$
        volumeUsd:
          type:
            - string
            - 'null'
          pattern: ^(0|[1-9]\d*)(\.\d+)?$
          description: >-
            Execution-leg USD valuation, not deduplicated economic volume.
            Unknown USD reference is null.
        priceSource:
          type:
            - string
            - 'null'
        eventAtMs:
          type: integer
          minimum: 0
        observedAtMs:
          type: 'null'
          description: Not available in the qualified cache wire; never inferred.
        finality:
          type: 'null'
          description: Not available in the qualified cache wire; never inferred.
    TokenTapeCoverage:
      type: object
      required:
        - status
        - reason
        - from
        - through
        - cursor
        - complete
      properties:
        status:
          type: string
          enum:
            - complete
            - partial
            - unavailable
        reason:
          type: string
          description: Native cache coverage reason, preserved from the source.
        from:
          type:
            - integer
            - 'null'
          minimum: 0
          description: Retained source coverage start, epoch milliseconds.
        through:
          type:
            - integer
            - 'null'
          minimum: 0
          description: >-
            Retained source coverage end, epoch milliseconds; not proof that the
            requested range is complete.
        cursor:
          type:
            - string
            - 'null'
          description: Same opaque value as nextCursor.
        complete:
          type: boolean
        basis:
          type: string
          const: retained_cache
        scope:
          type: string
          const: all
    TokenLiquidityEvent:
      type: object
      required:
        - eventType
        - id
        - signature
        - eventAtMs
        - slot
        - poolAddress
        - maker
        - identity
        - dex
        - kind
        - tokenA
        - tokenB
        - instruction
        - programId
        - provisional
      properties:
        eventType:
          const: liquidity
          type: string
        id:
          type: string
        signature:
          type: string
        eventAtMs:
          type: integer
        slot:
          type:
            - string
            - 'null'
        poolAddress:
          type: string
        maker:
          type:
            - string
            - 'null'
        identity:
          type:
            - object
            - 'null'
          description: >-
            Optional own-data wallet identity, refreshed per page. Native role
            labels expire after 60 seconds; reviewed profile metadata expires
            after 30 days. Absence is unknown, not proof of safety. KOL
            metadata/platform remain null without an observed native source; a
            creator profile is not this token's dev.
          properties:
            label:
              type:
                - string
                - 'null'
            image:
              type:
                - string
                - 'null'
            twitter:
              type:
                - string
                - 'null'
            type:
              type:
                - string
                - 'null'
            platform:
              type:
                - string
                - 'null'
            flags:
              type: array
              maxItems: 23
              items:
                type: string
            source:
              type: string
              const: oceanx_wallet_labels
            asOf:
              type:
                - integer
                - 'null'
              minimum: 0
            profileAsOf:
              type:
                - integer
                - 'null'
              minimum: 0
            profileSource:
              type:
                - string
                - 'null'
              enum:
                - wallet_label_reviews
                - null
        dex:
          type:
            - string
            - 'null'
        kind:
          type: string
          enum:
            - add
            - remove
            - init
            - migration
            - unknown
        tokenA:
          type: object
          required:
            - asset
            - amount
            - amountRaw
            - decimals
            - feeAmountRaw
            - amountBasis
          properties:
            asset:
              type:
                - string
                - 'null'
            amount:
              type:
                - string
                - 'null'
              pattern: ^(0|[1-9]\d*)(\.\d+)?$
            amountRaw:
              type:
                - string
                - 'null'
              pattern: ^[0-9]+$
            decimals:
              type:
                - integer
                - 'null'
              minimum: 0
              maximum: 255
            feeAmountRaw:
              type:
                - string
                - 'null'
              description: >-
                Null until transfer fee evidence is decoded; never zero by
                default.
            amountBasis:
              type:
                - string
                - 'null'
              enum:
                - vault_balance_delta
                - null
              description: Net pool vault change, not the provider's gross debit.
        tokenB:
          type: object
          required:
            - asset
            - amount
            - amountRaw
            - decimals
            - feeAmountRaw
            - amountBasis
          properties:
            asset:
              type:
                - string
                - 'null'
            amount:
              type:
                - string
                - 'null'
              pattern: ^(0|[1-9]\d*)(\.\d+)?$
            amountRaw:
              type:
                - string
                - 'null'
              pattern: ^[0-9]+$
            decimals:
              type:
                - integer
                - 'null'
              minimum: 0
              maximum: 255
            feeAmountRaw:
              type:
                - string
                - 'null'
              description: >-
                Null until transfer fee evidence is decoded; never zero by
                default.
            amountBasis:
              type:
                - string
                - 'null'
              enum:
                - vault_balance_delta
                - null
              description: Net pool vault change, not the provider's gross debit.
        instruction:
          type:
            - string
            - 'null'
        programId:
          type:
            - string
            - 'null'
        provisional:
          type: boolean
          const: false
          description: >-
            REST captures are canonical; stream captures are provisional and
            require REST reconciliation.
  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_…`. Required scopes are
        operation-specific: market reads use md.read, tracker uses tracker.read,
        copy reads use copy.read, and alert operations use alerts.read or
        alerts.write. New scopes require explicit selection and grant no trading
        authority. Existing perps operations retain their documented scopes.

````

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