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

# Balances for a customer wallet

> Returns balances for every derived address of the customer wallet — native coin plus
supported stablecoins (USDT/USDC where applicable).

**Served from Rach's database, not a live chain read.** The deposit monitor keeps the
stored figure in step with the chain, raising it on deposits and lowering it on spends,
so this endpoint costs nothing and can be polled as often as your UI needs.

| Query | Behaviour |
|-------|-----------|
| *(none)* | Stored balances, returned immediately. |
| `?refresh=true` | Returns stored balances immediately **and** schedules the monitor to re-read these addresses on its next cycle (typically ≤30s). Responds with `refresh_requested: true` and `refresh_eta_seconds`; poll again after that interval. Concurrent refresh requests collapse into one chain read. |
| `?live=true` | Reads the chain directly, throttled per address. Needed only for the confirmed-vs-unconfirmed split on BTC/LTC/BCH, or when auditing for drift. |

Each address object carries `source` (`database` or `chain`) and an array of per-currency
`balances`; every supported currency for the network is present, including zeros. Each
balance carries `as_of` — when that figure was last read from the chain.

`spendable` is what can actually be sent right now:
- **XRP:** excludes the locked ~1 XRP base reserve.
- **BTC / LTC / BCH:** with `?live=true`, `confirmed` counts confirmed UTXOs only;
  `balance` may include unconfirmed (0-conf) funds.
- **All other networks:** `spendable` equals `balance`.




## OpenAPI

````yaml /api-reference/openapi.json get /api/v1/wallet/{customerID}/balances
openapi: 3.0.3
info:
  contact:
    email: support@rachfinance.com
    name: Rach Finance Support
  description: >
    Complete REST API for the Rach Finance platform — covering authentication,
    KYC, crypto payment gateway,

    Wallet-as-a-Service (WaaS) HD wallets, remittance/FX transfers, OTC trading,
    virtual accounts,

    analytics, webhooks, push notifications, and all admin operations.


    ## Authentication

    Three authentication methods are supported depending on the endpoint group:


    | Method | Header | Used For |

    |--------|--------|----------|

    | JWT Bearer | `Authorization: Bearer <token>` | Dashboard / user-facing
    endpoints |

    | API Key | `X-API-Key: <key>` | Server-to-server integrations (remittance,
    checkout, WaaS) |

    | Admin Token | `X-Admin-Token: <token>` | Admin-only operations |


    ## API Key Environments


    Every business has two server-to-server API keys. The key **prefix is
    authoritative** —

    the environment is determined by which key you send, not a toggle in your
    dashboard:


    | Prefix | Type | Behaviour |

    |--------|------|-----------|

    | `test_sk_` | Test (sandbox) | Testnet addresses, no real funds move, no
    blockchain confirmations needed |

    | `live_sk_` | Production | Mainnet addresses, real transactions, webhooks
    fire on real confirmations |


    **Use the same code path for both environments** — swap the key, not the
    logic.

    The `is_test_mode` flag is locked onto every checkout session and wallet
    operation

    at the moment the request is authenticated, so mode cannot drift mid-flow
    even if

    you later toggle sandbox mode in the dashboard.


    Sandbox toggle (`POST /api/v1/api-keys/toggle-sandbox`) only affects legacy
    keys

    (no prefix). If you use prefixed keys it has no effect.


    ## Base URL

    `https://api.rach.finance/api/v1/`


    (Rach CaaS — Card-as-a-Service — is served separately at
    `https://api.rach.finance/caas/api/v1/`.)


    ## Official SDKs


    Client libraries covering every endpoint on this page:


    | Language | Install | Source |

    |----------|---------|--------|

    | **JavaScript / Node** | `npm install rachfinance` | `sdk/javascript/` |

    | **Python** | `pip install rachfinance` | `sdk/python/` |

    | **Go** | `go get github.com/rach-finance/rachfinance-go` | `sdk/go/` |

    | **Flutter / Dart** | add `rachfinance` to `pubspec.yaml` | `sdk/flutter/`
    |


    **JavaScript quick start:**

    ```js

    const RachFinance = require('rachfinance');

    const rach = new RachFinance({ apiKey: 'live_sk_...' });

    const session = await rach.checkout.create({ amount: 100, currency: 'USD',
      customerEmail: 'user@example.com', reference: 'ORDER-001' });
    ```


    **Python quick start:**

    ```python

    from rachfinance import RachFinance

    rach = RachFinance(api_key='live_sk_...')

    session = rach.checkout.create(amount=100, currency='USD',
        customer_email='user@example.com', reference='ORDER-001')
    ```


    **Go quick start:**

    ```go

    c, _ := rachfinance.New(rachfinance.WithAPIKey("live_sk_..."))

    session, err := c.Checkout.Create(ctx, rachfinance.CreateCheckoutRequest{
        Amount: 100, Currency: "USD",
        CustomerEmail: "user@example.com", Reference: "ORDER-001",
    })

    ```


    **Flutter quick start:**

    ```dart

    final rach = RachFinance(apiKey: 'live_sk_...');

    final session = await rach.checkout.create(
        amount: 100, currency: 'USD',
        customerEmail: 'user@example.com', reference: 'ORDER-001');
    ```


    ## Common Error Format

    ```json

    { "error": "Human-readable error message" }

    ```
  title: Rach Finance API
  version: 1.0.0
servers:
  - description: Production
    url: https://api.rach.finance
  - description: Local development
    url: http://localhost:8080
security: []
tags:
  - name: Checkout (Crypto Gateway)
  - name: WaaS (Wallet-as-a-Service)
  - description: >
      Unified token swap API for merchants. Same-chain swaps on POL/BSC are
      executed via the

      Rach FiatSwapV2 smart contract; cross-chain pairs are routed through LiFi.
      Merchants

      consume one API — routing is invisible to them.


      **Auth:** Quote is public. Execute and history require `X-API-Key`.
    name: Swap
  - description: >
      Real-time crypto market data service — included with every merchant
      account.

      Prices for 100+ coins served from Rach's edge cache with no additional
      setup required.


      **Auth:** `X-API-Key` or `Authorization: Bearer <key>`. Health check is
      public.


      **Rate limit:** 120 REST requests per merchant per minute.


      **WebSocket:** Connect to `/v1/market/ws?key=<api-key>`, send a subscribe
      message, then receive

      a snapshot immediately followed by real-time price ticks as they change.
    name: Market Data
paths:
  /api/v1/wallet/{customerID}/balances:
    get:
      tags:
        - WaaS (Wallet-as-a-Service)
      summary: Balances for a customer wallet
      description: >
        Returns balances for every derived address of the customer wallet —
        native coin plus

        supported stablecoins (USDT/USDC where applicable).


        **Served from Rach's database, not a live chain read.** The deposit
        monitor keeps the

        stored figure in step with the chain, raising it on deposits and
        lowering it on spends,

        so this endpoint costs nothing and can be polled as often as your UI
        needs.


        | Query | Behaviour |

        |-------|-----------|

        | *(none)* | Stored balances, returned immediately. |

        | `?refresh=true` | Returns stored balances immediately **and**
        schedules the monitor to re-read these addresses on its next cycle
        (typically ≤30s). Responds with `refresh_requested: true` and
        `refresh_eta_seconds`; poll again after that interval. Concurrent
        refresh requests collapse into one chain read. |

        | `?live=true` | Reads the chain directly, throttled per address. Needed
        only for the confirmed-vs-unconfirmed split on BTC/LTC/BCH, or when
        auditing for drift. |


        Each address object carries `source` (`database` or `chain`) and an
        array of per-currency

        `balances`; every supported currency for the network is present,
        including zeros. Each

        balance carries `as_of` — when that figure was last read from the chain.


        `spendable` is what can actually be sent right now:

        - **XRP:** excludes the locked ~1 XRP base reserve.

        - **BTC / LTC / BCH:** with `?live=true`, `confirmed` counts confirmed
        UTXOs only;
          `balance` may include unconfirmed (0-conf) funds.
        - **All other networks:** `spendable` equals `balance`.
      parameters:
        - in: path
          name: customerID
          required: true
          schema:
            type: string
        - in: query
          name: refresh
          required: false
          schema:
            type: boolean
          description: >-
            Schedule a monitor re-read of these addresses on its next cycle and
            return stored balances immediately. Does NOT block on a chain read.
        - in: query
          name: live
          required: false
          schema:
            type: boolean
          description: >-
            Read the chain directly instead of the stored figure. Throttled per
            address; use only when you need the confirmed/unconfirmed split or
            are auditing for drift.
      responses:
        '200':
          description: Balances per address
          content:
            application/json:
              schema:
                type: object
                properties:
                  customer_id:
                    type: string
                  addresses:
                    type: array
                    items:
                      type: object
                      properties:
                        network:
                          type: string
                          example: ETH
                        address:
                          type: string
                          description: EIP-55 checksummed for EVM chains.
                        index:
                          type: integer
                        source:
                          type: string
                          enum:
                            - database
                            - chain
                          example: database
                          description: >-
                            Where these figures came from. `database` is the
                            normal path; `chain` appears with `?live=true`, or
                            when this address has never been read before.
                        balances:
                          type: array
                          description: >-
                            One entry per supported currency on the network,
                            including zeros.
                          items:
                            type: object
                            properties:
                              currency:
                                example: USDT
                                type: string
                              balance:
                                type: string
                                example: '125.50'
                                description: Total balance in human units.
                              spendable:
                                type: string
                                example: '125.50'
                                description: >-
                                  Amount spendable right now (XRP minus reserve;
                                  UTXO confirmed-only).
                              confirmed:
                                type: string
                                example: '0.04'
                                description: >-
                                  UTXO chains with `?live=true` only —
                                  confirmed-only balance. Omitted otherwise.
                              as_of:
                                type: string
                                format: date-time
                                description: >-
                                  When this figure was last read from the chain.
                                  Omitted on a fresh live read.
                              note:
                                type: string
                                description: >-
                                  Present when balance and spendable differ
                                  (unconfirmed funds, or the XRP reserve).
                  total:
                    type: integer
                  note:
                    type: string
                    description: >-
                      Explains the database-backed behaviour and the
                      refresh/live options.
                  refresh_requested:
                    type: boolean
                    example: true
                    description: >-
                      Present only when `?refresh=true` or `?live=true` was
                      passed.
                  refresh_eta_seconds:
                    type: integer
                    example: 30
                    description: >-
                      Roughly how long until a requested refresh is reflected.
                      Poll again after this interval.
        '404':
          description: Wallet not found
      security:
        - ApiKeyAuth: []
components:
  securitySchemes:
    ApiKeyAuth:
      description: |
        Business API key for server-to-server integrations.
        Key prefix determines the environment — no separate flag needed:
        `test_sk_*` = sandbox/testnet, `live_sk_*` = production/mainnet.
      in: header
      name: X-API-Key
      type: apiKey

````