# Pix withdrawals (/en/docs/conta-digital/withdrawals)

<QuickLinks>
  <QuickLink href="/docs/conta-digital/endpoints/withdrawals/post_withdraw" title="Withdraw to Pix key" method="POST" path="/transactions/withdraw" />

  <QuickLink href="/docs/conta-digital/endpoints/withdrawals/get_withdraw" title="Get withdrawal" method="GET" path="/transactions/withdraw/{withdrawId}" />

  <QuickLink href="/docs/conta-digital/recipient" title="Look up recipient" />
</QuickLinks>

The amount you request is what reaches the destination; the fee is added on top. Both leave the available balance at the time of the request and come back if the withdrawal fails.

<Mermaid
  chart="`
flowchart LR
  A[&#x22;Request the withdrawal&#x22;] --> B[&#x22;Amount and fee leave the balance&#x22;]
  B --> C[&#x22;WITHDRAW_COMPLETED webhook&#x22;]
  C --> D[&#x22;Money delivered&#x22;]
  B -.->|&#x22;failed&#x22;| E[&#x22;WITHDRAW_FAILED webhook&#x22;]
  E -.-> F[&#x22;Amount and fee come back to the balance&#x22;]

  click A &#x22;/docs/conta-digital/endpoints/withdrawals/post_withdraw&#x22; &#x22;Withdraw to Pix key&#x22;
  click C &#x22;/docs/conta-digital/webhooks&#x22; &#x22;Webhooks&#x22;
  click E &#x22;/docs/conta-digital/webhooks&#x22; &#x22;Webhooks&#x22;

  style A fill:#f59e0b,stroke:#d97706,color:#ffffff
  style C fill:#14ce71,stroke:#0eb464,color:#ffffff
  style D fill:#14ce71,stroke:#0eb464,color:#ffffff
  style E fill:#ef4444,stroke:#dc2626,color:#ffffff
`"
/>

<Steps>
  <Step>
    ### Check who receives [#check-who-receives]

    Optional. To show the key holder before confirming, use [Look up recipient](/docs/conta-digital/recipient).
  </Step>

  <Step>
    ### Request the withdrawal [#request-the-withdrawal]

    [`POST /transactions/withdraw`](/docs/conta-digital/endpoints/withdrawals/post_withdraw), scope `WITHDRAW`. Required: `amount`, in cents, and `pixKey`, the destination key.

    Generate an `Idempotency-Key` for each withdrawal and store it with your record. Repeating the call with the same key returns the existing withdrawal, without sending another Pix.

    <Tabs items="['curl', 'Node.js']">
      <Tab value="curl">
        ```bash
        IDEMPOTENCY_KEY=$(uuidgen)

        curl -X POST https://api.hub.payzu.com.br/api/v1/transactions/withdraw \
          -H "Authorization: Bearer $PAYZU_TOKEN" \
          -H "Idempotency-Key: $IDEMPOTENCY_KEY" \
          -H "Content-Type: application/json" \
          -d '{
            "amount": 10000,
            "pixKey": "fulano@exemplo.com",
            "pixKeyType": "EMAIL",
            "comment": "Repasse semanal"
          }'
        ```
      </Tab>

      <Tab value="Node.js">
        ```ts
        import crypto from 'node:crypto';

        const idempotencyKey = crypto.randomUUID();

        const res = await fetch('https://api.hub.payzu.com.br/api/v1/transactions/withdraw', {
          method: 'POST',
          headers: {
            Authorization: `Bearer ${process.env.PAYZU_TOKEN}`,
            'Idempotency-Key': idempotencyKey,
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({
            amount: 10000,
            pixKey: 'fulano@exemplo.com',
            pixKeyType: 'EMAIL',
            comment: 'Repasse semanal',
          }),
        });
        const saque = await res.json();
        ```
      </Tab>
    </Tabs>

    Also send `pixKeyType` (`CPF`, `CNPJ`, `EMAIL`, `PHONE` or `EVP`). Without it, the type is inferred from the format, and an 11-digit mobile number can be read as a CPF. A type that does not match the key is refused with `400` `WITHDRAW_PIX_KEY_TYPE_MISMATCH`, and nothing leaves the balance.

    `comment` goes to the recipient when their bank displays it. `callbackUrl` receives this withdrawal's webhooks and requires the [callback secret](/docs/conta-digital/webhooks#operation-callbackurl). All fields are in [Withdraw to Pix key](/docs/conta-digital/endpoints/withdrawals/post_withdraw).
  </Step>

  <Step>
    ### Store the withdrawal [#store-the-withdrawal]

    The response (`201`) carries the withdrawal. Store the `id`.

    ```json
    {
      "id": "hubp-20261005R4D8TN2WQZ127431",
      "status": "APPROVED",
      "amount": 10000,
      "serviceFee": 250,
      "totalDebited": 10250,
      "pixKey": "fulano@exemplo.com",
      "comment": "Repasse semanal",
      "e2e": null,
      "providerRejectedReason": null,
      "callbackUrl": null,
      "createdAt": "2026-10-05T14:40:11.002Z",
      "sentAt": "2026-10-05T14:40:11.380Z",
      "approvedAt": "2026-10-05T14:40:11.702Z",
      "confirmedAt": null
    }
    ```

    `totalDebited` is what left the account: `amount` + `serviceFee`. With a fee of 1.5% + R$ 1.00, a R$ 100.00 withdrawal debits R$ 102.50.
  </Step>

  <Step>
    ### Confirm delivery [#confirm-delivery]

    The withdrawal is delivered when the `WITHDRAW_COMPLETED` webhook arrives, with `status: "CONFIRMED"`. If it fails, `WITHDRAW_FAILED` arrives.

    To check at any time, call [`GET /transactions/withdraw/{withdrawId}`](/docs/conta-digital/endpoints/withdrawals/get_withdraw), scope `WITHDRAW_READ`, with the `id` from the response or the `withdrawId` from the webhook.

    In the lookup and in the list, the key comes in `destination.pixKey`, masked when it is a CPF, email or phone number. Only the `POST` response carries `pixKey` at the root.
  </Step>
</Steps>

## Withdrawal status [#withdrawal-status]

<Mermaid
  chart="`
stateDiagram-v2
  [*] --> REQUESTED
  REQUESTED --> CREATED
  CREATED --> APPROVED
  APPROVED --> CONFIRMED
  REQUESTED --> FAILED
  CREATED --> FAILED
  APPROVED --> FAILED
  CONFIRMED --> [*]
  FAILED --> [*]
`"
/>

| Status      | Meaning                                                                                                                                   |
| ----------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `REQUESTED` | Request received. The amount and the fee have already left the available balance.                                                         |
| `CREATED`   | Registered at the bank.                                                                                                                   |
| `APPROVED`  | Approved, on its way. The money has not been delivered yet.                                                                               |
| `CONFIRMED` | The money arrived. Webhook: `WITHDRAW_COMPLETED`.                                                                                         |
| `FAILED`    | It did not go out, and the amount and the fee came back to the balance. It can come from any previous status. Webhook: `WITHDRAW_FAILED`. |

## Repeated request [#repeated-request]

The `Idempotency-Key` has 1 to 255 visible ASCII characters, with no spaces. It is valid per account and does not expire.

| You send                                                   | The API responds                                                     |
| ---------------------------------------------------------- | -------------------------------------------------------------------- |
| The same key, with the same `amount` and the same `pixKey` | The existing withdrawal, in its current status. No new Pix goes out. |
| The same key, with another `amount` or another `pixKey`    | `409` `WITHDRAW_IDEMPOTENCY_KEY_REUSED`.                             |
| No key                                                     | A new withdrawal on each request.                                    |

`comment` and `callbackUrl` are not part of the comparison.

On a `502` with `PROVIDER_UNAVAILABLE`, or `PROVIDER_REFUSED` with `details.status` `408` or `429`, the Pix may have gone out, and the amount stays out of the available balance until the result is checked with the bank. Repeat with the same `Idempotency-Key`, which returns the original withdrawal, or look for the withdrawal in [`GET /transactions/withdraw`](/docs/conta-digital/endpoints/withdrawals/get_withdraws) before requesting again. Any other `PROVIDER_REFUSED` is a final refusal: the amount comes back right away and the withdrawal becomes `FAILED`.

## Balance and limits [#balance-and-limits]

* Insufficient balance refuses the whole withdrawal, with no partial withdrawal: `422` `WITHDRAW_INSUFFICIENT_BALANCE`, with `details.available` and `details.required`. `WITHDRAW_INSUFFICIENT_PROVIDER_BALANCE`: the bank does not cover the withdrawal at that moment, even with enough `available`.
* The amount must be between the account's minimum and maximum withdrawal, in `withdraw` in the [limits](/docs/conta-digital/statement#limits).
* There is a daily cap on Pix outflows, adding up withdrawals and Pix copy-and-paste payments. The cap and how much was already used that day are in `dailyWithdraw`; `0` blocks every withdrawal and `limit: null` means no cap. Going over it responds `422` `WITHDRAW_DAILY_LIMIT`.
* Up to 5 requests per minute per credential and 10 per account, counted together with Pix copy-and-paste payments and refunds. Above that, the API responds `429` with `Retry-After`.

## Lookups and receipts [#lookups-and-receipts]

* **List:** [`GET /transactions/withdraw`](/docs/conta-digital/endpoints/withdrawals/get_withdraws), scope `WITHDRAW_READ`, paginated by cursor. It also includes Pix copy-and-paste payments, with `operation: "EXTERNAL_PAYMENT"`.
* **Receipt:** [`GET /transactions/withdraw/{withdrawId}/receipt`](/docs/conta-digital/endpoints/withdrawals/get_withdraw_receipt) returns the PDF in base64, for a `CONFIRMED` withdrawal.

## Returned Pix [#returned-pix]

When the recipient returns the Pix, the amount comes back to the balance. Most of the time the `WITHDRAW_REFUND_RECEIVED` webhook arrives, with no fee. Details in [Pix received without a charge](/docs/conta-digital/deposits#return-of-a-sent-pix).

The rejections, with the `code`, are in [Withdraw to Pix key](/docs/conta-digital/endpoints/withdrawals/post_withdraw).