openapi: 3.0.3
info:
  title: Cognivo Public API
  version: "1.0.0"
  description: |
    The Cognivo Public API gives developers programmatic access to Cognivo's
    on-chain token and wallet intelligence for Ethereum, Base, and BNB Smart Chain.

    ## Authentication
    Every endpoint except `GET /v1/api/health` requires an API key created in the
    Cognivo developer portal. Send it in the `X-API-Key` header. `Authorization:
    Bearer <key>` is accepted as an alias for client-library convenience.

    Keys come in two environments:
    - `cogv_live_...` live keys: self-serve, work immediately, billed
      pay-as-you-go in Cognivo credits per successful call.
    - `cogv_test_...` Sandbox keys, clearly labelled Sandbox, for limited
      demos and integration testing only; they cannot run live intelligence
      and are capped at 25 requests per hour, 100 per day and 1 per second.

    Keys are scoped. Each endpoint below states the scope it requires
    (`intel:read`, `liquidity:read`, or `security:read`). `GET /v1/api/me` and
    `GET /v1/api/discover` accept any valid key regardless of scope.

    ## Access model and pricing
    Live keys are self-serve and pay-as-you-go. A new live key works
    immediately: no trial and no request-access step is needed for ordinary
    use. Each successful call deducts the endpoint's credit price from the
    owner account's Cognivo credit balance; failed calls are never charged,
    and a successful call is charged exactly once (duplicate submissions of
    the same operation cannot double-charge). The amount charged appears in
    `meta.credits_charged`. When the balance cannot cover a call the API
    returns `402` with error code `payment_required` and nothing is charged:
    top up on the Cognivo account billing page and retry.

    Trial is an optional admin-granted evaluation allowance (not required for
    ordinary paid use). Partner is an admin-managed arrangement. Enterprise is
    the request-access path: custom pricing, custom limits and volume. A
    suspended key cannot execute; the developer portal shows the reason.

    Credit prices per successful call:

    | Endpoint | Credits per successful call |
    |----------|------------------------------|
    | POST /v1/api/intel/liquidity | 2 |
    | POST /v1/api/intel/risk | 2 |
    | POST /v1/api/wallet/approvals | 2 |
    | POST /v1/api/intel/why-down | 3 |
    | POST /v1/api/intel/team-wallets | 5 |
    | POST /v1/api/wallet/exact-movements | 5 |
    | POST /v1/api/wallet/pnl | 10 |
    | GET /v1/api/health, GET /v1/api/me | free |
    | GET /v1/api/discover | free, tightly capped |

    ## Rate limits
    Limits are per key, by access mode:

    | Access mode | Limit |
    |-------------|-------|
    | live paid: basic (default for new live keys) | 1,000 per hour |
    | live paid: premium (admin-assigned) | 5,000 per hour |
    | live paid: pro (admin-assigned) | 15,000 per hour |
    | partner / enterprise | admin-configured |
    | sandbox (`cogv_test_`) | 25 per hour, 100 per day, 1 per second |
    | metadata endpoints (`health`, `me`, `discover`), any valid key | 60 per hour, 1 per second |

    When a limit is exceeded the API returns `429` with error code
    `rate_limited` and a `Retry-After` header. Standard `RateLimit-*` headers
    are included on responses.

    ## Conventions
    - All executable intelligence endpoints use `POST` with a JSON body, so link
      previews, crawlers, and prefetchers can never trigger an execution.
    - `chain` is required on every POST body and must be one of `eth`, `base`, `bsc`.
    - Addresses are 0x-prefixed 40-hex-character EVM addresses.
    - Successful responses use the envelope
      `{ "ok": true, "data": ..., "meta": { ... } }`.
    - Failed responses use `{ "ok": false, "error": "<code>", "message"?: "...", "request_id"?: "..." }`.

    ## Disclaimer
    Cognivo intelligence is informational tooling, not financial advice. Data is
    derived from public blockchain state and may be incomplete, delayed, or
    revised. Always do your own research before making any financial decision.
servers:
  - url: https://api.cognivolabs.io
    description: Cognivo production API
tags:
  - name: Service
    description: Health and key introspection.
  - name: Discover
    description: Public discovery feed.
  - name: Token Intelligence
    description: Token-focused intelligence reads.
  - name: Wallet Intelligence
    description: Wallet-focused intelligence reads.
security:
  - cogvApiKey: []
paths:
  /v1/api/health:
    get:
      tags: [Service]
      summary: Service health check
      description: >
        Lightweight liveness probe for the public API surface. No API key is
        required. Returns `404` with error code `public_api_disabled` while the
        public API is not enabled.
      operationId: getHealth
      security: []
      responses:
        "200":
          description: The public API is up.
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                    example: true
                  service:
                    type: string
                    example: cognivo-public-api
                  version:
                    type: string
                    example: v1
                  generated_at:
                    type: string
                    format: date-time
                required: [ok, service, version, generated_at]
        "404":
          $ref: "#/components/responses/PublicApiDisabled"

  /v1/api/me:
    get:
      tags: [Service]
      summary: Introspect the calling API key
      description: >
        Returns safe metadata about the key used to authenticate this request:
        a redacted key label, project id, environment, tier, scopes, the
        effective hourly rate limit, the key's access mode, the owner
        account's Cognivo credit balance, and top-up guidance for live
        self-serve keys. Any valid key can call this endpoint; no specific
        scope is required. Free.
      operationId: getMe
      responses:
        "200":
          description: Key metadata inside the standard envelope.
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/SuccessEnvelope"
                  - type: object
                    properties:
                      data:
                        type: object
                        properties:
                          key:
                            type: string
                            description: Redacted key label. The full key is never returned.
                            example: cogv_test_****ab12
                          project_id:
                            type: string
                          environment:
                            type: string
                            enum: [live, test]
                          tier:
                            type: string
                            enum: [free, basic, premium, pro, enterprise]
                          scopes:
                            type: array
                            items:
                              type: string
                            example: [intel:read, liquidity:read]
                          rate_limit_per_hour:
                            type: integer
                            example: 1000
                          access_mode:
                            type: string
                            description: How this key can execute. `live` is the standard self-serve pay-as-you-go mode; `sandbox` keys cannot run live intelligence; `trial` is an optional admin-granted evaluation allowance; `partner` and `enterprise` are admin-managed arrangements; `metadata` marks legacy metadata-only keys; `suspended` keys cannot execute (the portal shows the reason).
                            example: live
                          credits_balance:
                            type: number
                            nullable: true
                            description: The owner account's current Cognivo credit balance, so integrators can monitor spend. `null` if the balance is temporarily unavailable.
                            example: 1250
                          top_up:
                            type: string
                            description: Human-readable guidance on where to top up credits for live self-serve keys.
                            example: Top up Cognivo credits on your account billing page in the dApp.
                          paid_mode:
                            type: boolean
                            description: True when pay-as-you-go billing is active for this key's project. Live self-serve keys run with paid mode on.
                            example: true
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/PublicApiDisabled"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"

  /v1/api/discover:
    get:
      tags: [Discover]
      summary: Public discovery feed
      description: >
        Returns recent public activity cards from the Cognivo discovery feed,
        newest first. Any valid key can call this endpoint; no specific scope
        is required. Free, with a tight rate cap.
      operationId: getDiscover
      parameters:
        - in: query
          name: limit
          required: false
          description: Maximum number of cards to return. Values outside 1 to 50 are clamped.
          schema:
            type: integer
            minimum: 1
            maximum: 50
            default: 20
        - in: query
          name: chain
          required: false
          description: Optional chain filter. Omit to include all supported chains.
          schema:
            $ref: "#/components/schemas/Chain"
      responses:
        "200":
          description: Discovery cards inside the standard envelope.
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/SuccessEnvelope"
                  - type: object
                    properties:
                      data:
                        type: object
                        properties:
                          cards:
                            type: array
                            description: Public activity cards, newest first.
                            items:
                              type: object
                          total:
                            type: integer
                            description: Number of cards in this response.
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/PublicApiDisabled"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"

  /v1/api/intel/why-down:
    post:
      tags: [Token Intelligence]
      summary: Why is this token down
      description: >
        Explains recent downward price pressure on a token: sell pressure,
        notable outflows, and related on-chain signals. Requires the
        `intel:read` scope. Self-serve on any live key with this scope: charged in Cognivo
        credits per successful call at the price listed in the API
        description; failed calls are never charged. Insufficient credits
        return `402 payment_required` (top up and retry). Sandbox keys cannot
        run live intelligence.
      operationId: postIntelWhyDown
      requestBody:
        $ref: "#/components/requestBodies/ChainAddressBody"
      responses:
        "200":
          $ref: "#/components/responses/IntelSuccess"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "402":
          $ref: "#/components/responses/PaymentRequired"
        "503":
          $ref: "#/components/responses/BillingUnavailable"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/PublicApiDisabled"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"

  /v1/api/intel/team-wallets:
    post:
      tags: [Token Intelligence]
      summary: Team and insider wallets for a token
      description: >
        Identifies wallets associated with a token's team or deployer cluster
        and summarizes their holdings and movements. Requires the `intel:read`
        scope. Self-serve on any live key with this scope: charged in Cognivo
        credits per successful call at the price listed in the API
        description; failed calls are never charged. Insufficient credits
        return `402 payment_required` (top up and retry). Sandbox keys cannot
        run live intelligence.
      operationId: postIntelTeamWallets
      requestBody:
        $ref: "#/components/requestBodies/ChainAddressBody"
      responses:
        "200":
          $ref: "#/components/responses/IntelSuccess"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "402":
          $ref: "#/components/responses/PaymentRequired"
        "503":
          $ref: "#/components/responses/BillingUnavailable"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/PublicApiDisabled"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"

  /v1/api/intel/liquidity:
    post:
      tags: [Token Intelligence]
      summary: Liquidity status for a token
      description: >
        Reports a token's DEX liquidity: pools, depth, and lock or burn status
        signals. Optional boolean flags request extra sections. Requires the
        `liquidity:read` scope. Self-serve on any live key with this scope: charged in Cognivo
        credits per successful call at the price listed in the API
        description; failed calls are never charged. Insufficient credits
        return `402 payment_required` (top up and retry). Sandbox keys cannot
        run live intelligence.
      operationId: postIntelLiquidity
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                chain:
                  $ref: "#/components/schemas/Chain"
                address:
                  allOf:
                    - $ref: "#/components/schemas/Address"
                  description: Token contract address.
                metadata:
                  type: boolean
                  default: false
                  description: Include token metadata in the result.
                locks:
                  type: boolean
                  default: false
                  description: Include liquidity lock details in the result.
                full:
                  type: boolean
                  default: false
                  description: Include the full detail set in the result.
              required: [chain, address]
      responses:
        "200":
          $ref: "#/components/responses/IntelSuccess"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "402":
          $ref: "#/components/responses/PaymentRequired"
        "503":
          $ref: "#/components/responses/BillingUnavailable"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/PublicApiDisabled"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"

  /v1/api/intel/risk:
    post:
      tags: [Token Intelligence]
      summary: Token risk assessment
      description: >
        Chain-aware risk read for a token contract, falling back to a red-flags
        scan when the primary assessment is unavailable. Requires the
        `intel:read` scope. Self-serve on any live key with this scope: charged in Cognivo
        credits per successful call at the price listed in the API
        description; failed calls are never charged. Insufficient credits
        return `402 payment_required` (top up and retry). Sandbox keys cannot
        run live intelligence.
      operationId: postIntelRisk
      requestBody:
        $ref: "#/components/requestBodies/ChainAddressBody"
      responses:
        "200":
          $ref: "#/components/responses/IntelSuccess"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "402":
          $ref: "#/components/responses/PaymentRequired"
        "503":
          $ref: "#/components/responses/BillingUnavailable"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/PublicApiDisabled"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"

  /v1/api/wallet/pnl:
    post:
      tags: [Wallet Intelligence]
      summary: Realized PnL for a wallet on one token
      description: >
        Computes realized profit and loss for one wallet on one token from
        on-chain activity. Returns `422` when there is not enough priced trade
        data to compute a result; a `422` is never charged. Requires the
        `intel:read` scope. Self-serve on any live key with this scope:
        charged in Cognivo credits per successful call at the price listed in
        the API description; failed calls are never charged. Insufficient
        credits return `402 payment_required` (top up and retry). Sandbox keys
        cannot run live intelligence.
      operationId: postWalletPnl
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                chain:
                  $ref: "#/components/schemas/Chain"
                wallet:
                  allOf:
                    - $ref: "#/components/schemas/Address"
                  description: Wallet address to analyze.
                token:
                  allOf:
                    - $ref: "#/components/schemas/Address"
                  description: Token contract address to compute PnL against.
              required: [chain, wallet, token]
      responses:
        "200":
          $ref: "#/components/responses/IntelSuccess"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "402":
          $ref: "#/components/responses/PaymentRequired"
        "503":
          $ref: "#/components/responses/BillingUnavailable"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/PublicApiDisabled"
        "422":
          $ref: "#/components/responses/UnprocessableResult"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"

  /v1/api/wallet/approvals:
    post:
      tags: [Wallet Intelligence]
      summary: Token approvals held against a wallet
      description: >
        Lists live token approvals granted by a wallet, with risk context, so
        integrators can surface revoke suggestions. Requires the
        `security:read` scope. Self-serve on any live key with this scope: charged in Cognivo
        credits per successful call at the price listed in the API
        description; failed calls are never charged. Insufficient credits
        return `402 payment_required` (top up and retry). Sandbox keys cannot
        run live intelligence.
      operationId: postWalletApprovals
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                chain:
                  $ref: "#/components/schemas/Chain"
                address:
                  allOf:
                    - $ref: "#/components/schemas/Address"
                  description: Wallet address to scan for approvals.
                limit:
                  type: integer
                  description: Optional page size for the approvals list.
                offset:
                  type: integer
                  description: Optional offset for the approvals list.
                full:
                  type: boolean
                  description: Include the full detail set in the result.
              required: [chain, address]
      responses:
        "200":
          $ref: "#/components/responses/IntelSuccess"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "402":
          $ref: "#/components/responses/PaymentRequired"
        "503":
          $ref: "#/components/responses/BillingUnavailable"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/PublicApiDisabled"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"

  /v1/api/wallet/exact-movements:
    post:
      tags: [Wallet Intelligence]
      summary: Exact on-chain movements for a wallet
      description: >
        Grounded, transaction-exact movement history for a wallet, optionally
        narrowed to a single token. Returns `422` when no movements are found.
        Requires the `intel:read` scope. Self-serve on any live key with this scope: charged in Cognivo
        credits per successful call at the price listed in the API
        description; failed calls are never charged. Insufficient credits
        return `402 payment_required` (top up and retry). Sandbox keys cannot
        run live intelligence.
      operationId: postWalletExactMovements
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                chain:
                  $ref: "#/components/schemas/Chain"
                wallet:
                  allOf:
                    - $ref: "#/components/schemas/Address"
                  description: Wallet address to trace.
                token:
                  allOf:
                    - $ref: "#/components/schemas/Address"
                  description: Optional token contract address to narrow the movement set.
              required: [chain, wallet]
      responses:
        "200":
          $ref: "#/components/responses/IntelSuccess"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "402":
          $ref: "#/components/responses/PaymentRequired"
        "503":
          $ref: "#/components/responses/BillingUnavailable"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/PublicApiDisabled"
        "422":
          $ref: "#/components/responses/UnprocessableResult"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"

components:
  securitySchemes:
    cogvApiKey:
      type: apiKey
      in: header
      name: X-API-Key
      description: >
        Cognivo developer API key (`cogv_live_...` or `cogv_test_...`), created
        in the developer portal. `Authorization: Bearer <key>` is accepted as
        an alias. Keys are hashed at rest, scoped, and rate limited per key.

  requestBodies:
    ChainAddressBody:
      required: true
      content:
        application/json:
          schema:
            type: object
            properties:
              chain:
                $ref: "#/components/schemas/Chain"
              address:
                allOf:
                  - $ref: "#/components/schemas/Address"
                description: Token contract address.
            required: [chain, address]

  schemas:
    Chain:
      type: string
      enum: [eth, base, bsc]
      description: Supported chain. eth is Ethereum mainnet, base is Base, bsc is BNB Smart Chain.
      example: eth

    Address:
      type: string
      pattern: "^0x[0-9a-fA-F]{40}$"
      description: 0x-prefixed 40-hex-character EVM address. Case-insensitive; normalized to lowercase.
      example: "0x1234567890abcdef1234567890abcdef12345678"

    Meta:
      type: object
      description: Response metadata attached to every successful call.
      properties:
        chain:
          allOf:
            - $ref: "#/components/schemas/Chain"
          description: Present on chain-specific results.
        sources:
          type: array
          items:
            type: string
          description: Cognivo source labels backing this result, when available.
        request_id:
          type: string
          description: Unique id for this request. Include it in support requests.
          example: capi_1a2b3c4d5e6f7a8b9c0d1e2f
        credits_charged:
          type: integer
          description: Credits deducted for this call. The endpoint's credit price on a successful paid call; 0 for free endpoints, trial-allowance calls, and any failed or honest-empty result. A successful call is charged exactly once.
          example: 2
        generated_at:
          type: string
          format: date-time
          description: UTC timestamp when the response was generated.
      required: [request_id, credits_charged, generated_at]

    SuccessEnvelope:
      type: object
      description: Standard success envelope.
      properties:
        ok:
          type: boolean
          example: true
        data:
          type: object
          description: >
            Endpoint-specific result. Field shapes may gain new fields over
            time; integrators should ignore unknown fields.
        meta:
          $ref: "#/components/schemas/Meta"
      required: [ok, data, meta]

    ErrorEnvelope:
      type: object
      description: >
        Standard error envelope. `request_id` is present once a request has
        passed authentication and reached endpoint handling; authentication
        and rate-limit errors may omit it.
      properties:
        ok:
          type: boolean
          example: false
        error:
          type: string
          description: |
            Machine-readable error code. Codes by status:
            - 400: `bad_request`, `invalid_chain`, `invalid_address`, `invalid_wallet`, `invalid_token`
            - 401: `missing_api_key`, `invalid_api_key`
            - 402: `payment_required` (not enough Cognivo credits for this call; top up on your Cognivo account billing page and try again; nothing was charged)
            - 403: `access_required` (legacy metadata-only keys), `sandbox_limited` (sandbox keys cannot run live intelligence), `trial_expired`, `trial_exhausted`, `endpoint_denied`, `suspended_key`, `revoked_api_key`, `project_disabled`, `scope_denied`, `origin_denied`
            - 404: `public_api_disabled`
            - 422: `insufficient_data`, `no_result` (empty-result reads; never charged)
            - 429: `rate_limited` (the response carries `Retry-After`)
            - 500: `internal_error`
            - 503: `pricing_mismatch`, `billing_unavailable`, `billing_commit_failed`, `unavailable` (rare billing or dependency hiccups; nothing was charged, simply retry)

            Failed calls are never charged.
          example: invalid_chain
        message:
          type: string
          description: Optional human-readable detail.
        request_id:
          type: string
          description: Unique id for this request, when available.
      required: [ok, error]

  responses:
    IntelSuccess:
      description: Intelligence result inside the standard envelope.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/SuccessEnvelope"
    BadRequest:
      description: >
        Invalid input. `invalid_chain` when `chain` is not one of eth, base,
        bsc; `invalid_<field>` (for example `invalid_address`, `invalid_wallet`,
        `invalid_token`) when a required address field is missing or not a
        0x-prefixed 40-hex address.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorEnvelope"
          example:
            ok: false
            error: invalid_chain
            message: "chain must be one of: eth, base, bsc"
            request_id: capi_1a2b3c4d5e6f7a8b9c0d1e2f
    Unauthorized:
      description: >
        `missing_api_key` when no key was presented; `invalid_api_key` when the
        key has the wrong prefix or does not match any active key.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorEnvelope"
          example:
            ok: false
            error: missing_api_key
    Forbidden:
      description: >
        `access_required` when a legacy metadata-only key tries a live call
        (create a new self-serve live key to move to pay-as-you-go);
        `sandbox_limited` when a Sandbox key tries a live intelligence call
        (sandbox keys cannot run live intelligence); `trial_expired` /
        `trial_exhausted` when an optional trial allowance has ended or is
        used up (not needed for ordinary paid use; use a live key);
        `endpoint_denied` when the key's access arrangement does not cover
        this specific endpoint; `suspended_key` when the key is suspended and
        cannot execute (the portal shows the reason); `revoked_api_key` when
        the key was revoked or rotated away; `project_disabled` when the
        owning project is suspended; `scope_denied` when the key lacks the
        scope this endpoint requires; `origin_denied` when an Origin or IP
        allowlist is configured on the key and this request does not match
        it. Denied calls never run and are never charged.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorEnvelope"
          example:
            ok: false
            error: scope_denied
    PaymentRequired:
      description: >
        `payment_required`: not enough Cognivo credits for this call. Top up
        in your Cognivo account billing page and try again. Failed calls are
        never charged, so nothing was deducted for this attempt. `GET
        /v1/api/me` shows the current `credits_balance`.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorEnvelope"
          example:
            ok: false
            error: payment_required
            message: "Not enough Cognivo credits for this call. Top up in your Cognivo account billing page and try again. Failed calls are never charged."
    PublicApiDisabled:
      description: The public API is not currently enabled.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorEnvelope"
          example:
            ok: false
            error: public_api_disabled
    RateLimited:
      description: >
        The key's request budget is exhausted. Live keys follow their access
        mode's limit (basic 1,000 per hour by default); sandbox keys are
        capped at 25 requests per hour, 100 per day and 1 per second; the
        metadata surface is capped at 60 per hour with a 1-per-second burst
        cap for every valid key. Honor the `Retry-After` header, check the
        `RateLimit-*` response headers, and retry after the window resets.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorEnvelope"
          example:
            ok: false
            error: rate_limited
    UnprocessableResult:
      description: >
        The request was valid but no computable result exists, for example a
        PnL request with no priced trade legs (`insufficient_data`) or a
        movement trace with no matching activity (`no_result`). Empty results
        are never charged.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorEnvelope"
          example:
            ok: false
            error: insufficient_data
            request_id: capi_1a2b3c4d5e6f7a8b9c0d1e2f
    BillingUnavailable:
      description: >
        Rare billing or dependency hiccup: `pricing_mismatch`,
        `billing_unavailable`, `billing_commit_failed`, or `unavailable`.
        Nothing was charged; simply retry the call.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorEnvelope"
          example:
            ok: false
            error: billing_unavailable
    InternalError:
      description: Unexpected server-side failure. Retry later; include the request id when contacting support.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorEnvelope"
          example:
            ok: false
            error: internal_error
            request_id: capi_1a2b3c4d5e6f7a8b9c0d1e2f
