> ## 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 own copy PnL summary

> Owner comes exclusively from the bearer key. Caller owner fields are rejected. Scopes are opt-in and independent of md.read and trading authority. Every request consumes the existing REST key limiter. URLs <=8 KiB and bodies <=32 KiB; no-store and credential-free CORS including PATCH/Idempotency-Key/If-Match. Aggregates store full-history executed-sell PnL for current follows only; removed follows are excluded. No sells, missing basis/aggregate or any unknown sells leaves realizedUsd null. Unrealized PnL is unavailable, never zero. Existing numeric USD type is preserved; no exact-decimal or tax-accounting claim.



## OpenAPI

````yaml https://www.oceanx.trade/api/v1/openapi.json get /api/v1/copy-trading/pnl
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/copy-trading/pnl:
    get:
      tags:
        - Copy Trading
      summary: Read own copy PnL summary
      description: >-
        Owner comes exclusively from the bearer key. Caller owner fields are
        rejected. Scopes are opt-in and independent of md.read and trading
        authority. Every request consumes the existing REST key limiter. URLs
        <=8 KiB and bodies <=32 KiB; no-store and credential-free CORS including
        PATCH/Idempotency-Key/If-Match. Aggregates store full-history
        executed-sell PnL for current follows only; removed follows are
        excluded. No sells, missing basis/aggregate or any unknown sells leaves
        realizedUsd null. Unrealized PnL is unavailable, never zero. Existing
        numeric USD type is preserved; no exact-decimal or tax-accounting claim.
      operationId: getCopyPnl
      responses:
        '200':
          description: >-
            Owner-scoped projection; unknown observations remain null.
            Cache-Control: no-store.
          headers:
            ETag:
              schema:
                type: string
              description: Quoted configVersion on alert item reads/writes.
            X-Request-Id:
              schema:
                type: string
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/CopyPnl'
                  meta:
                    $ref: '#/components/schemas/OwnedResponseMeta'
                required:
                  - data
                  - meta
                additionalProperties: false
        '400':
          description: >-
            Malformed input, unknown/repeated field, invalid cursor or altered
            cursor filters/owner.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OwnedApiError'
        '401':
          description: >-
            Missing, revoked, invalid or disabled API key. No session-cookie
            fallback.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OwnedApiError'
        '403':
          description: Key lacks this operation's explicit scope.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OwnedApiError'
        '404':
          description: >-
            Owned resource not found. Foreign and missing IDs are
            indistinguishable.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OwnedApiError'
        '410':
          description: Cursor expired or lost; restart pagination. Alert may be expired.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OwnedApiError'
        '422':
          description: >-
            Source exceeds the snapshot budget or qualified alert price/delivery
            capability is unavailable.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OwnedApiError'
        '429':
          description: REST or alert-service quota exceeded; Retry-After provided.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OwnedApiError'
        '500':
          description: Existing API-key verification dependency failed.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OwnedApiError'
        '503':
          description: >-
            Admission, store or alert service unavailable. No fabricated
            empty/zero success.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OwnedApiError'
      security:
        - bearerAuth: []
components:
  schemas:
    CopyPnl:
      type: object
      properties:
        realizedUsd:
          type:
            - number
            - 'null'
        knownSells:
          type:
            - integer
            - 'null'
          minimum: 0
          maximum: 9007199254740991
        unknownSells:
          type:
            - integer
            - 'null'
          minimum: 0
          maximum: 9007199254740991
        status:
          enum:
            - known
            - partial
            - unavailable
        unrealizedUsd:
          type: 'null'
        coverage:
          const: executed_sells_of_current_follows
        methodVersion:
          const: copy-store-realized-v1
      required:
        - realizedUsd
        - knownSells
        - unknownSells
        - status
        - unrealizedUsd
        - coverage
        - methodVersion
      additionalProperties: false
    OwnedResponseMeta:
      type: object
      required:
        - requestId
        - source
        - methodVersion
        - observedAtMs
        - staleAfterMs
      properties:
        requestId:
          type: string
        source:
          enum:
            - copy-trading-store
            - alert-eval-rs
        methodVersion:
          type: string
        observedAtMs:
          type: 'null'
        staleAfterMs:
          type: 'null'
        coverage:
          type: string
        completeHistory:
          type: boolean
        snapshotExpiresAtMs:
          type: integer
          minimum: 0
          maximum: 9007199254740991
        pagination:
          const: service_keyset
        cursorTtlMs:
          const: 300000
        mode:
          type: object
          properties:
            disabled:
              type: boolean
            dryRun:
              type: boolean
            liveExecutionAvailable:
              const: false
          required:
            - disabled
            - dryRun
            - liveExecutionAvailable
          additionalProperties: false
        limits:
          type: object
          properties:
            maxPerTradeUsd:
              type: number
            dailyCapUsd:
              type: number
            slippageBps:
              type: number
            targets:
              type: integer
              minimum: 0
              maximum: 9007199254740991
          required:
            - maxPerTradeUsd
            - dailyCapUsd
            - slippageBps
            - targets
          additionalProperties: false
    OwnedApiError:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
            message:
              type: string
          required:
            - code
            - message
          additionalProperties: false
        requestId:
          type: string
      required:
        - error
        - requestId
      additionalProperties: false
  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.