Skip to content

Latest commit

 

History

History
111 lines (93 loc) · 4.67 KB

File metadata and controls

111 lines (93 loc) · 4.67 KB
title Withdraw
description Step-by-step guide to sending funds from an account to a registered beneficiary.

Overview

Withdrawals move funds out of an account to an external destination — a bank account (PIX, TED) or a crypto wallet. Every withdrawal references a quote that locks the FX rate (or a 1:1 spot for same-asset) and a previously approved beneficiary with at least one payment instruction.

Prerequisites

Steps

Submit the holder details and the payment instruction (PIX, bank account, or crypto wallet). The beneficiary record itself has no status — it is created once and reused across destinations. Each payment instruction is reviewed individually: it starts in `PENDING_REVIEW` on creation and transitions asynchronously to `APPROVED` or `REJECTED`. The first instruction on a new beneficiary triggers the full compliance review; instructions added later to the same beneficiary go through a reduced check.
```bash
curl --request POST \
  --url {{sandboxUrl}}/api/beneficiaries \
  --header 'Authorization: Bearer <token>' \
  --header 'X-Idempotency-Key: <unique-key>' \
  --header 'Content-Type: application/json' \
  --data '{
    "holder": {
      "type": "INDIVIDUAL",
      "firstName": "John",
      "lastName": "Doe",
      "taxId": {
        "value": "12345678901",
        "type": "CPF"
      },
      "dateOfBirth": "1990-01-15"
    },
    "relationshipType": "THIRD_PARTY",
    "paymentInstruction": {
      "type": "PIX",
      "asset": "BRL",
      "dictKeyType": "CPF",
      "dictKey": "12345678901"
    }
  }'
```

The response returns the beneficiary with its `id` and the created `paymentInstruction.id`. A `BENEFICIARY_PAYMENT_INSTRUCTION_CREATED` webhook fires immediately, then either `BENEFICIARY_PAYMENT_INSTRUCTION_APPROVED` or `BENEFICIARY_PAYMENT_INSTRUCTION_REJECTED` once the review completes — subscribe to track the outcome. Only `APPROVED` instructions can be used in a withdrawal.
Quotes lock the FX rate (or a 1:1 spot for same-asset) for a short window and are bound to one account. Provide either `sourceAmount` or `targetAmount`, never both.
```bash
curl --request POST \
  --url {{sandboxUrl}}/api/quotes \
  --header 'Authorization: Bearer <token>' \
  --header 'X-Idempotency-Key: <unique-key>' \
  --header 'Content-Type: application/json' \
  --data '{
    "accountId": "<account-id>",
    "sourceAsset": "BRL",
    "targetAsset": "BRL",
    "sourceAmount": "500.00"
  }'
```

The response returns the quote `id`, the locked `effectiveRate`, and `expiresAt`. The quote can be consumed by exactly one operation before it expires.
Reference the approved beneficiary, the chosen payment instruction on that beneficiary, and the quote.
```bash
curl --request POST \
  --url {{sandboxUrl}}/api/operations/withdrawal \
  --header 'Authorization: Bearer <token>' \
  --header 'X-Idempotency-Key: <unique-key>' \
  --header 'Content-Type: application/json' \
  --data '{
    "accountId": "<account-id>",
    "quoteId": "<quote-id>",
    "beneficiary": {
      "type": "REFERENCE",
      "id": "<beneficiary-id>",
      "paymentInstruction": {
        "type": "REFERENCE",
        "id": "<payment-instruction-id>"
      }
    }
  }'
```

Returns `201` immediately with the operation in `REQUESTED` status. Settlement and rail dispatch happen asynchronously.
Subscribe to `OPERATION_COMPLETED` and `OPERATION_FAILED` to receive the terminal outcome — both deliver the same payload as `OPERATION_REQUESTED`, with `currentState.status` set to the new status (and `currentState.reason` populated on failure). Intermediate statuses (`PROCESSING`, `ON_HOLD`, `ACTION_REQUIRED`) are not published as webhooks; poll `GET /api/operations/{operationId}` if you need to surface them in your UI.
```bash
curl --request GET \
  --url {{sandboxUrl}}/api/operations/<operation-id> \
  --header 'Authorization: Bearer <token>'
```

What happens next