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

# Get balances

> Return the balance triple of `normal` (public stablecoin),
`confidential` (cAROUSD; decrypted server-side for custodial wallets),
and `total`, plus gas ETH, for every wallet or one wallet.

Confidential reads involve FHE decryption and are comparatively heavy;
for frequent polling use `GET /gas` instead.




## OpenAPI

````yaml /api-reference/openapi.yaml get /balances
openapi: 3.1.0
info:
  title: AroPay API
  version: 1.0.0
  description: |
    The AroPay API for orchestrating sealed, private payments on public
    ledgers, built on the Aro Confidential Rails (Zama Protocol FHE). The
    current deployment is an MVP sandbox for B2B users on Ethereum Sepolia,
    with Mainnet to follow.

    Every response (except the flat Sandbox probes)
    uses the shared envelope: `{ "ok": true, "data": … }` on success and
    `{ "ok": false, "error": { "code", "message", "details?" } }` on failure.

    Amounts are decimal strings in human units (e.g. `"125.50"`). Write
    requests must send `Content-Type: application/json`.
  contact:
    name: Aro Media
    url: https://aro.media
servers:
  - url: https://aropay.aro.media/api/v1
    description: Sandbox
  - url: http://aropay.localhost:3000/api/v1
    description: Local development
security:
  - apiKeyAuth: []
  - sessionCookie: []
tags:
  - name: Auth
    description: Password, TOTP, and passkey login; session inspection and logout.
  - name: Profile & security
    description: Profile, password, two-factor authentication, and passkey management.
    x-group: Profile & security
  - name: API keys
    description: Programmatic credentials. Creation and revocation are session-only.
  - name: Wallets
    description: Custodial and external (watch-only) wallets.
  - name: Balances
    description: Balance triples and lightweight gas reads.
  - name: Money movement
    description: Faucet funding, minting, transfers, and redemptions.
  - name: Transactions
    description: History, single-transaction reads, and notarized receipts.
  - name: Sandbox
    description: Unauthenticated status and echo probes with a flat response shape.
paths:
  /balances:
    get:
      tags:
        - Balances
      summary: Get balances
      description: |
        Return the balance triple of `normal` (public stablecoin),
        `confidential` (cAROUSD; decrypted server-side for custodial wallets),
        and `total`, plus gas ETH, for every wallet or one wallet.

        Confidential reads involve FHE decryption and are comparatively heavy;
        for frequent polling use `GET /gas` instead.
      operationId: getBalances
      parameters:
        - name: walletId
          in: query
          required: false
          schema:
            type: string
          description: Restrict to a single wallet.
      responses:
        '200':
          description: Balance triples.
          content:
            application/json:
              schema:
                type: object
                required:
                  - ok
                  - data
                properties:
                  ok:
                    const: true
                  data:
                    type: object
                    required:
                      - balances
                    properties:
                      balances:
                        type: array
                        items:
                          $ref: '#/components/schemas/WalletBalances'
              example:
                ok: true
                data:
                  balances:
                    - wallet:
                        id: ckwlt0001abcd
                        address: '0x8Ba1f109551bD432803012645Ac136ddd64DBA72'
                        type: CUSTODIAL
                        label: Payouts
                        isPrimary: true
                        createdAt: '2026-08-13T09:30:00.000Z'
                      eth:
                        amount: '0.05'
                      normal:
                        token: AROUSD
                        amount: '890.00'
                      confidential:
                        token: cAROUSD
                        amount: '65.00'
                        encrypted: false
                        handle: 0x1f8e…
                      total:
                        amount: '955.00'
                        currency: USD
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/AccountDisabled'
        '404':
          description: Account has no wallets, or the requested wallet is unknown.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
components:
  schemas:
    WalletBalances:
      type: object
      description: The balance triple plus gas for one wallet.
      required:
        - wallet
        - eth
        - normal
        - confidential
        - total
      properties:
        wallet:
          $ref: '#/components/schemas/Wallet'
        eth:
          type: object
          required:
            - amount
          properties:
            amount:
              type: string
              description: Sepolia ETH, human units.
        normal:
          type: object
          description: Public ERC-20 balance of the test stablecoin.
          required:
            - token
            - amount
          properties:
            token:
              type: string
            amount:
              type: string
        confidential:
          type: object
          description: cAROUSD (ERC-7984) encrypted balance.
          required:
            - token
            - amount
            - encrypted
            - handle
          properties:
            token:
              type: string
            amount:
              type:
                - string
                - 'null'
              description: Decrypted amount; `null` for external (watch-only) wallets.
            encrypted:
              type: boolean
              description: True when the value is only available as an encrypted handle.
            handle:
              type: string
              description: The on-chain encrypted handle.
        total:
          type: object
          required:
            - amount
            - currency
          properties:
            amount:
              type:
                - string
                - 'null'
              description: normal + confidential, when the confidential side is known.
            currency:
              type: string
              examples:
                - USD
    ErrorResponse:
      type: object
      description: The shared failure envelope.
      required:
        - ok
        - error
      properties:
        ok:
          const: false
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
              description: Machine-readable error code; match on this, not `message`.
            message:
              type: string
            details:
              description: Structured context, e.g. per-field validation issues.
    Wallet:
      type: object
      description: A custodial or external (watch-only) wallet.
      required:
        - id
        - address
        - type
        - label
        - isPrimary
        - createdAt
      properties:
        id:
          type: string
          examples:
            - ckwlt0001abcd
        address:
          type: string
          description: EIP-55 checksummed address.
          examples:
            - '0x8Ba1f109551bD432803012645Ac136ddd64DBA72'
        type:
          type: string
          enum:
            - CUSTODIAL
            - EXTERNAL
          description: >-
            Custodial wallets can spend through the sandbox; external wallets
            are watch-only.
        label:
          type:
            - string
            - 'null'
        isPrimary:
          type: boolean
          description: The account's first wallet becomes primary.
        createdAt:
          type: string
          format: date-time
  responses:
    Unauthorized:
      description: Missing or invalid credential.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            ok: false
            error:
              code: invalid_api_key
              message: Invalid API key.
    AccountDisabled:
      description: The account has been deactivated.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            ok: false
            error:
              code: account_disabled
              message: This account is disabled.
    RateLimited:
      description: Rate limit exceeded.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            ok: false
            error:
              code: rate_limited
              message: Too many requests. Try again shortly.
    InternalError:
      description: Unexpected server error.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            ok: false
            error:
              code: internal_error
              message: An unexpected error occurred.
  securitySchemes:
    apiKeyAuth:
      type: http
      scheme: bearer
      bearerFormat: aro_sk_…
      description: |
        AroPay API key, sent as `Authorization: Bearer aro_sk_…`. Created in
        the dashboard under Settings → API keys. Takes precedence over a
        session cookie when both are present.
      x-default: aro_sk_your_key_here
    sessionCookie:
      type: apiKey
      in: cookie
      name: aropay_session
      description: |
        Browser session cookie minted by `POST /auth/login` (or passkey
        login). httpOnly, `SameSite=Lax`, 24 h TTL. Endpoints marked
        **Session-only** accept only this credential and return
        `403 session_required` for API keys.

````