---
url: /docs/fiat/quickstart-payout.md
description: >-
  Pay USD out to a bank account from a BlindPay-managed wallet on a development
  instance, using only the REST API.
---

This quickstart walks through a payout: funds leave a BlindPay-managed wallet and USD lands in a recipient's bank account. You will accept the terms of service, create a customer, create and fund a managed wallet, add a bank account, quote the payout, and execute it. Because BlindPay custodies the funding wallet, there is no on-chain signing or token approval; every step is a REST call. On a development instance the payout completes automatically a few seconds after you execute it.

## Before you begin

You need a BlindPay account and an API key for a development instance. See [Instances](/learn/instances) and [API keys](/learn/api-keys).

### Accept terms of service

Every instance requires a terms of service acceptance before you can create customers. For testing, you can accept on behalf of the customer; in production, your customer should accept the terms themselves.

```bash [cURL]
curl --request POST \
  --url https://api.blindpay.com/v1/e/instances/in_000000000000/tos \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "idempotency_key": "<your_uuid>"
  }'
```

Open the URL from the response in your browser, accept the terms, and copy the `tos_id` shown on the confirmation screen. You will pass this `tos_id` when you create the customer in the next step.

### Create a customer

Every payout requires a customer that has completed KYC. This example creates an individual customer with standard KYC.

```bash [cURL]
curl --request POST \
  --url https://api.blindpay.com/v1/instances/in_000000000000/customers \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "tos_id": "to_000000000000",
    "type": "individual",
    "kyc_type": "standard",
    "email": "email@example.com",
    "tax_id": "12345678",
    "address_line_1": "8 The Green",
    "address_line_2": "#12345",
    "city": "Dover",
    "state_province_region": "DE",
    "country": "US",
    "postal_code": "02050",
    "ip_address": "127.0.0.1",
    "phone_number": "+13022006100",
    "proof_of_address_doc_type": "UTILITY_BILL",
    "proof_of_address_doc_file": "https://example.com/proof-of-address.jpg",
    "first_name": "John",
    "last_name": "Doe",
    "date_of_birth": "1998-01-01T00:00:00Z",
    "id_doc_country": "US",
    "id_doc_type": "PASSPORT",
    "id_doc_front_file": "https://example.com/passport-front.jpg",
    "selfie_file": "https://example.com/selfie.jpg"
  }'
```

Save the `id` from the response: this is your customer ID (`re_...`).

On development instances, KYC is approved automatically. In production, automated review for standard KYC takes about 60 seconds.

### Create a managed wallet

Every payout needs a funding source, the wallet the settlement stablecoins are pulled from. A [managed wallet](/fiat/wallets) is the simplest one: BlindPay generates the address and holds the keys, so executing the payout later needs no approval or signature. This example creates it on Solana Devnet, the development network with a REST endpoint for minting test funds.

```bash [cURL]
curl --request POST \
  --url https://api.blindpay.com/v1/instances/in_000000000000/customers/re_000000000000/wallets \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "network": "solana_devnet",
    "name": "Quickstart Wallet"
  }'
```

Save the `id` (`bl_...`) and the `address` from the response. You need the address for the next step and for executing the payout.

### Fund the wallet with USDB

Mint USDB, BlindPay's development-only test stablecoin, straight into the managed wallet. Pass the wallet's `address` and the amount of USDB to mint:

```bash [cURL]
curl --request POST \
  --url https://api.blindpay.com/v1/instances/in_000000000000/mint-usdb-solana \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "address": "YOUR_WALLET_ADDRESS",
    "amount": "100"
  }'
```

The response returns `success: true` with the on-chain signature. The wallet now holds 100 USDB to pay out from.

### Add a bank account

This is the payout destination, the bank account that receives the USD. This example adds a US ACH account. Use real, valid bank details, even on development.

```bash [cURL]
curl --request POST \
  --url https://api.blindpay.com/v1/instances/in_000000000000/customers/re_000000000000/bank-accounts \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "type": "ach",
    "name": "Display Name",
    "beneficiary_name": "<Replace this>",
    "routing_number": "<Replace this>",
    "account_number": "<Replace this>",
    "account_type": "checking",
    "account_class": "individual"
  }'
```

Save the bank account ID (`ba_...`).

### Create a payout quote

A quote locks the conversion rate and fees for 5 minutes. The `network` and `token` describe the funding wallet: `solana_devnet` and `USDB` for the wallet you just funded.

```bash [cURL]
curl --request POST \
  --url https://api.blindpay.com/v1/instances/in_000000000000/quotes \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "bank_account_id": "ba_000000000000",
    "currency_type": "sender",
    "cover_fees": false,
    "request_amount": 5000,
    "network": "solana_devnet",
    "token": "USDB"
  }'
```

`request_amount` is an integer in minor units, so `5000` here means $50.00. `cover_fees: false` means the fee is deducted from what the bank account receives, the common case. Save the quote ID (`qu_...`).

### Execute the payout

Execute the payout by passing the quote ID and the managed wallet's address as the funding source. Because BlindPay custodies the wallet, there is no approve or delegation step; this single call moves the funds.

```bash [cURL]
curl --request POST \
  --url https://api.blindpay.com/v1/instances/in_000000000000/payouts/evm \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "quote_id": "qu_000000000000",
    "sender_wallet_address": "YOUR_WALLET_ADDRESS"
  }'
```

The response returns the payout with `status: "processing"`.

The endpoint is `/payouts/evm` regardless of the funding network; it handles managed wallets on every supported chain.

## What happens next

On a development instance, the payout completes automatically a few seconds after you execute it. Check for the `payout.complete` webhook to confirm. In production, settlement timing depends on the payout rail; see [cut-off times](/kb/cut-off-times).

Done. To send another payment, create a new payout quote and execute it again; each quote is single-use.

## Related

* [Pay out to bank](/fiat/send): full reference for every payout rail, including Pix, SPEI, and SWIFT
* [Bank transfer to stablecoins](/fiat/quickstart-payin): the payin counterpart of this guide
* [Managed wallet](/fiat/wallets): the funding wallet entity used in this quickstart
* [Webhooks](/learn/webhooks): handle `payout.complete` and other events in real time
