Skip to main content
A withdrawal moves available BRL from your YuvexPay balance to a destination PIX key. Withdrawals are created via POST /v1/withdrawals and processed asynchronously by the network.

What amount means

amount is the net — the exact value that reaches the recipient. The platform fee is added on top of it, never deducted from it. For a request of amount: 250.00 against the default R$ 2.49 fee: A R$ 250.00 payout therefore costs you R$ 252.49. Your available balance must hold the gross, and INSUFFICIENT_BALANCE is evaluated against the gross, not against amount. Everything else splits the same way:
  • Daily and nightly limits count the gross. used in GET /v1/withdrawals/limits is the sum of grossAmount for the day, so the largest amount you can request is remaining - fee, not remaining.
  • Per-transaction caps are compared against the gross.
  • The minimum is compared against amount — the net. At the R$ 10.00 floor, a R$ 10.00 withdrawal is accepted and debits R$ 12.49.
The fee is fixed per request, not a percentage of it. Your account’s active value is returned as fee by GET /v1/withdrawals/limits — read it from there rather than hardcoding 2.49.

Constraints

  • Currency: BRL only.
  • Method: PIX only. Other rails (boleto, TED) are not exposed via the API.
  • Minimum amount: R$ 10.00, compared against amount (the net). This is a platform floor that the platform never goes below, but it can be raised — read the value that applies to you from minAmount in GET /v1/withdrawals/limits rather than hardcoding 10. It is unrelated to the routing provider’s own minimum, which surfaces separately as WITHDRAWAL_BELOW_PROVIDER_MINIMUM.
  • Per-transaction cap: account-dependent, not a fixed platform number. The cap that applies to your account is returned as perTransactionLimit by GET /v1/withdrawals/limits (null means no account-level cap). A second, lower ceiling can apply at the network side depending on which PIX provider routes the payout. That one is not knowable before submission, but it is still evaluated synchronously: it comes back as a 400 WITHDRAWAL_LIMIT_EXCEEDED or 400 WITHDRAWAL_BELOW_PROVIDER_MINIMUM on the create call, after the account-level checks have passed. Requests above R$ 1,000,000.00 are rejected by request validation before any of this is evaluated. Both caps are compared against amount + feeAmount, so the largest amount you can request is the cap minus the fee.
  • Daily and nightly limits: Each account has a daily limit. After business hours (BRT) a smaller “nightly” limit applies. Use GET /v1/withdrawals/limits to fetch the live numbers, including how much you’ve already used today and the current dayStartHour / dayEndHour cutoffs. Day and night share one counter: used is the running total for the whole Brazilian calendar day, so the nightly cap is compared against a number that already includes your daytime volume.
  • used and remaining count the fee: a withdrawal consumes amount + feeAmount of your limit. The largest amount you can request is therefore remaining - fee, not remaining.
  • PIX key type: detected automatically from destination.pixKey. CPF, CNPJ, e-mail, Brazilian phone (+55XXXXXXXXXXX), and random EVP/UUID keys are all accepted. You do not need to send a pixKeyType field. INVALID_PIX_KEY covers format only — a key is rejected up front when it is not a recognizable CPF, CNPJ, e-mail, phone or EVP (a CPF or CNPJ key must also pass its check digits). Whether the key actually exists on the PIX network is not checked before acceptance. Depending on when the network rejects it, a well-formed key that belongs to nobody surfaces either as a synchronous 400 PROVIDER_ERROR on the create call or later as a WITHDRAWAL_FAILED webhook. Handle both.
  • Recipient document: the PIX network requires a creditor document on every payout. Send destination.recipientDocument whenever the destination key belongs to someone other than you. See Recipient document.

Recipient document

Every PIX payout carries a creditor document — the CPF or CNPJ of the account that receives the money. YuvexPay resolves it in three steps, in this order:
  1. destination.recipientDocument, when you send it. Punctuation and whitespace are stripped server-side, and the result must be a valid CPF (11 digits) or CNPJ (14 digits) — check digits included.
  2. The PIX key itself, when destination.pixKey is a CPF or a CNPJ key. Such a key belongs to that document by definition, so it is always a better creditor than your own tax id.
  3. Your own tax id — the company CNPJ for business accounts, the owner’s CPF for individual accounts. In sandbox this step returns a placeholder document rather than your real tax id, so a sandbox request never fails with CREDITOR_DOCUMENT_UNAVAILABLE.
Step 3 is a fallback, not a default. If you pay a third party on an e-mail, phone or random key and omit recipientDocument, the network is told your document is the creditor. The request is still accepted, but the payout can be rejected downstream by the receiving institution, arriving as a WITHDRAWAL_FAILED webhook minutes or hours later. If you send recipientDocument and the key is a CPF or CNPJ key, the two must agree. A disagreement is a typo in one of them and is rejected up front with RECIPIENT_DOCUMENT_MISMATCH rather than failing at the network later. creditorDocumentSource is a dashboard-only field. Sending it to POST /v1/withdrawals is rejected with 400 CREDITOR_DOCUMENT_SOURCE_NOT_SUPPORTED; it is never silently ignored. To put a document other than your company CNPJ on the wire from the API, send destination.recipientDocument — it wins over step 3 and puts exactly the document you send on the payout.

Create a withdrawal

Paying a third party — send the holder’s document:
Paying a CPF or CNPJ key — the document is derived from the key, so recipientDocument is redundant:
The response includes the withdrawal record:
netAmount is what reaches the recipient — the amount you requested, always identical to it. grossAmount is amount + feeAmount, and that is what is debited from your balance and counted against your limits, at the time the withdrawal is created. See What amount means.

Lifecycle and statuses

Listen for WITHDRAWAL_SENT and WITHDRAWAL_FAILED webhook events to react to status changes.
Never retry a withdrawal that is sitting in PROCESSING. Retrying risks sending the same money twice. PROCESSING means the transfer was handed to the network and its outcome is not yet known — the horizon for that is hours, not minutes, and a withdrawal can legitimately sit there for a large part of a business day before settling or failing. Wait for the WITHDRAWAL_SENT or WITHDRAWAL_FAILED webhook, or poll GET /v1/withdrawals/{withdrawalId}. Funds are returned to your balance automatically when a withdrawal fails.

PIX key in responses

The pixKey field is always returned masked in withdrawal responses (both in GET /v1/withdrawals and GET /v1/withdrawals/{withdrawalId}). This is intentional: it prevents the full key from being logged or cached client-side. If you need to reconcile a withdrawal against your own records, use txId or your own metadata, not the masked pixKey.

Fees

The platform’s withdrawal fee is fixed per request and is reported in the feeAmount field of every withdrawal. The active value is returned as fee by GET /v1/withdrawals/limits; the platform default is R$ 2.49. The fee is charged on top of amount and counts towards your daily limit. See What amount means for the full breakdown.

Idempotency

POST /v1/withdrawals requires X-Idempotency-Key. Reusing the same key with the same body returns the original response. Reusing it with a different body returns 409 IDEMPOTENCY_PAYLOAD_MISMATCH.

Receipts

Once a withdrawal is COMPLETED you can fetch a printable receipt. The endpoint returns rendered HTML (format=html) or plain text (format=text), not a PDF, and requires the documents:read scope:
The receipt is scoped to the environment of the key you call it with. A ypk_live_ key can only fetch receipts for production withdrawals and a ypk_test_ key only for sandbox ones — the other environment returns 404, even for a withdrawal id that belongs to your own account.

Common error codes

INVALID_WITHDRAWAL_RECIPIENT and PIX_KEY_VALIDATION_FAILED were removed. The PIX key ownership policy they enforced no longer exists — withdrawals go to any valid PIX key. Neither code can be returned by the API; remove any branch in your integration that handles them.CREDITOR_DOCUMENT_PERSONAL_FORBIDDEN was likewise never reachable from an API key and is no longer documented here. creditorDocumentSource now returns 400 CREDITOR_DOCUMENT_SOURCE_NOT_SUPPORTED on the public API.