---
url: /docs/stablecoin/quickstart-payout.md
description: >-
  Send your first stablecoin off-ramp payout from a BlindPay-managed wallet,
  using only the REST API.
---

This quickstart walks through an off-ramp payout: pulling USDB from a managed wallet and delivering USD to a bank account. You will accept the terms of service, create a customer, create and fund a managed wallet, add a bank account, create a payout quote, and execute the payout. Every step is a REST call, no on-chain signing involved.

If you want to fund the payout from a self-custodied wallet instead (with the on-chain authorization that entails), follow the [Payout with EVM](/stablecoin/payout-evm), [Stellar](/stablecoin/payout-stellar), or [Solana](/stablecoin/payout-solana) tutorials after this one.

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

## Steps

### Accept terms of service

For testing you can accept the terms of service yourself. In production, your customer should be the one accepting them.

```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 returned URL in your browser, accept the terms, and copy the `tos_id` shown on the confirmation screen. You will need it to create the customer.

### Create a customer

Every payout requires a customer that has completed KYC. On development instances, customers are auto-approved.

```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": "+1234567890",
    "proof_of_address_doc_type": "UTILITY_BILL",
    "proof_of_address_doc_file": "https://pub-4fabf5dd55154f19a0384b16f2b816d9.r2.dev/v4-460px-Get-Proof-of-Address-Step-3-Version-2.jpg.jpeg",
    "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://pub-4fabf5dd55154f19a0384b16f2b816d9.r2.dev/1000_F_365165797_VwQbNaD4yjWwQ6y1ENKh1xS0TXauOQvj.jpg",
    "selfie_file": "https://pub-4fabf5dd55154f19a0384b16f2b816d9.r2.dev/selfie.png"
  }'
```

This is the full standard KYC payload (`kyc_type: "standard"`): identity document, selfie, and proof of address. Save the customer ID (`re_...`) from the response.

### Create a managed wallet

The payout needs a funding source, the wallet the stablecoins are pulled from. A [managed wallet](/stablecoin/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. See [Mint USDB](/stablecoin/mint-usdb) for minting on other networks.

### Add a bank account

This is the fiat destination for the payout, the bank account that receives the USD once the stablecoin is converted. 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, `5000` is $50.00. `cover_fees: false` means the customer's stablecoin amount absorbs the fee, 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` call, signature, or delegation; 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"`. On a development instance, the payout completes automatically a few seconds after creation, no manual settlement step needed. You will receive a `payout.complete` webhook once it does.

Congratulations! You've completed your first off-ramp payout with BlindPay. To send another, create a new quote and execute again, each quote is single-use.

## Next steps

This quickstart used a managed wallet, so no on-chain authorization was needed. To pull funds from a self-custodied wallet instead, follow the per-network tutorials: [EVM](/stablecoin/payout-evm) (ERC-20 approve), [Stellar](/stablecoin/payout-stellar) (authorize + signed XDR), or [Solana](/stablecoin/payout-solana) (token delegation).

## Related

* [Payouts](/stablecoin/payouts): the full payout section, with a tutorial per funding path
* [Payins](/stablecoin/payins): accept fiat and deliver stablecoins to a wallet
* [Managed wallet](/stablecoin/wallets): the funding wallet entity used in this quickstart
* [Webhooks](/learn/webhooks): handle `payout.complete` and other real-time events
* [KYC](/kb/kyc): customer verification levels and required fields
