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

# Transfers and cash-out

> How the Indirect Pix Plugin (BTG) confirms a destination before moving money, and how a Pix cash-out settles.

A Pix cash-out moves money out of an account to an external destination. The **Indirect Pix Plugin (BTG)** handles it in two deliberate steps — **initiate**, then **process** — so you always confirm *where* the money is going before any funds leave the ledger.

## Why two steps

***

Splitting a cash-out into initiate and process gives you a checkpoint between "who is the payee?" and "send the money":

* **Verify the destination first.** Initiate validates and resolves the payee account without touching balances. A wrong Pix key or an invalid account fails here — before any money moves.
* **Show the payer who they're paying.** The initiate response returns the resolved account owner, so your app can display the real name and let the payer confirm before committing.
* **Move funds only on confirmation.** Nothing is debited until you process the transfer. If the payer abandons the flow, there's no reversal to make — there was never any movement to undo.

This mirrors how a good payment experience works: look up the destination, confirm the details, then pay.

<Note>
  Both steps are idempotent — safe to retry without creating duplicate transfers. See [Retries and idempotency](/en/reference/retries-idempotency).
</Note>

## Step 1 — Initiate: confirm the destination

***

Initiating a transfer creates a short-lived record that validates and resolves the payee **without moving funds**. How the plugin finds the destination depends on what you start with:

| You start with                              | Initiation type | What the plugin does                                                                                                         |
| ------------------------------------------- | --------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| A Pix key (CPF, CNPJ, email, phone, or EVP) | `KEY`           | Looks the key up in [DICT](/en/midaz/plugins/pix/indirect/indirect-pix-dict) and resolves the destination account for you.   |
| A QR code (BR Code)                         | `QR_CODE`       | Decodes the code and resolves the destination via DICT. See [QR Codes](/en/midaz/plugins/pix/indirect/indirect-pix-qrcodes). |
| The payee's full account details            | `MANUAL`        | Uses the branch, account, participant, and owner document you provide — no DICT lookup needed.                               |

For `KEY` and `QR_CODE`, you never supply the destination yourself. The plugin resolves it and returns it in the response, ready to show the payer for confirmation.

### Request — pick the tab for your initiation type

<CodeGroup>
  ```json KEY theme={null}
  POST /v1/transfers/cashout/initiate
  X-Account-Id: 01989f9e-6508-79f8-9540-835be49fbd0d
  {
    "initiationType": "KEY",
    "key": "john.doe@example.com"
  }
  ```

  ```json QR_CODE theme={null}
  POST /v1/transfers/cashout/initiate
  X-Account-Id: 01989f9e-6508-79f8-9540-835be49fbd0d
  {
    "initiationType": "QR_CODE",
    "emv": "00020126...5802BR5913Fulano..."
  }
  ```

  ```json MANUAL theme={null}
  POST /v1/transfers/cashout/initiate
  X-Account-Id: 01989f9e-6508-79f8-9540-835be49fbd0d
  {
    "initiationType": "MANUAL",
    "destination": {
      "account": {
        "branch": "0001",
        "number": "123456789",
        "participant": "12345678",
        "type": "CACC"
      },
      "owner": {
        "document": "12345678901",
        "name": "John Doe"
      }
    }
  }
  ```
</CodeGroup>

Account `type` values are `CACC` (checking), `SVGS` (savings), `TRAN` (transaction), and `OTHR` (other). `endToEndId` is optional for all types — it's auto-generated when omitted.

### Response

The response returns the initiation `id` (used as `initiationId` in step 2) and the resolved `destination`:

```json theme={null}
→ 201 Created
{
  "id": "019c96a0-0c82-7c3d-8dcc-c180868b45c4",
  "initiationType": "KEY",
  "endToEndId": "E1234567820240101000001234567890",
  "destination": { "account": { ... }, "owner": { ... } },
  "expiresAt": "2024-01-15T11:00:00Z",
  "createdAt": "2024-01-15T10:30:00Z"
}
```

<Note>
  Initiations expire. The response includes an `expiresAt` timestamp — process the transfer before it lapses, or initiate again. This keeps a confirmed destination from going stale between the lookup and the payment.
</Note>

<Tip>
  **API reference:** [Initiate a Pix Transfer](/en/reference/midaz/plugins/indirect-pix/initiate-a-pix-transfer)
</Tip>

## Step 2 — Process: move the money

***

Processing takes the initiation you just confirmed and executes the cash-out: it debits the source account and routes the payment to BTG for settlement with BACEN.

Settlement with the Pix network is **asynchronous**. The transfer comes back as `PROCESSING` while BTG settles, and the final result — completed or failed — arrives later through a `cashout` webhook. Build your flow to react to that event rather than waiting on the process response. See [Webhooks](/en/midaz/plugins/pix/indirect/indirect-pix-webhooks).

### Request

Pass the `id` from the initiate response as `initiationId`, along with the `amount` to transfer:

```json theme={null}
POST /v1/transfers/cashout/process
X-Account-Id: 01989f9e-6508-79f8-9540-835be49fbd0d
X-Purpose: TRANSFER
{
  "initiationId": "019c96a0-0c82-7c3d-8dcc-c180868b45c4",
  "amount": "100.50"
}
```

`amount` is required. You can also pass an optional `description` (max 140 characters) and `metadata` (custom key-value attributes).

#### The `X-Purpose` header

Use the optional `X-Purpose` header to declare why the cash-out is happening. It defaults to `TRANSFER` when omitted:

| Value                    | When to use                                                                                                                                  |
| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------- |
| `TRANSFER`               | A regular Pix cash-out — the default for ordinary payments.                                                                                  |
| `INSTANT_PAYMENT_REFUND` | When the cash-out is refunding a previously received instant payment, so the network can classify it as a refund rather than a new transfer. |

<Note>
  **Fixed-amount QR codes:** when the initiation is a `QR_CODE` whose EMV payload carries a fixed amount, the `amount` you send to process **must equal** that encoded amount. A mismatch is rejected before any funds move.
</Note>

### Response

```json theme={null}
→ 201 Created
{
  "id": "019c96a0-0c21-71f9-a487-66a1258278a1",
  "endToEndId": "E1234567820240101000001234567890",
  "amount": "100.50",
  "status": "PROCESSING",
  "type": "CASHOUT",
  "createdAt": "2024-01-15T10:30:00Z",
  "updatedAt": "2024-01-15T10:30:00Z"
}
```

<Note>
  When the destination belongs to your own institution, the money never leaves for BTG — it settles internally as a P2P transfer. See [Intra-PSP transfers](/en/midaz/plugins/pix/indirect/indirect-pix-intra-psp).
</Note>

<Tip>
  **API reference:** [Process a Pix Transfer](/en/reference/midaz/plugins/indirect-pix/process-a-pix-transfer)
</Tip>

## Tracking a transfer

***

Every transfer follows a predictable lifecycle: it starts in `PENDING`/`PROCESSING` while it's in flight, then reaches a terminal `COMPLETED`, `FAILED`, or `CANCELLED`. To check where a transfer stands, you can retrieve a single one by its id, or list transfers filtered by status, type (cash-out or cash-in), or date range.

```json theme={null}
GET /v1/transfers?type=CASHOUT&status=COMPLETED&limit=10&offset=0
X-Account-Id: 01989f9e-6508-79f8-9540-835be49fbd0d
```

List filters include `status`, `type` (`CASHOUT`/`CASHIN`), `end_to_end`, and `modified_after`/`modified_before`, plus `limit`/`offset`/`sort_order` pagination.

<Tip>
  **API reference:** [List transfers](/en/reference/midaz/plugins/indirect-pix/list-pix-transfers) · [Retrieve a transfer](/en/reference/midaz/plugins/indirect-pix/retrieve-a-pix-transfer)
</Tip>

## When a transfer gets stuck

***

If the settlement call to BTG times out before it confirms, a transfer can stay in `PROCESSING` with its funds still on hold. The plugin provides an **unblock** operation that re-checks the transfer with BTG and drives it to the correct final state — settling it if BTG confirms, or releasing the hold if BTG never received it.

<Note>
  Unblock doesn't apply to intra-PSP transfers — there's no BTG transaction to re-check. For the full unblock behavior and its options, see [Refund operations](/en/midaz/plugins/pix/indirect/indirect-pix-refund-operations).
</Note>

## Next steps

***

* [Intra-PSP transfers](/en/midaz/plugins/pix/indirect/indirect-pix-intra-psp) — Internal P2P settlement
* [QR Codes](/en/midaz/plugins/pix/indirect/indirect-pix-qrcodes) — Generating and decoding QR codes
* [Refund operations](/en/midaz/plugins/pix/indirect/indirect-pix-refund-operations) — Refunds and unblocking
* [Webhooks](/en/midaz/plugins/pix/indirect/indirect-pix-webhooks) — Cash-out and cash-in event handling
* [API reference](/en/reference/midaz/plugins/indirect-pix/initiate-a-pix-transfer) — Full request/response details, headers, and field schemas
