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

> Send Pix cash-out through the Indirect Pix Plugin via BTG: the two-step initiate-and-process flow that confirms the destination before moving funds.

A Pix cash-out moves money from an account to an external destination. The **Indirect Pix Plugin (BTG)** runs it in two steps: **initiate**, then **process**. You confirm *where* the money goes 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 receives the money.** The initiate response returns the resolved account owner. Your app can display the real name and let the payer confirm first.
* **Move funds only on confirmation.** The plugin debits nothing until you process the transfer. If the payer abandons the flow, there is no movement to undo.

<Note>
  Both steps are idempotent. You can retry them 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/interfaces/pix-btg/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/interfaces/pix-btg/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. The plugin generates one when you omit it.

### 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/interfaces/pix-btg/initiate-a-pix-transfer)
</Tip>

## Step 2: Process (move the money)

***

Processing executes the cash-out from the initiation you confirmed. It debits the source account, then 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. The final result (completed or failed) arrives later through a `cashout` webhook. Build your flow to react to that event, not to wait on the process response. See [Webhooks](/en/interfaces/pix-btg/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 the reason for the cash-out. 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:** the initiation can be a `QR_CODE` whose EMV payload carries a fixed amount. In that case, 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/interfaces/pix-btg/indirect-pix-intra-psp).
</Note>

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

## Tracking a transfer

***

Every transfer follows the same lifecycle. It starts in `PENDING`/`PROCESSING` while in flight, then reaches a terminal `COMPLETED`, `FAILED`, or `CANCELLED`. To check where a transfer stands, retrieve a single one by its id. You can also 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&page=1
X-Account-Id: 01989f9e-6508-79f8-9540-835be49fbd0d
```

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

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

## How transfers land in Midaz

***

The plugin posts every settled movement to Midaz as a ledger transaction, with the external leg against the `@external/BRL` account. Midaz records the accounting entry and correlation metadata, not the transfer's full banking details. Counterparty branch, account number, account type, and Pix key never reach Midaz. The one exception is the payer's identity on cash-in (`sourceBank`, `sourceDocument`, `sourceName`), stamped when known. The full counterparty detail lives in the plugin's transfer record.

The metadata stamped on the Midaz transaction depends on the flow:

| Flow         | Metadata keys                                                                                                                                                      |
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Cash-out     | `initiationId`, `endToEndId`, `accountId`, `transferType: CASHOUT`, `paymentType`, `initiationType`                                                                |
| Cash-in      | `endToEndId`, `accountId`, `transferType: CASHIN`, `paymentType`, `initiationType` — plus `sourceBank`, `sourceDocument`, and `sourceName` when the payer is known |
| Refund (out) | `refundId`, `originalEndToEndId`, `returnIdentification`, `accountId`, `transferType: REFUND_CASHOUT`, `refundType`, `reason`                                      |
| Refund (in)  | The same refund keys with `transferType: REFUND_CASHIN`                                                                                                            |

The Midaz transaction `code` also carries the `endToEndId` (or the `returnIdentification` for refunds), so the E2E identifier is visible directly on the ledger entry.

Correlation works in both directions:

* The plugin stores the Midaz transaction and operation identifiers on its own transfer and refund records, and uses them to commit, cancel, or revert ledger entries.
* The Midaz transaction carries correlation keys in its metadata: filter by `metadata.endToEndId` for cash-outs and cash-ins, or by `metadata.originalEndToEndId` / `metadata.returnIdentification` for refunds. The transaction `code` is the common fallback. It carries the E2E ID on transfers and the return identification on refunds.

<Note>
  Custom `metadata` you pass when processing a cash-out is stored with the plugin's transfer record and returned by the plugin's own API. It is **not** copied onto the Midaz transaction. The plugin fixes the Midaz metadata keys above.
</Note>

## When a transfer gets stuck

***

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

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

## Next steps

***

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