Affiliation PIX keys (
/pix/keys) are not the same as external PIX key destinations under /pix-keys. The latter exists only for cashout recipients. See Banking and PIX Payments.Origins and destinations
The origin is always identified byorigin_bank_account_id: an account UUID that corresponds to a Bank Account from an Affiliation with available balance. The destination is set through exactly one of four fields on the cashout body:
destination_bank_account_id— id of a registered destination bank account.destination_pix_key_id— id of a registered destination PIX key.destination_bank_account— an inline bank account payload (branch, account, holder, ISPB) that the service matches against the caller’s active accounts on(account_number, ispb)and either reuses or registers as a new non-primary account.destination_pix_key— an inline PIX key value ({ "key": "…" }) that the service normalizes and matches against the caller’s active keys, or registers as a new non-primary key using a single DICT lookup shared with the payment itself.
400 validation error. Registered destinations can be prepared in advance with POST …/bank-accounts / POST …/pix-keys; inline destinations remove that separate step.
Entity relationships
Operational rules
- One destination per cashout: send exactly one of
destination_bank_account_id,destination_pix_key_id,destination_bank_accountordestination_pix_key. Requests with more than one (or none) fail validation with a400error. - Inline resolution is caller-scoped: an inline
destination_bank_accountordestination_pix_keyis only matched against, or created under, the caller’s own merchant or company records. It never reaches a third party’s stored account. Records created inline are always non-primary. - Inline resolution happens after the guards: the origin, pricing and balance checks run first, so a request rejected before the payment leaves no record behind. A request rejected by the provider after the payment attempt starts leaves the new record as a valid, reusable destination.
- Inline bank-account conflicts: when an inline
destination_bank_accountmatches an active account on(account_number, ispb)but differs on another banking field, the request is rejected with409 CONFLICT_ERROR(details.differing_fieldsnames the mismatched fields) rather than silently paying to the stored details. - No implicit destination: the
primaryflag on bank accounts and PIX keys never affects a cashout you create through the API—every request names its destination explicitly.primaryonly matters for automatic cashouts. - Balance: funds must be available on the origin.
- Identifiers:
request_idis required—use it for idempotency and to correlate your orders with ours. - DICT: PIX key destinations are validated with the network; responses may expose masked holder data per BACEN rules. An inline PIX key spends exactly one DICT lookup, made after every local guard and consumed by the payment itself.
- PIX key destinations require an active Affiliation as it is required for DICT lookup
External PIX keys
Create a/pix-keys record per recipient key your integration will route cashouts through. Resolution runs against DICT; creation responses include dict_key_information (sometimes masked).
In a company context, use
/v1/companies/me/pix-keys (create, read, update, delete) instead of /v1/merchants/{merchantId}/pix-keys. Full field lists and behavior are documented on those /pix-keys paths in the API reference.External bank accounts
Register recipient settlement details withPOST …/bank-accounts. Accounts used as cashout destinations reuse the same merchant (or company) bank-account resources described in Banking; the difference is how you use the returned id in the cashout payload.
Use digits only for
branch_number and account_number (no dashes or spaces). Full field lists and validation errors are documented on POST /v1/merchants/{merchantId}/bank-accounts (and /v1/companies/me/bank-accounts) in the API reference.nickname is optional (1–100 characters) and only used to help you tell destinations apart when you have multiple external bank accounts registered—it is never sent to the provider. It can be edited at any time (including on accounts that already have cashouts) and cleared by sending "nickname": null on PATCH. Cashout responses echo the current label of the destination account as destination_bank_account_nickname (live value, not a snapshot; null for PIX-key destinations or accounts without a nickname). See Banking → Nicknames.
Creating a cashout
Each cashoutPOST debits origin_bank_account_id, transfers amount (in cents), and uses method: PIX. Omit one destination field entirely when you use the other.
Bank account destination
PIX key destination
Senddestination_pix_key_id (the id from POST …/pix-keys) instead of destination_bank_account_id.
Inline destinations
To pay to a destination the caller has not registered yet, send the destination in the cashout body itself. The service reuses the caller’s existing active record when one matches, or registers a new non-primary record as part of the request; the 201 response carries the resultingdestination_bank_account_id or destination_pix_key_id so subsequent cashouts can reference it directly.
Inline PIX key (destination_pix_key) — the value is normalized (documents to bare digits, phones to + and digits, emails to lowercase), so formatting differences never create a duplicate. A miss triggers a single DICT lookup that persists the key and is consumed by the same payment:
201 — destination_pix_key_id is the id of the reused or newly registered key:
destination_bank_account) — the caller’s active account with the same (account_number, ispb) is reused when its branch_number, account_type, account_holder_name and account_holder_document_number all match the payload. A match with different values is rejected with 409 CONFLICT_ERROR (details.differing_fields names the mismatched fields); no match creates a non-primary company bank account:
201 — destination_bank_account_id is the id of the reused or newly registered account:
(account_number, ispb) matches an active account of the caller but any of branch_number, account_type, account_holder_name or account_holder_document_number differs, the request is rejected with 409 CONFLICT_ERROR (error.details.differing_fields names the mismatched field names, error.details.bank_account_id is the stored account’s id, error.details.field is account_number):
Inline destinations are resolved and registered only after the origin, pricing and balance guards pass. A request rejected before payment leaves no record behind; a request rejected by the provider after payment starts leaves the new destination in place, ready to reuse.
POST …/cashouts schema in the API reference:
Automatic cashouts
Companies with automatic transfers enabled (transfer_configurations.automatic_transfer_enabled, see Banking → Automatic transfers) get cashouts created by Rinne on the configured schedule, without an API call. Because there is no request body, the destination is selected from the company’s registered records by priority:
- Primary external bank account — the company’s
/bank-accountsrecord flaggedprimarywith statusACTIVE. - Primary external PIX key — used only when no active primary bank account exists: the company’s
/pix-keysrecord flaggedprimarywith statusACTIVE. - Neither registered — the automatic cashout is skipped for that cycle; no transfer happens until an active primary destination exists.
Listing, status, and receipts
You confirm outcomes by polling identifiers and subscribing to webhooks (preferred for production).Receipts are only available for eligible finalized states, may require operational context such as end-to-end IDs, and are documented under
GET /v1/merchants/{merchantId}/cashouts/{id}/receipt (organization: GET /v1/banking/cashouts/{id}/receipt).Lifecycle and returns
Statuses move asynchronously:PENDING, PROCESSING, COMPLETED, FAILED, plus post-settlement reversal states PARTIALLY_RETURNED and RETURNED.
COMPLETED: the outbound leg succeeded from the provider’s perspective.PARTIALLY_RETURNED/RETURNED: subsequent reversal events alter what you reconcile—treat each transition as its own ledger event.
Webhooks
Cashouts finish asynchronously after the API acceptsPOST …/cashouts: the provider executes the PIX leg and may emit returns later. Treat webhooks as the primary signal for lifecycle updates in production (use listing and GET …/cashouts/{id} when you need to backfill or audit).
Rinne sends two banking events for cashouts:
cashout.created: Emitted when the cashout resource is created successfully.cashout.status-changed: Emitted when status changes—covering progress (PENDING,PROCESSING), terminal outcomes (COMPLETED,FAILED), and post-settlement reversals (PARTIALLY_RETURNED,RETURNED).
cashout_id, old_status, new_status, and error_message when a failure occurs). Event envelopes also carry standard metadata such as id, timestamp, company_id, and correlation_id; see the Webhooks guide for the shared shape.
For endpoint setup, Svix signature verification, retries, and handler examples, see Webhooks. Payload field definitions for each event live in the API reference under Webhooks → Events (cashout.created, cashout.status-changed).
Next steps
Cashouts guide
Step-by-step registration, payloads, and organization vs merchant paths
Banking
Balances, statements, affiliation keys, internal transfers
Webhooks
Event-driven lifecycle handling
API reference
Exact request and response schemas for each cashout and destination endpoint

