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

# Withdraw Funds

> Initiates a withdrawal from your wallet to a beneficiary. Either `beneficiaryId` or `inlineBeneficiary` must be provided. For USD international_wire, send as multipart/form-data and attach reference documents under the `documents` field.

Initiate a withdrawal from your wallet to a beneficiary. You can reference a saved beneficiary by ID or provide inline beneficiary details for a one-time transfer.

Either `beneficiaryId` or `inlineBeneficiary` must be provided. The required fields inside `inlineBeneficiary` depend on the currency and `withdrawal_method`.

<Info>
  **Paying out for a specific merchant (tenant keys):** if your API key is a white-label tenant key managing multiple merchants, add the [`X-Account-Id`](/api-reference/introduction#acting-on-a-tenant-account-x-account-id) header set to the merchant's account ID — the payout is then deducted from **that merchant's wallet**. Without it, the withdrawal runs against your own (parent) account. The account ID is the `id` returned by `POST /accounts` (or from `GET /accounts`).
</Info>

<Info>
  For **USD**, the top-level **`amount`** is **US cents** — e.g. **100** cents = **\$1.00** USD transferred (consistent with ledger `*_amount` fields returned on transactions).
</Info>

## Top-level Parameters

| Parameter               | Type          | Required | Description                                                                            |
| ----------------------- | ------------- | -------- | -------------------------------------------------------------------------------------- |
| `amount`                | number        | Yes      | Amount in the smallest unit (kobo for NGN, cents for USD — **100 cents = \$1.00 USD**) |
| `currency`              | string        | Yes      | 3-letter currency code — `NGN`, `USD`, or `XAF`                                        |
| `description`           | string        | No       | Narration for the transaction                                                          |
| `externalReference`     | string        | No       | Your own unique reference for this transaction                                         |
| `beneficiaryId`         | string (UUID) | No\*     | ID of a saved beneficiary                                                              |
| `inlineBeneficiary`     | object        | No\*     | One-time beneficiary details (see per-currency fields below)                           |
| `saveBeneficiary`       | boolean       | No       | Save the inline beneficiary for future use                                             |
| `deductFeesFromBalance` | boolean       | No       | If `true`, fees are deducted from your wallet; beneficiary receives the exact amount   |

\* One of `beneficiaryId` or `inlineBeneficiary` is required.

***

## `inlineBeneficiary` — Required Fields by Currency

### NGN

| Field            | Required                            |
| ---------------- | ----------------------------------- |
| `account_number` | Yes                                 |
| `bank_name`      | Yes                                 |
| `bank_code`      | Yes                                 |
| `account_name`   | No (auto-resolved from bank lookup) |

```bash theme={null}
curl -X POST "https://api.rolla.xyz/api/v1/external/wallet/withdraw" \
  -H "X-API-Key: your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 5000,
    "currency": "NGN",
    "description": "Vendor payment",
    "inlineBeneficiary": {
      "account_number": "0123456789",
      "bank_name": "Access Bank",
      "bank_code": "000014"
    },
    "saveBeneficiary": true
  }'
```

***

### Choosing a USD rail

USD payouts run on one of three bank rails, selected with `withdrawal_method`. The choice drives settlement speed, the fields you must supply, and the fee — so pass it explicitly on both the quote and the withdrawal.

| `withdrawal_method`  | Use for                     | Addressed by           | Notes                                                       |
| -------------------- | --------------------------- | ---------------------- | ----------------------------------------------------------- |
| `ach`                | Domestic US, cost-sensitive | `routing_number` (ABA) | Settles in business days. Cheapest US rail.                 |
| `domestic_wire`      | Domestic US, time-sensitive | `routing_number` (ABA) | Same-day settlement, priced above ACH.                      |
| `international_wire` | Outside the US              | `swift_code`           | Requires supporting documents — `multipart/form-data` only. |

<Tip>
  Fees are configured per rail, so `ach` and `domestic_wire` to the same bank generally cost different amounts. Send `withdrawal_method` (or `beneficiaryId`) to [`POST /wallet/fee`](/api-reference/endpoint/wallet/fee) to quote the exact fee this withdrawal will be charged.
</Tip>

***

### USD — ACH

| Field                 | Required                                                                                                  |
| --------------------- | --------------------------------------------------------------------------------------------------------- |
| `withdrawal_method`   | Yes — `"ach"`                                                                                             |
| `account_name`        | Yes                                                                                                       |
| `bank_name`           | Yes                                                                                                       |
| `account_number`      | Yes                                                                                                       |
| `routing_number`      | Yes — 9-digit ABA number                                                                                  |
| `beneficiary_address` | Yes — `{ street, city, state, postalCode, country }`                                                      |
| `bank_address`        | Yes — `{ street, city, state, postalCode, country }`                                                      |
| `account_category`    | No — `"checking"` or `"savings"`. Recommended; carried onto the saved record when `saveBeneficiary: true` |

```bash theme={null}
curl -X POST "https://api.rolla.xyz/api/v1/external/wallet/withdraw" \
  -H "X-API-Key: your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 1000,
    "currency": "USD",
    "description": "Payroll run",
    "inlineBeneficiary": {
      "withdrawal_method": "ach",
      "account_name": "Jane Smith",
      "bank_name": "Chase Bank",
      "account_number": "123456789",
      "routing_number": "021000021",
      "account_category": "checking",
      "beneficiary_address": { "street": "123 Main St", "city": "New York", "state": "NY", "postalCode": "10001", "country": "US" },
      "bank_address": { "street": "270 Park Ave", "city": "New York", "state": "NY", "postalCode": "10017", "country": "US" }
    }
  }'
```

<Info>
  Unlike `international_wire`, ACH needs no supporting documents — send it as a normal JSON body.
</Info>

<Warning>
  `routing_number` is required for `ach` and `domestic_wire`. Omitting it returns a `400` with `"routing_number is required for ACH and domestic wire withdrawals"`.

  This is newly **enforced**. It has always been documented as required for `domestic_wire`, but the server previously accepted domestic wire requests without it and the payout then stranded. If you have been omitting it, those requests now fail fast instead.
</Warning>

***

### USD — Domestic Wire

| Field                 | Required                                             |
| --------------------- | ---------------------------------------------------- |
| `withdrawal_method`   | Yes — `"domestic_wire"`                              |
| `account_name`        | Yes                                                  |
| `bank_name`           | Yes                                                  |
| `account_number`      | Yes                                                  |
| `routing_number`      | Yes                                                  |
| `beneficiary_address` | Yes — `{ street, city, state, postalCode, country }` |
| `bank_address`        | Yes — `{ street, city, state, postalCode, country }` |

```bash theme={null}
curl -X POST "https://api.rolla.xyz/api/v1/external/wallet/withdraw" \
  -H "X-API-Key: your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 1000,
    "currency": "USD",
    "inlineBeneficiary": {
      "withdrawal_method": "domestic_wire",
      "account_name": "Jane Smith",
      "bank_name": "Chase Bank",
      "account_number": "123456789",
      "routing_number": "021000021",
      "beneficiary_address": { "street": "123 Main St", "city": "New York", "state": "NY", "postalCode": "10001", "country": "US" },
      "bank_address": { "street": "270 Park Ave", "city": "New York", "state": "NY", "postalCode": "10017", "country": "US" }
    }
  }'
```

***

### USD — International Wire

| Field                              | Required                                             |
| ---------------------------------- | ---------------------------------------------------- |
| `withdrawal_method`                | Yes — `"international_wire"`                         |
| `account_name`                     | Yes                                                  |
| `bank_name`                        | Yes                                                  |
| `account_number`                   | Yes                                                  |
| `swift_code`                       | Yes                                                  |
| `beneficiary_address`              | Yes — `{ street, city, state, postalCode, country }` |
| `bank_address`                     | Yes — `{ street, city, state, postalCode, country }` |
| `intermediary_bank_name`           | No                                                   |
| `intermediary_bank_routing_number` | No                                                   |

<Warning>
  USD international wire requires reference documents/invoices to be attached, so this is the one withdrawal type that must be sent as `multipart/form-data` (every other currency/method uses a JSON body). Include one or more files under the `documents` field.
</Warning>

<Warning>
  Send `inlineBeneficiary` as a **single JSON-stringified field** — one form field named `inlineBeneficiary` whose value is the full JSON object. Do **not** spread it across bracketed fields like `inlineBeneficiary[account_name]=…`; multipart form fields are not reconstructed into a nested object, so the request will fail with `400 "Either beneficiaryId or inlineBeneficiary must be provided"`.
</Warning>

```bash theme={null}
curl -X POST "https://api.rolla.xyz/api/v1/external/wallet/withdraw" \
  -H "X-API-Key: your_api_key_here" \
  -F "amount=1000" \
  -F "currency=USD" \
  -F 'inlineBeneficiary={
        "withdrawal_method": "international_wire",
        "account_name": "Jane Smith",
        "bank_name": "Barclays Bank",
        "account_number": "12345678",
        "swift_code": "BARCGB22",
        "beneficiary_address": { "street": "123 Main Street", "city": "New York", "state": "NY", "postalCode": "10001", "country": "US" },
        "bank_address": { "street": "456 Bank Avenue", "city": "New York", "state": "NY", "postalCode": "10001", "country": "US" }
      }' \
  -F "documents=@/path/to/invoice.pdf"
```

***

### USD — Crypto (USDT / USDC)

Crypto withdrawals are sent from your **USD wallet**. Set `withdrawal_method` to `"crypto_usdt"` or `"crypto_usdc"` to send the USD value as a stablecoin to a crypto wallet address.

| Field               | Required                                 |
| ------------------- | ---------------------------------------- |
| `withdrawal_method` | Yes — `"crypto_usdt"` or `"crypto_usdc"` |
| `account_name`      | Yes — used as a display nickname         |
| `wallet_address`    | Yes — 26–64 alphanumeric characters      |
| `wallet_chain`      | Yes — e.g. `"ethereum"`, `"tron"`        |

```bash theme={null}
curl -X POST "https://api.rolla.xyz/api/v1/external/wallet/withdraw" \
  -H "X-API-Key: your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 100,
    "currency": "USD",
    "inlineBeneficiary": {
      "withdrawal_method": "crypto_usdt",
      "account_name": "My USDT Wallet",
      "wallet_address": "TXyZ1234abcd5678efgh9012ijkl3456mnop",
      "wallet_chain": "tron"
    }
  }'
```

***

### XAF

| Field            | Required                                 |
| ---------------- | ---------------------------------------- |
| `account_name`   | Yes                                      |
| `bank_name`      | Yes                                      |
| `account_number` | Yes                                      |
| `swift_code`     | Yes                                      |
| `bank_address`   | Yes — `{ street, city, state, country }` |

***

## Example Response

```json theme={null}
{
  "status": 200,
  "success": true,
  "message": "Withdrawal initiated successfully",
  "data": {
    "transaction": {
      "id": "866b7abd-6cac-40f2-a04f-d6e58bf47d04",
      "transaction_type": "withdrawal",
      "status": "pending",
      "description": "Vendor payment",
      "external_reference": "NG-NFNUJTUW",
      "fee_amount": 25,
      "source_amount": 5000,
      "destination_amount": 4975,
      "source_currency": "NGN",
      "destination_currency": "NGN",
      "created_at": "2026-03-23T13:45:28.138Z",
      "updated_at": "2026-03-23T13:45:28.263Z",
      "beneficiary": {
        "bank_name": "Access Bank",
        "bank_code": "000014",
        "account_name": "John Doe",
        "account_number": "0123456789"
      }
    }
  }
}
```

<Info>
  Use `beneficiaryId` to pay a saved beneficiary. Use `inlineBeneficiary` for one-time transfers. Set `saveBeneficiary: true` to save the inline beneficiary automatically for reuse.
</Info>

<Warning>
  **Fees**: By default, fees are deducted from the withdrawal amount (beneficiary receives less). Set `deductFeesFromBalance: true` so fees come out of your wallet balance and the beneficiary receives the exact amount specified.
</Warning>


## OpenAPI

````yaml POST /wallet/withdraw
openapi: 3.1.0
info:
  title: Rolla Developer API
  description: >-
    API for programmatic transaction management on the Rolla platform. Monetary
    `amount` fields use the smallest unit of the referenced currency unless an
    endpoint says otherwise (e.g. NGN = kobo, USD = cents, where **100 cents =
    USD 1.00**).
  version: 1.0.0
servers:
  - url: https://api.rolla.xyz/api/v1/external
    description: Production server
security:
  - apiKeyAuth: []
paths:
  /wallet/withdraw:
    post:
      summary: Withdraw Funds
      description: >-
        Initiates a withdrawal from your wallet to a beneficiary. Either
        `beneficiaryId` or `inlineBeneficiary` must be provided. For USD
        international_wire, send as multipart/form-data and attach reference
        documents under the `documents` field.
      operationId: withdraw
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WithdrawalRequest'
          multipart/form-data:
            schema:
              type: object
              description: >-
                Required for USD `international_wire` (reference documents must
                be attached). Send `inlineBeneficiary` as a single
                JSON-stringified field — not as bracketed sub-fields.
              required:
                - amount
                - currency
              properties:
                amount:
                  type: integer
                  description: >-
                    Amount in the smallest currency unit (cents for USD — 100 =
                    $1.00).
                  example: 1000
                currency:
                  type: string
                  example: USD
                inlineBeneficiary:
                  type: string
                  description: >-
                    The full beneficiary object, JSON-stringified into one
                    field. Multipart fields are not reconstructed into a nested
                    object, so bracket notation
                    (`inlineBeneficiary[account_name]=…`) will fail with 400.
                    Either this or `beneficiaryId` is required.
                  example: >-
                    {"withdrawal_method":"international_wire","account_name":"Jane
                    Smith","bank_name":"Barclays
                    Bank","account_number":"12345678","swift_code":"BARCGB22","beneficiary_address":{"street":"123
                    Main Street","city":"New
                    York","state":"NY","postalCode":"10001","country":"US"},"bank_address":{"street":"456
                    Bank Avenue","city":"New
                    York","state":"NY","postalCode":"10001","country":"US"}}
                beneficiaryId:
                  type: string
                  format: uuid
                  description: >-
                    ID of a saved beneficiary. Either this or
                    `inlineBeneficiary` is required.
                externalReference:
                  type: string
                  description: Your own reference for this transaction.
                description:
                  type: string
                saveBeneficiary:
                  type: boolean
                deductFeesFromBalance:
                  type: boolean
                  description: >-
                    If true, fees come out of your wallet balance and the
                    beneficiary receives the exact amount.
                documents:
                  type: array
                  description: >-
                    One or more reference documents/invoices. Required for USD
                    international_wire. Max 50MB per file.
                  items:
                    type: string
                    format: binary
      responses:
        '200':
          description: Withdrawal initiated successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: number
                    example: 200
                  success:
                    type: boolean
                    example: true
                  message:
                    type: string
                    example: Withdrawal initiated successfully
                  transaction:
                    type: object
                    properties:
                      id:
                        type: string
                        format: uuid
                      transaction_type:
                        type: string
                        example: withdrawal
                      status:
                        type: string
                        example: pending
                      description:
                        type: string
                      external_reference:
                        type: string
                      fee_amount:
                        type: number
                        example: 25
                      source_amount:
                        type: number
                        example: 5000
                      destination_amount:
                        type: number
                        example: 4975
                      source_currency:
                        type: string
                        example: NGN
                      destination_currency:
                        type: string
                        example: NGN
                      created_at:
                        type: string
                        format: date-time
                      updated_at:
                        type: string
                        format: date-time
                      beneficiary:
                        type: object
                        properties:
                          bank_name:
                            type: string
                          bank_code:
                            type: string
                          account_name:
                            type: string
                          account_number:
                            type: string
        '400':
          description: Bad request - Invalid input or insufficient balance
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unauthorized - Invalid or missing API key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  schemas:
    WithdrawalRequest:
      type: object
      required:
        - amount
        - currency
      description: Either `beneficiaryId` or `inlineBeneficiary` must be provided.
      properties:
        amount:
          type: number
          description: >-
            Amount in smallest units (kobo for NGN; US cents for USD — 100 = 1
            USD).
          example: 5000
        currency:
          type: string
          description: 3-letter currency code
          minLength: 3
          maxLength: 3
          example: NGN
        description:
          type: string
          description: Narration for the transaction
          maxLength: 500
        externalReference:
          type: string
          description: Your own unique reference for this transaction
          maxLength: 255
        beneficiaryId:
          type: string
          format: uuid
          description: ID of a saved beneficiary. Use this OR inlineBeneficiary.
        inlineBeneficiary:
          $ref: '#/components/schemas/InlineBeneficiary'
          description: One-time beneficiary details (use instead of beneficiaryId)
        saveBeneficiary:
          type: boolean
          description: Save the inline beneficiary for future use
          default: false
        deductFeesFromBalance:
          type: boolean
          description: >-
            If true, fees are taken from your wallet balance so the beneficiary
            receives the exact amount
          default: false
    Error:
      type: object
      properties:
        success:
          type: boolean
          example: false
        message:
          type: string
    InlineBeneficiary:
      type: object
      description: >-
        One-time beneficiary details (use instead of beneficiaryId). Required
        fields depend on currency and withdrawal_method — see the endpoint docs
        for per-currency examples.
      properties:
        withdrawal_method:
          type: string
          description: >-
            Required for USD, GBP, EUR, and crypto. NGN defaults to local
            transfer.
          enum:
            - local_transfer
            - domestic_wire
            - international_wire
            - ach
            - crypto_usdt
            - crypto_usdc
            - rolla_transfer
        account_name:
          type: string
          description: >-
            Account holder name. Required for all currencies except EUR SEPA.
            For crypto, used as a display nickname.
          example: John Doe
        account_number:
          type: string
          description: >-
            Required for NGN, USD, GBP local (8 digits), GBP international, EUR
            international. Not required for EUR SEPA or crypto.
          example: '0123456789'
        bank_name:
          type: string
          description: Required for NGN, USD, GBP. Not required for EUR SEPA or crypto.
          example: Access Bank
        bank_code:
          type: string
          description: Required for NGN (e.g. '000014' for Access Bank).
          example: '000014'
        routing_number:
          type: string
          description: 9-digit ABA routing number. Required for USD ach and domestic_wire.
        swift_code:
          type: string
          description: >-
            Required for USD international_wire, GBP international_wire, EUR
            international_wire, and other currencies.
        sort_code:
          type: string
          description: Required for GBP local_transfer. Must be exactly 6 digits.
          example: '400515'
        iban:
          type: string
          description: Required for EUR local_transfer (SEPA).
          example: DE89370400440532013000
        bic:
          type: string
          description: Required for EUR local_transfer (SEPA).
          example: COBADEFFXXX
        bank_address:
          type: object
          description: >-
            Required for USD, GBP (international), EUR (international), and
            XAF/other currencies.
          properties:
            street:
              type: string
              example: 456 Bank Avenue
            city:
              type: string
              example: New York
            state:
              type: string
              example: NY
            postalCode:
              type: string
              example: '10001'
            country:
              type: string
              example: US
        beneficiary_address:
          type: object
          description: >-
            Required for USD and GBP. Street, city, state, postalCode, and
            country.
          properties:
            street:
              type: string
              example: 123 Main Street
            city:
              type: string
              example: New York
            state:
              type: string
              example: NY
            postalCode:
              type: string
              example: '10001'
            country:
              type: string
              example: US
        wallet_address:
          type: string
          description: >-
            Required for crypto_usdt and crypto_usdc. Must be 26–64 alphanumeric
            characters. Use with currency: USD.
          example: TXyZ1234abcd5678efgh9012ijkl3456mnop
        wallet_chain:
          type: string
          description: >-
            Required for crypto_usdt and crypto_usdc. The blockchain network
            (e.g. 'ethereum', 'tron'). Use with currency: USD.
          example: tron
        intermediary_bank_name:
          type: string
          description: Optional. Intermediary bank for USD international_wire.
        intermediary_bank_routing_number:
          type: string
          description: >-
            Optional. Intermediary bank routing number for USD
            international_wire.
        email:
          type: string
          format: email
          description: Optional. Beneficiary email address.
        contact_person:
          type: string
          description: Optional. Contact person at the beneficiary.
  securitySchemes:
    apiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
      description: Your Rolla API key

````