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

# Payout: USDC to BRL

> Pay out USDC from your customer's wallet to a Pix key in Brazil, end to end in the sandbox.

A payout takes stablecoin from your customer's wallet and delivers fiat to a bank account. In this quickstart, your customer sells 100 USDC and the BRL lands on a Pix key in Brazil. It runs in the sandbox, where the Pix transfer is simulated, so it takes about a minute and no real money moves.

## Why USDC and BRL

This picks up where the [pay-in quickstart](https://docs.lumx.io/quickstarts/pay-in.md) ends: the customer holds USDC on Polygon. Paying out over Pix shows the return trip, with the customer turning dollars on-chain back into reais, for example to pay a supplier or move the money to their own bank.

The same calls work in other corridors. Register a destination on another rail, such as a CLABE over `SPEI` for MXN, and point the off-ramp at it. See [Coverage](https://docs.lumx.io/get-started/coverage.md) for every currency, rail, and network.

## Build it with your AI agent

Copy a prompt into Cursor, Claude Code, Codex, or any coding agent. Both read this page and the API spec before writing code.

> [tab] Build it for me
>
> The agent writes and runs the full script, then reports back.
>
> ```text Prompt theme={null}
> You are a backend engineer integrating Lumx. Goal: in the Lumx sandbox, pay out USDC from a customer's wallet to that customer's own Pix key in Brazil, end to end, in one script.
>
> Ground truth. Read these before writing code and follow them over any prior knowledge:
> 1. https://docs.lumx.io/quickstarts/payout.md, the quickstart you are implementing.
> 2. https://docs.lumx.io/llms.txt, the documentation index. Every page has a .md twin at its own path.
> 3. https://lumx-docs-public-prod.s3.us-east-1.amazonaws.com/api-production.yaml, the OpenAPI spec. Take field names and enum values from here.
>
> Use https://api-sandbox.lumx.io only. Read the API key from the LUMX_API_KEY environment variable and the customer id from LUMX_CUSTOMER_ID, and never hard-code either. Never call production. The customer must be APPROVED and hold USDC on Polygon. If it does not, run https://docs.lumx.io/quickstarts/pay-in.md first.
>
> Steps:
> 1. GET /customers/{id}?includeBalances=true and confirm the Polygon wallet holds at least 100 USDC. Read the customer's name and taxId from the same response.
> 2. POST /destinations with rail PIX, currency BRL, identifier keyType CPF and keyValue equal to the customer's taxId, and holder type INDIVIDUAL, relationship SELF, the customer's name and taxId, and a Brazilian address. Send an Idempotency-Key header. Continue only if holder.verification.status is APPROVED.
> 3. POST /transactions/off-ramp with that destinationId, sourceCurrency USDC, sourceAmount "100.00", purpose PERSONAL_ACCOUNT, blockchain POLYGON, a memo, and an Idempotency-Key header.
> 4. Poll GET /transactions/{id} until the status is SUCCESS or FAILED. Print finalTargetAmount and blockExplorerUrl from the receipt.
>
> Constraints:
> - The minimum payout is the equivalent of USD 40.
> - Retry 429 responses with exponential backoff. No rate limit is published, so do not assume one.
> - Exit non-zero if any step fails, and log what each step returned.
>
> When you finish, hand back the script and a short summary of each step's result.
> ```

> [tab] Step by step
>
> The agent explains each call and waits for your go-ahead before running it.
>
> ```text Prompt theme={null}
> You are a backend engineer teaching me to integrate Lumx. Goal: in the Lumx sandbox, pay out USDC from a customer's wallet to that customer's own Pix key in Brazil. Walk me through it one step at a time.
>
> Ground truth. Read these first and follow them over any prior knowledge:
> 1. https://docs.lumx.io/quickstarts/payout.md, the quickstart we are following.
> 2. https://docs.lumx.io/llms.txt, the documentation index. Every page has a .md twin at its own path.
> 3. https://lumx-docs-public-prod.s3.us-east-1.amazonaws.com/api-production.yaml, the OpenAPI spec.
>
> Use https://api-sandbox.lumx.io only. Read the API key from the LUMX_API_KEY environment variable and never print it. Never call production. Ask me for the customer id. The customer must be APPROVED and hold USDC on Polygon. If it does not, we start with https://docs.lumx.io/quickstarts/pay-in.md.
>
> For each step: explain what the call does and why it is needed, show the exact request, run it only after I confirm, then show the response and point out the fields we use next. If a call fails, stop and explain the error before trying anything else.
>
> Steps:
> 1. GET /customers/{id}?includeBalances=true to check the USDC balance and read the customer's name and taxId.
> 2. POST /destinations for the customer's own CPF Pix key, with holder relationship SELF. Check that holder.verification.status is APPROVED.
> 3. POST /transactions/off-ramp for 100 USDC on Polygon to that destination, with purpose PERSONAL_ACCOUNT and an Idempotency-Key header.
> 4. GET /transactions/{id} until the status is SUCCESS, then walk me through the receipt.
> ```

## How it works

| **Object** | **Role in the payout** |
| :- | :- |
| [Wallet](https://docs.lumx.io/concepts/wallets.md) | Holds the customer's USDC. The off-ramp debits it. |
| [Destination](https://docs.lumx.io/concepts/destinations.md) | The bank account that receives the BRL, here a Pix key, with the holder's details. |
| [Off-ramp](https://docs.lumx.io/concepts/transactions.md) | One conversion: how much USDC goes out, from which network, and to which destination. |

## Before you start

* A sandbox API key. See [Authentication](https://docs.lumx.io/get-started/authentication.md).
* An approved customer with USDC in their wallet. The [pay-in quickstart](https://docs.lumx.io/quickstarts/pay-in.md) gets you there, and this page uses the customer it creates.

## 1. Register the Pix destination

A destination is where the payout goes, and Lumx verifies its holder before any money is sent. Here it is the customer's own Pix key, so `holder.relationship` is `SELF` and the holder's name and `taxId` match the customer.

```bash Request theme={null}
curl -X POST https://api-sandbox.lumx.io/destinations \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "customerId": "9d1ed178-7c29-42bb-912f-255f0e10cdb9",
    "name": "Ana - own account",
    "rail": "PIX",
    "currency": "BRL",
    "identifier": {
      "keyType": "CPF",
      "keyValue": "529.982.247-25"
    },
    "holder": {
      "type": "INDIVIDUAL",
      "relationship": "SELF",
      "name": "Ana Souza",
      "taxId": "529.982.247-25",
      "address": {
        "line1": "Rua Voluntarios da Patria 89",
        "city": "Rio de Janeiro",
        "state": "RJ",
        "postalCode": "22270-000",
        "country": "BRA"
      }
    }
  }'
```

```json Response (excerpt) theme={null}
{
  "id": "d588796f-1d5c-4c94-b8ae-7d4172a12732",
  "customerId": "9d1ed178-7c29-42bb-912f-255f0e10cdb9",
  "rail": "PIX",
  "currency": "BRL",
  "identifier": { "keyType": "CPF", "keyValue": "52998224725" },
  "holder": {
    "name": "Ana Souza",
    "type": "INDIVIDUAL",
    "relationship": "SELF",
    "verification": { "status": "APPROVED", "level": "BASIC" }
  }
}
```

A payout needs a destination in `APPROVED`, and this Pix destination comes back approved. Save its `id`. Later payouts to the same recipient can reuse it.

## 2. Create the off-ramp

The off-ramp sells 100 USDC from the customer's Polygon wallet and sends the BRL to the destination. The minimum per payout is the equivalent of USD 40.

```bash Request theme={null}
curl -X POST https://api-sandbox.lumx.io/transactions/off-ramp \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "destinationId": "d588796f-1d5c-4c94-b8ae-7d4172a12732",
    "sourceCurrency": "USDC",
    "sourceAmount": "100.00",
    "purpose": "PERSONAL_ACCOUNT",
    "blockchain": "POLYGON",
    "memo": "Quickstart payout"
  }'
```

```json Response (excerpt) theme={null}
{
  "id": "9685c5e2-9dd9-4eb4-a82c-f2f26a8d1ad0",
  "customerId": "9d1ed178-7c29-42bb-912f-255f0e10cdb9",
  "type": "OFF_RAMP",
  "request": {
    "sourceCurrency": "USDC",
    "targetCurrency": "BRL",
    "sourceAmount": "100.000000",
    "rail": "PIX",
    "purpose": "PERSONAL_ACCOUNT",
    "blockchain": "POLYGON",
    "memo": "Quickstart payout"
  },
  "state": { "status": "TRANSFERRING_STABLECOIN" }
}
```

* The destination already fixes the rail and the currency, so the request has no `rail` or `targetCurrency`. The response fills them in.
* `PERSONAL_ACCOUNT` only works with `SELF` destinations. To pay a third party, register the destination with their details and pick the matching [purpose code](https://docs.lumx.io/additional-information/purpose-codes.md).
* `memo` goes in the message field of the Pix.

## 3. Wait for the payout

The off-ramp moves through `TRANSFERRING_STABLECOIN`, `TRADING`, and `TRANSFERRING_FIAT` to `SUCCESS`. In the sandbox this takes about a minute.

```bash Request theme={null}
curl https://api-sandbox.lumx.io/transactions/9685c5e2-9dd9-4eb4-a82c-f2f26a8d1ad0 \
  -H "Authorization: Bearer YOUR_API_KEY"
```

```json Response (excerpt) theme={null}
{
  "id": "9685c5e2-9dd9-4eb4-a82c-f2f26a8d1ad0",
  "type": "OFF_RAMP",
  "request": {
    "sourceAmount": "100.000000",
    "targetAmount": "538.08"
  },
  "state": {
    "status": "SUCCESS",
    "receipt": {
      "sourceCurrency": "USDC",
      "sourceAmount": "100.000000",
      "targetCurrency": "BRL",
      "baseExchangeRate": "5.437900",
      "baseTargetAmount": "543.79",
      "fees": {
        "lumx": { "rate": "5", "flatAmount": "1.000000", "totalAmount": "1.050000", "currency": "USDC" }
      },
      "finalTargetAmount": "538.08",
      "finalExchangeRate": "5.380802",
      "transactionHash": "0xf82ab0941b313022f25b5a9a7c0ffa39e9031d0c1fff779c5c930f49971de1bb",
      "blockExplorerUrl": "https://amoy.polygonscan.com/tx/0xf82ab0941b313022f25b5a9a7c0ffa39e9031d0c1fff779c5c930f49971de1bb"
    }
  }
}
```

`finalTargetAmount` is the BRL the recipient receives, after fees. `blockExplorerUrl` opens the on-chain transfer that left the customer's wallet.

## What changes in production

* **Recipients:** most payouts go to third parties, such as suppliers or employees. Register their destination with their details and the right `holder.relationship`. Destinations on some rails stay in `UNDER_VERIFICATION` until Lumx approves them. Wait for the `destinations.approved` webhook.
* **The rate:** without a quote, the off-ramp converts at a floating rate. To fix the BRL amount before you pay, [lock a quote](https://docs.lumx.io/guides/locked-fx-quote-usdc-to-brl.md).
* **Status updates:** subscribe to the `offramp.*` [webhooks](https://docs.lumx.io/developer/webhooks.md) instead of polling.
* **Sender name:** the recipient sees your customer as the sender. See [Sender of record](https://docs.lumx.io/additional-information/sender-of-record.md).

## Related resources

> [card] [Pay out stablecoins via Pix](https://docs.lumx.io/guides/pix-payout-from-stablecoins.md)
>
> The full Pix payout guide, with third-party recipients and errors.

> [card] [Lock an FX quote](https://docs.lumx.io/guides/locked-fx-quote-usdc-to-brl.md)
>
> Fix the BRL amount before you pay.

> [card] [USDT to MXN over SPEI](https://docs.lumx.io/guides/use-cases/usdt-to-mxn-spei-payout.md)
>
> The same flow in Mexico.

> [card] [Pay-in: BRL to USDC](https://docs.lumx.io/quickstarts/pay-in.md)
>
> Fund the wallet first.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.