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

# Get FX Conversion Quote

> Returns a locked exchange rate for converting local fiat (XOF, NGN, KES, etc.) to USDC. The returned quote_id must be passed to POST /v1/transfers/send for fiat-denominated transfers. Quotes expire in 60 seconds — check expires_at before use. For direct crypto-to-crypto transfers without FX conversion use the DIRECT_CRYPTO:{TOKEN}:{AMOUNT} quote_id format instead.



## OpenAPI

````yaml /api-reference/caas-openapi.json post /v1/fx/quote
openapi: 3.0.0
info:
  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.


    **Stablecoins:** USDC and USDT are supported equally everywhere. On any
    endpoint that moves value — `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.


    **Network:** Polygon PoS (Chain ID 137). All smart contract wallets,
    transfers, and withdrawals settle on Polygon mainnet. Test environments use
    Sepolia (Chain ID 11155111).


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


    **Dashboard endpoints** (`/v1/dashboard/*`) use JWT Bearer authentication.
    Your JWT must include `business_id` and the `waas` permission scope.


    ## 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 → `POST
    /v1/dashboard/treasury/topup`

    3. Rach confirms XOF receipt → `POST
    /v1/dashboard/treasury/topup/{id}/confirm` (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 via Polygon 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 `GET /v1/dashboard/rates`. Topup quotes and
    withdrawals carry a `currency_code` / `payout_currency`.


    ## Status Lifecycles

    **Deposit:** `QUEUED` → `SETTLED`

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

    **Withdrawal:** `PENDING` → `SUBMITTED` → `CRYPTO_RECEIVED` → `COMPLETED`
  title: Rach CaaS — Crypto-as-a-Service API
  contact:
    name: Rach Finance Support
    url: https://rach.finance
  version: 1.0.1
servers:
  - url: https://api.rach.finance/caas/api
security: []
paths:
  /v1/fx/quote:
    post:
      tags:
        - B2B - FX
      summary: Get FX Conversion Quote
      description: >-
        Returns a locked exchange rate for converting local fiat (XOF, NGN, KES,
        etc.) to USDC. The returned quote_id must be passed to POST
        /v1/transfers/send for fiat-denominated transfers. Quotes expire in 60
        seconds — check expires_at before use. For direct crypto-to-crypto
        transfers without FX conversion use the DIRECT_CRYPTO:{TOKEN}:{AMOUNT}
        quote_id format instead.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/cmd_api.QuoteRequest'
        description: Quote request
        required: true
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/cmd_api.QuoteResponse'
        '400':
          description: Invalid currency or missing fields
          content:
            application/json:
              schema:
                type: object
                additionalProperties: true
        '401':
          description: Invalid or missing API key
          content:
            application/json:
              schema:
                type: object
                additionalProperties: true
        '500':
          description: FX engine error or unsupported trading pair
          content:
            application/json:
              schema:
                type: object
                additionalProperties: true
      security:
        - ApiKeyAuth: []
components:
  schemas:
    cmd_api.QuoteRequest:
      type: object
      required:
        - fiat_amount
        - local_currency
      properties:
        fiat_amount:
          type: number
          example: 20000
        local_currency:
          type: string
          example: XOF
        target_token:
          type: string
          example: USDC
    cmd_api.QuoteResponse:
      type: object
      properties:
        currency_pair:
          type: string
          example: XOF_USDC
        expected_out:
          type: string
          example: '35.67'
        expires_at:
          type: string
          example: '2026-06-24T21:25:25Z'
        fiat_amount:
          type: string
          example: '20000.00'
        quote_id:
          type: string
          example: fx_b3d8a1c2-...
        rate:
          type: string
          example: '560.77'
        target_token:
          type: string
          example: USDC
  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).
      type: apiKey
      name: X-API-Key
      in: header

````