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

> ## Agent Instructions
> HEVN is payments software: an API and app over a Base smart wallet. HEVN is not a bank and holds no key to the wallet. Virtual accounts, fiat payins and fiat payouts are provided by partner banks, which hold fiat while it is in transit. Self-serve (the General tab): the person who controls the email signs for the wallet. Developers integrate /dapi/v1 in one of two ways. HEVN Connect (recommended, the HEVN Connect tab): the integrator's customer creates or links a HEVN account in a HEVN-hosted sign-in window on the integrator's site, the integrator's backend reads the linked account and books its payouts, and the account holder approves each payout in that window. External wallets (the External wallets tab, enabled per integrator): the integrator creates a client through the API, registers a wallet address the customer holds as an external account, and requests virtual accounts that deliver to that address. The customer's own wallet sends each transfer that funds a payout. The developer key signs for the integrator's wallet and its sub accounts and cannot sign for a client's wallet.
> Use HEVN's terms as written. A product is the region a client requests. A rail is the bank route HEVN picks for the product. A virtual account (bnk_) is the record a partner bank opens for a client. Account details are what a payer needs to send a bank transfer, returned in a field named requisites. A client (cl_) is a customer's account: linked to the integrator through Sign in with HEVN (POST /dapi/v1/connect/sessions, then POST /dapi/v1/clients/link), or created with POST /dapi/v1/clients for an external-wallets integration. An external account (acc_, kind external) is a wallet address the client holds and signs for. A sub account (acc_, kind sub) is a further wallet of the integrator's own account on Base, spent with the developer key. Write 'sub account' as two words. A contact is a saved destination. A beneficiary is the party that receives a fiat payout. Money leaving an account is a payout, whether it goes to a bank account or to a wallet.
> Do not name a bank, payment institution, card issuer, identity-verification vendor or stablecoin issuer. Say 'the partner bank'. Do not describe HEVN as licensed, regulated or insured.
> HEVN publishes no fee rates, spreads or minimums. Prices come from a quote on a specific payment. Direct pricing questions to HEVN and do not invent numbers.
> The API is at /dapi/v1 and takes a developer-key session plus an X-Hevn-Account header. Developer keys have an IP allowlist and no scopes. Remote transfers are at /api/v1/remote_spend_limit and take a remote transfer key (rsl_) in X-Api-Key, bounded by an onchain spend permission the account holder grants. The two credentials are separate and neither works on the other API. The HEVN CLI is discontinued.

# Add an account

> Without `kind`, or with `kind: external`: register an address for the client on `chain` (base, arb, eth, op, pol or sol). A receiving account opened on it delivers USDC on that network, an on-chain pay-in can be delivered to it, and a Base address can fund payouts it sends itself. Answers 201 the first time and 200 with `Idempotency-Replayed: true` when the same address was already added with the same label; another label is `account_address_taken`.

With `kind: sub`: open a sub account, a further wallet of your own account on Base that holds one token, `asset`: `USDC` (the default) or `RD`. The token is chosen once; receiving accounts, payouts and moves of the account run in it, and money moves only between accounts of the same token. Its address takes deposits at once; another token sent to it is not in `balance` and can only be moved out to the account's wallet with a swap. Name it as `sourceAccount` or `destinationAccount` on payouts, pay-ins and swaps, and as `accountId` on a receiving account; a payout or swap that leaves it is signed with your developer key, exactly like one that leaves the account's wallet. A create whose `label` and `asset` a sub account already carries answers 200 with that account; the same `label` with another `asset`, or a create without `label`, opens a new one. A sub account is opened on your own account only: a request that acts for a client returns `403 account_not_controlled`. An account whose wallet is not protected by co-signing returns `409 safe_mode_required`. A sub account cannot be archived.



## OpenAPI

````yaml /openapi.json post /client/accounts
openapi: 3.1.0
info:
  title: HEVN Platform API
  description: >-
    HEVN's account, verification and money-movement API. Verification follows a
    submission workflow: save applicant info and documents, inspect outstanding
    requirements, then explicitly complete the submission to send an immutable
    snapshot for review. Completing a submission is separate from editing it.
  version: 1.0.0
servers: []
security: []
tags:
  - name: auth
    description: >-
      Log in with a developer key and refresh the access token. Developer keys
      are created in the HEVN app.
  - name: accounts
    description: Create and manage business or individual customer accounts.
  - name: client accounts
    description: >-
      Register addresses a client holds on supported networks, and open sub
      accounts of the client, to receive and pay USDC through.
  - name: verification
    description: >-
      Collect business-applicant and related-individual information, inspect
      requirements, and complete a verification submission for review.
  - name: documents
    description: Upload verification and payment evidence for later reference by id.
  - name: virtual accounts
    description: Discover payment methods and create persistent receiving account details.
  - name: transfers
    description: Quote, create, authorize and track incoming or outgoing transfers.
  - name: contacts
    description: Create saved contacts and inspect their available payment channels.
  - name: transactions
    description: Read and export the account ledger.
  - name: escrow
    description: Create, authorize and reconcile on-chain escrow agreements.
  - name: sandbox
    description: >-
      Emulate funding and lifecycle events in the sandbox. These routes return
      `404` in production.
paths:
  /client/accounts:
    post:
      tags:
        - client accounts
      summary: Add an account
      description: >-
        Without `kind`, or with `kind: external`: register an address for the
        client on `chain` (base, arb, eth, op, pol or sol). A receiving account
        opened on it delivers USDC on that network, an on-chain pay-in can be
        delivered to it, and a Base address can fund payouts it sends itself.
        Answers 201 the first time and 200 with `Idempotency-Replayed: true`
        when the same address was already added with the same label; another
        label is `account_address_taken`.


        With `kind: sub`: open a sub account, a further wallet of your own
        account on Base that holds one token, `asset`: `USDC` (the default) or
        `RD`. The token is chosen once; receiving accounts, payouts and moves of
        the account run in it, and money moves only between accounts of the same
        token. Its address takes deposits at once; another token sent to it is
        not in `balance` and can only be moved out to the account's wallet with
        a swap. Name it as `sourceAccount` or `destinationAccount` on payouts,
        pay-ins and swaps, and as `accountId` on a receiving account; a payout
        or swap that leaves it is signed with your developer key, exactly like
        one that leaves the account's wallet. A create whose `label` and `asset`
        a sub account already carries answers 200 with that account; the same
        `label` with another `asset`, or a create without `label`, opens a new
        one. A sub account is opened on your own account only: a request that
        acts for a client returns `403 account_not_controlled`. An account whose
        wallet is not protected by co-signing returns `409 safe_mode_required`.
        A sub account cannot be archived.
      operationId: create_account_client_accounts_post
      parameters:
        - name: X-Hevn-Account
          in: header
          required: true
          schema:
            type: string
            description: The selected client account, as a `cl_…` id.
            examples:
              - cl_9f2c1ab84d7e4f1fa3c65b0e7d9a2c41
            title: X-Hevn-Account
          description: The selected client account, as a `cl_…` id.
        - name: Idempotency-Key
          in: header
          required: false
          schema:
            anyOf:
              - type: string
              - type: 'null'
            description: >-
              Your own key for this write, `^[A-Za-z0-9._:-]{1,128}$`. A retry
              with the same key replays the first answer; the same key with a
              different request is refused.
            examples:
              - po-inv-2026-114
            title: Idempotency-Key
          description: >-
            Your own key for this write, `^[A-Za-z0-9._:-]{1,128}$`. A retry
            with the same key replays the first answer; the same key with a
            different request is refused.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              oneOf:
                - $ref: '#/components/schemas/ClientExternalAccountRequest'
                - $ref: '#/components/schemas/ClientSubAccountRequest'
              title: Data
      responses:
        '201':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ClientAccountView'
        '422':
          description: Request validation failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PlatformErrorResponse'
      security:
        - HTTPBearer: []
components:
  schemas:
    ClientExternalAccountRequest:
      properties:
        kind:
          type: string
          const: external
          title: Kind
          description: >-
            `external`, the default: an address the client holds and signs for
            itself.
          default: external
        chain:
          type: string
          enum:
            - base
            - arb
            - eth
            - op
            - pol
            - sol
          title: WalletNetwork
          description: >-
            Network the address receives USDC on: base, arb, eth, op, pol or
            sol.
        address:
          type: string
          maxLength: 64
          minLength: 1
          title: Address
          description: >-
            Address on `chain`: a 0x address on EVM networks, a base58 address
            on Solana.
          examples:
            - '0x8ba1f109551bD432803012645Ac136ddd64DBA72'
        label:
          anyOf:
            - type: string
              maxLength: 64
            - type: 'null'
          title: Label
          description: Name shown for this address.
      additionalProperties: false
      type: object
      required:
        - chain
        - address
      title: ClientExternalAccountRequest
    ClientSubAccountRequest:
      properties:
        kind:
          type: string
          const: sub
          title: Kind
          description: >-
            `sub`: a further wallet of the client that HEVN opens on Base. It
            holds one token, chosen with `asset`, and is spent with your
            developer key exactly like the client's wallet.
        asset:
          type: string
          enum:
            - USDC
            - RD
          title: Asset
          description: >-
            The token the sub account holds: `USDC` (the default) or `RD`. It is
            chosen once and never changes; receiving accounts, payouts and moves
            of the account all run in this token.
          default: USDC
        label:
          anyOf:
            - type: string
              maxLength: 64
            - type: 'null'
          title: Label
          description: >-
            Name shown for this account. A create that repeats the label and the
            `asset` of a sub account the client already has returns that account
            instead of opening another; the same label with another `asset`
            opens a new account.
      additionalProperties: false
      type: object
      required:
        - kind
      title: ClientSubAccountRequest
    ClientAccountView:
      properties:
        accountId:
          type: string
          pattern: ^(?:acc_)?[A-Za-z0-9._:\-]{1,216}$
          title: Accountid
          description: Stable public identifier of this account, as an `acc_` id.
          examples:
            - acc_9f2c1ab84d7e4f1fa3c65b0e7d9a2c41
        kind:
          $ref: '#/components/schemas/ClientAccountKind'
          description: >-
            `external`: an address the client holds and signs for itself. `sub`:
            a further wallet of the client that HEVN opened, spent with your
            developer key.
        asset:
          type: string
          enum:
            - USDC
            - RD
          title: Asset
          description: >-
            The token the account holds: `USDC`, or `RD` for a sub account
            opened with `asset: RD`.
        chain:
          type: string
          enum:
            - base
            - arb
            - eth
            - op
            - pol
            - sol
          title: WalletNetwork
          description: >-
            Network the address holds `asset` on. Always `base` for a sub
            account.
        address:
          type: string
          title: Address
          description: Address on `chain`.
        label:
          anyOf:
            - type: string
            - type: 'null'
          title: Label
          description: Name shown for this account.
        balance:
          type: string
          title: Balance
          description: >-
            `asset` held at the address on `chain`, read from the network when
            older than a minute and kept as last read when the network does not
            answer.
          example: '500.00'
        syncedAt:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Syncedat
          description: UTC timestamp of the last successful balance read.
        createdAt:
          type: string
          format: date-time
          title: Createdat
          description: UTC timestamp when the account was added.
      type: object
      required:
        - accountId
        - kind
        - asset
        - chain
        - address
        - balance
        - createdAt
      title: ClientAccountView
    PlatformErrorResponse:
      properties:
        error:
          $ref: '#/components/schemas/PlatformErrorBody'
          description: Public error body.
      type: object
      required:
        - error
      title: PlatformErrorResponse
    ClientAccountKind:
      type: string
      enum:
        - external
        - sub
      title: ClientAccountKind
    PlatformErrorBody:
      properties:
        code:
          $ref: '#/components/schemas/PlatformErrorCode'
          description: Stable machine-readable error code to branch on.
        message:
          type: string
          title: Message
          description: Human-readable explanation safe to show to an end user.
        details:
          anyOf:
            - additionalProperties: true
              type: object
            - type: 'null'
          title: Details
          description: >-
            Structured context for this error, with camelCase keys.
            `validation_failed` lists `fields`, plus `location` for a query,
            path or header. A `5xx` adds `requestId`.
      type: object
      required:
        - code
        - message
      title: PlatformErrorBody
    PlatformErrorCode:
      type: string
      enum:
        - invalid_request
        - validation_failed
        - invalid_cursor
        - invalid_id
        - idempotency_key_invalid
        - idempotency_key_reused
        - unauthenticated
        - token_expired
        - forbidden
        - not_found
        - method_not_allowed
        - conflict
        - gone
        - payload_too_large
        - rate_limited
        - provider_unavailable
        - database_unavailable
        - internal_error
        - invalid_credentials
        - request_expired
        - challenge_not_found
        - challenge_consumed
        - challenge_expired
        - signature_invalid
        - key_not_registered
        - signer_not_attached
        - wallet_not_linked
        - approval_consumed
        - approval_expired
        - approval_mismatch
        - signing_policy_refused
        - login_unavailable
        - login_mode_unavailable
        - developer_key_not_found
        - developer_key_already_exists
        - account_header_invalid
        - account_scope_conflict
        - account_not_found
        - account_forbidden
        - account_read_only
        - account_not_controlled
        - contact_not_found
        - quote_not_submitted
        - quote_not_fundable
        - funding_mode_unsupported
        - funding_token_unsupported
        - insufficient_funds
        - smart_wallet_not_deployed
        - wallet_owner_unverified
        - already_funded
        - payment_slot_consumed
        - funding_in_progress
        - funding_attempt_expired
        - contact_changed
        - user_operation_rejected
        - user_operation_unavailable
        - transfer_policy_denied
        - client_creation_not_enabled
        - client_not_found
        - link_code_invalid
        - link_code_expired
        - client_already_linked
        - redirect_uri_not_allowed
        - payout_not_awaiting_signature
        - verification_not_applicable
        - profile_locked
        - contact_not_payable
        - contact_chain_unsupported
        - contact_token_unsupported
        - contact_payment_details_invalid
        - amount_below_minimum
        - amount_above_maximum
        - amount_precision_unsupported
        - payout_not_found
        - payout_not_fundable
        - quote_expired
        - bundler_rejected
        - bundler_unavailable
        - contact_in_use
        - kyb_incomplete
        - kyb_documents_processing
        - kyb_roster_conflict
        - kyb_subject_conflict
        - document_not_found
        - document_type_unsupported
        - invalid_enum_value
        - entity_not_found
        - escrow_not_found
        - escrow_action_not_found
        - escrow_not_operated_by_you
        - escrow_state_changed
        - action_in_flight
        - simulation_failed
        - stale_nonce
        - amount_out_of_range
        - amount_not_allowed
        - window_closed
        - token_not_supported
        - receiver_not_a_client
        - rail_not_found
        - rail_not_available
        - payin_not_available
        - payin_expired
        - payin_not_found
        - transaction_not_found
        - account_unavailable
        - account_not_supported
        - swap_not_found
        - swap_route_unavailable
        - swap_not_confirmable
        - intent_not_signable
        - sandbox_amount_limit_exceeded
        - sandbox_faucet_balance_too_high
        - account_address_taken
        - account_address_refused
        - account_not_spendable
        - account_destination_unsupported
        - source_account_unsupported
        - account_funding_invalid
        - account_spend_forbidden
        - refund_address_required
        - safe_mode_required
        - account_archive_unsupported
      title: PlatformErrorCode
  securitySchemes:
    HTTPBearer:
      type: http
      scheme: bearer

````

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