> ## 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.

# Read TRON USDT balance

> Reads TRC-20 balanceOf directly, including for a zero-TRX unactivated customer address.



## OpenAPI

````yaml /api-reference/caas-openapi.json get /v1/tron/users/balance
openapi: 3.0.0
info:
  contact:
    name: Rach Finance Support
    url: https://rach.finance
  description: >-
    Rach CaaS is the stablecoin infrastructure layer for African fintechs and
    financial institutions. It enables any business to offer their customers
    non-custodial USDC and USDT wallets, instant on-chain transfers, and fiat ↔
    stablecoin conversion in any supported currency (XOF, XAF, NGN, GHS, ...) —
    without building blockchain infrastructure.


    **EVM stablecoins:** USDC and USDT are supported on the configured ERC-4337
    rail. On an EVM value endpoint — `POST /v1/users/fund`, `POST
    /v1/transfers/send`, `POST /v1/users/withdraw` — set the token
    (`target_token` / `token`, or the ticker inside a
    `DIRECT_CRYPTO:{USDC|USDT}:{amount}` quote). `GET /v1/users/balance` returns
    both `balance_usdc` and `balance_usdt`.


    **System-wide phone addressing:** wallets are keyed by phone number and
    belong to the system, not to any one business. Money moves freely across
    businesses — and to phone numbers that have never been provisioned: Rach
    creates the wallet on the fly and notifies the recipient by SMS with USSD
    access instructions.


    **Networks:** EVM settlement profiles are chain-scoped. Polygon PoS (137),
    Base (8453), and BNB Smart Chain (56) may be enabled together only after
    each has its own approved RPC, contracts, sponsor funding, and scan start
    block. External ERC-20 receipts are stored before their `transfer.received`
    webhook and include the rail name. TRON and Solana are parallel native
    rails.


    ## Native TRON USDT

    TRON mainnet is a parallel USDT TRC-20 rail, not an ERC-4337 chain profile.
    Use `/v1/tron/*` to provision a durable `T...` customer address, read its
    USDT contract balance, and submit a sponsored USDT send when the rail is
    ready. A customer may receive USDT and read its balance while holding **zero
    TRX**; Rach creates the account and sponsors Energy/Bandwidth only for an
    enabled transfer-out.


    When `/health/ready` returns `tron: INBOUND_READY`, native TRON read-side
    RPC and reader-account checks have passed, but `POST
    /v1/tron/transfers/send` is deliberately unavailable (503). The API
    readiness check does not certify the separately deployed custody or
    deposit-scanner workers; use a confirmed deposit record or
    `transfer.received` webhook as proof of an observed inbound USDT deposit.
    Only call a sponsored send after readiness reports `tron: READY`. This
    protects customer value while Rach funds or maintains sponsor capacity.


    ## Authentication

    **B2B API endpoints** (`/v1/users/*`, `/v1/transfers/*`, `/v1/fx/*`) use API
    Key authentication. Pass your key in the `X-API-Key` header. Keys are
    prefixed `rach_sk_live_` (mainnet) or `rach_sk_test_` (sandbox — no on-chain
    execution).


    ## Sandbox Mode

    All B2B endpoints honour test-mode API keys (`rach_sk_test_*`). In sandbox
    mode every operation returns an immediate success response
    (`SANDBOX_SIMULATED`) without touching the blockchain or debiting your
    treasury balance. Use sandbox keys for integration testing and CI.


    ## Typical Integration Flow

    1. `POST /v1/users/provision` — create a non-custodial SCW for each end-user
    (offline, no gas)

    2. Collect fiat from customer → deposit to Rach bank account → your CaaS
    dashboard

    3. Rach confirms XOF receipt → your CaaS dashboard (credits your USDC
    balance)

    4. `POST /v1/users/fund` — transfer USDC from your treasury balance to the
    customer SCW on-chain

    5. `GET /v1/users/balance` — read live on-chain USDC balance through the
    active chain RPC

    6. `POST /v1/transfers/send` — instant peer-to-peer USDC transfer between
    customer SCWs (ERC-4337 UserOp)

    7. `POST /v1/users/withdraw` — off-ramp: sweep USDC from SCW back to Rach
    treasury; Rach pays out XOF via mobile money


    ## System-Wide Wallets & Multi-Membership

    A wallet is keyed by phone number and belongs to the **system**, not to any
    one business. Several businesses can operate the same wallet — but only with
    the customer's consent.


    **Provisioning outcomes** (`POST /v1/users/provision`):

    - `PROVISIONED` — new wallet created; you are its first member.

    - `ADOPTED` — the phone had an unaffiliated wallet (created on the fly by an
    inbound transfer); you are now its primary member.

    - `ALREADY_EXISTS` — the wallet exists and you already operate it.

    - `LINK_REQUIRED` — the wallet belongs to another business. You get the same
    address back but **no operating rights**. Start the consent flow to gain
    them.


    **Consent-based linking** (to operate a wallet another business created):

    1. `POST /v1/users/link/request` — a one-time code is SMSed to the customer.

    2. `POST /v1/users/link/confirm` — submit the code the customer gives you;
    you become a member. Existing members receive a `user.linked` webhook.


    **Money-in is open, money-out is gated.** Any business can fund a wallet or
    send money to it (paid from the sender's own ledger). Only a **member** may
    originate transfers, withdraw, or change the phone number for a wallet.


    **Consent-gated phone change** (`POST /v1/users/phone-change/request` →
    `/confirm`): a one-time code is SMSed to the NEW number (proving SIM
    control). The SCW address, balance and history are preserved; every member
    receives a `user.phone_changed` webhook.


    ## Webhook Events

    Signed with HMAC-SHA256 over the body in the `X-Rach-Signature: sha256=...`
    header (key = your webhook secret).

    - `transfer.received` — a wallet you operate received an inbound transfer.

    - `user.linked` — a new business was granted operating rights on a wallet
    you operate.

    - `user.phone_changed` — the phone number of a wallet you operate was
    re-keyed (address unchanged).


    ## Multi-Currency

    Rach moves any fiat; USDC is the settlement rail. Rates are per-currency
    (XOF, XAF, NGN, GHS, ...). See your CaaS dashboard. Topup quotes and
    withdrawals carry a `currency_code` / `payout_currency`.


    ## Solana (USDC & USDT)

    Solana mainnet is a parallel SPL rail, not an ERC-4337 chain profile. Use
    `/v1/solana/*` to derive a durable customer address, read USDC and USDT
    balances, and submit a sponsored send.


    Sponsorship is native here: every Solana transaction names a fee payer, and
    Rach is named as that payer. The customer signs only as token authority and
    needs **zero SOL** — there is no paymaster contract and no resource lease.
    If a recipient has never held the mint, Rach also pays the one-off rent to
    open their token account; that cost is not recoverable, so it is reported
    per transfer as `created_recipient_ata`.


    When `/health/ready` returns `solana: INBOUND_READY`, provisioning, balance
    reads, deposit scanning and `transfer.received` webhooks are live, but `POST
    /v1/solana/transfers/send` is deliberately unavailable (503). Only call a
    sponsored send after readiness reports `solana: READY`.


    ## EVM Fees & Merchant Pricing

    An ERC-4337 peer-to-peer transfer costs **0.30% of the amount, capped at
    1.20**. That is Rach's margin, deducted from the amount sent: the sender is
    debited exactly what they asked to send, and the recipient receives the
    remainder.


    **You can charge your own fee alongside Rach's and keep it.** Price it the
    same way Rach does, at your CaaS dashboard, along with an EVM address you
    control: either `mode: "PERCENTAGE"` — a rate in `fee_bps` bounded by
    `fee_cap_micros` (0 for uncapped) — or `mode: "FLAT"`, one fixed
    `fee_flat_micros` per transfer. The two are alternatives and never combine.


    Your fee is deducted from the amount sent and moves directly from the sender
    to your address in the same atomic on-chain batch as the transfer — Rach
    never takes custody of it, so there is no payout to request and no balance
    to reconcile. On a transfer too small to carry both fees your fee is waived
    rather than the recipient receiving nothing. Read what you have earned at
    your CaaS dashboard.


    Your percentage is capped at 1000 basis points (10%). That ceiling is a typo
    guard, not a pricing policy: a slipped digit in basis points is charged to
    your own customers at full value on every transfer until someone notices.


    Native TRON USDT sponsorship covers the customer's network costs
    (activation, Energy, and Bandwidth) when sends are enabled. It does **not**
    reuse an EVM merchant-fee address or deduct an undisclosed TRON business
    fee; native fee collection remains disabled until Rach configures an
    explicit TRON collection policy.


    ## Status Lifecycles

    Every money-moving call returns `202 Accepted` and settles asynchronously.
    Only two states are terminal — `SETTLED`/`COMPLETED`/`REFUNDED` and
    `FAILED`. Treat everything else as still in progress.


    **Deposit / funding:** `QUEUED` → `SUBMITTING` → `SUBMITTED` → `SETTLED`

    **Transfer:** `QUEUED` → `SUBMITTING` → `SUBMITTED` → `SETTLED`

    **Swap:** `QUEUED` → `SUBMITTING` → `SUBMITTED` → `SETTLED`

    **Withdrawal:** `PENDING` → `SUBMITTING` → `SUBMITTED` → `CRYPTO_RECEIVED` →
    `PAYOUT_SUBMITTING` → `COMPLETED`


    Any of them can end in `FAILED`, which carries an `error_reason`. A failed
    funding or transfer returns the value to your ledger.


    **Never retry on `SUBMISSION_UNKNOWN` or `PAYOUT_UNKNOWN`.** They mean Rach
    could not confirm whether an operation reached the network or the payout
    provider, so it may already have happened. Rach reconciles them
    automatically. Retrying with a *new* idempotency key risks paying twice;
    retrying with the *same* key is always safe.


    On a withdrawal, `CRYPTO_RECEIVED` means the crypto leg is done but the cash
    has not landed. `COMPLETED` requires recorded evidence that the payout
    reached the recipient. `REFUNDED` means the payout could not be delivered
    and the stablecoin went back to the customer wallet — distinct from
    `FAILED`, where nothing ever left it.
  title: Rach CaaS — Crypto-as-a-Service API
  version: 1.0.1
servers:
  - url: https://api.rach.finance/caas/api
security: []
paths:
  /v1/tron/users/balance:
    get:
      tags:
        - B2B - TRON USDT
      summary: Read TRON USDT balance
      description: >-
        Reads TRC-20 balanceOf directly, including for a zero-TRX unactivated
        customer address.
      parameters:
        - description: E.164 customer phone number
          in: query
          name: phone_number
          required: true
          schema:
            type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/cmd_api.TronBalanceResponse'
          description: OK
        '400':
          content:
            application/json:
              schema:
                additionalProperties: true
                type: object
          description: Invalid E.164 phone number
        '403':
          content:
            application/json:
              schema:
                additionalProperties: true
                type: object
          description: Wallet is not linked to this tenant
        '404':
          content:
            application/json:
              schema:
                additionalProperties: true
                type: object
          description: >-
            Customer or TRON wallet not found; route is also absent while the
            rail is disabled
        '503':
          content:
            application/json:
              schema:
                additionalProperties: true
                type: object
          description: TRC-20 balance read unavailable
      security:
        - ApiKeyAuth: []
components:
  schemas:
    cmd_api.TronBalanceResponse:
      properties:
        account_status:
          type: string
        balance_source:
          type: string
        balance_usdt:
          type: string
        blind_index:
          type: string
        customer_needs_trx:
          type: boolean
        network:
          type: string
        token:
          type: string
        wallet_address:
          type: string
      type: object
  securitySchemes:
    ApiKeyAuth:
      description: >-
        Your Rach B2B API key. Use `rach_sk_live_*` for production (on-chain) or
        `rach_sk_test_*` for sandbox (no-chain simulation).
      in: header
      name: X-API-Key
      type: apiKey

````