Transaction Approval
Flow to require multiple approvals before a Pix payment is executed in BaaS API.
Instead of sending a Pix payment directly, the payer creates a transaction approval request. The payment is only released after the approvers registered in the wallet cast enough approval votes.
Prerequisite
You will need:
- an authenticated user with a finished onboarding
x-wallet-uuidheader on every requestnonceheader on every requestx-transaction-uuidheader on every write request (create, approve, cancel, delete)- the approver users already registered in the wallet
Approver setup is a prerequisite managed outside this BaaS flow. Have an authorized wallet administrator provision the APPROVER and, when required, APPROVER_MASTER roles before enabling approval settings. Provision access to view the relevant requests as well as permission to vote; approval permission alone does not grant every other action in this guide.
Provisioning Approvers through the Users API
The BaaS approval endpoints do not assign roles to wallet users. If the approvers are not configured yet, use the Users API with its required authentication and headers, including x-wallet-uuid for the same wallet used in this guide. The update must be performed by the wallet owner or an authorized wallet administrator; do not grant administrative privileges just to let a user vote. If your integration only has BaaS access, arrange this setup with the wallet administrator before enabling the approval setting.
GET /operations/permissions/typeslists the available permission type tags.GET /operations/permissions/userslists wallet members and their currentpermission_types.PATCH /operations/permissionsupdates an existing member. Senduser_idandpermission_types, includingAPPROVERfor common approval orAPPROVER_MASTERfor master approval.
The submitted permission_types list replaces the member's current roles; it does not append to them. Include the complete intended list, preserving other roles the member still needs. Confirm access to read requests separately from permission to vote or cancel. ROOT cannot be assigned, and this endpoint cannot change the wallet owner's permissions.
Flow Overview
Steps 1 and 2 are executed once, when configuring the wallet. Steps 3 to 6 are executed on every payment that falls under the setting.
Approval Rules
A request is approved when the votes match the setting. Votes are counted by the permission type of the voting user, and approver_master_required decides whether master votes are counted apart.
approver_master_required | How votes are counted | Approval condition |
|---|---|---|
false (or omitted) | single counter — the voter's role is not considered | total votes >= approvers_quantity |
true | two counters — APPROVER and the wallet owner fill the common count, APPROVER_MASTER fills the master count | common votes >= approvers_quantity and master votes >= approver_master_quantity |
Eligibility to vote is the same in both cases — APPROVER, APPROVER_MASTER, and the wallet owner. The flag changes only how the votes are counted.
How a vote is classified:
- user has the
APPROVER_MASTERtag → counted as a master vote - user is the wallet owner → counted as a common vote (
ROOT) - user has the
APPROVERtag → counted as a common vote - none of the above →
403, regardless ofapprover_master_required
Voting is granted to the APPROVER and APPROVER_MASTER permission types only. CLIENT and ADMIN cannot vote even when master approval is not required.
The wallet owner can vote without being assigned APPROVER. The owner's vote counts as common unless the owner also has APPROVER_MASTER, in which case it counts only as a master vote. Each eligible user contributes at most one vote to a request.
Numeric example — setting with approvers_quantity: 2, approver_master_required: true, approver_master_quantity: 1:
| Votes cast | Common | Master | State |
|---|---|---|---|
| 2 approvers | 2 | 0 | PENDING — master vote still missing |
| 1 approver + 1 master | 1 | 1 | PENDING — one common vote still missing |
| 2 approvers + 1 master | 2 | 1 | APPROVED |
Master votes do not count toward approvers_quantity. Size the setting accordingly: the example above needs three distinct voters.
Before enabling the setting, confirm that the wallet has enough distinct eligible voters in each category. Creating the setting does not check whether the wallet currently has enough eligible voters to satisfy it. A successful creation response therefore does not guarantee that requests can receive all required votes. Count an owner with APPROVER_MASTER only toward the master requirement. Without all required votes, a request remains PENDING until canceled or expired. Use the request's state to confirm approval; a 201 vote response alone does not confirm that all required votes were received.
Step 1: List Approval Types
GET /permissions/transaction-approval-types
List the transaction types that support the approval flow. Use it to confirm that the transaction type you want to protect is available.
Optional query params: page, size, sort, order
Returns per item: id, transaction_type_id, transaction_type_tag, description, created_at
Step 2: Create the Approval Setting
POST /permissions/transaction-approval-settings/pix-payment
Create the rule that decides when a Pix payment of this wallet requires approval. Transaction type and currency are fixed by the endpoint — you do not send them.
Only the wallet owner can create or delete a setting. No permission type grants these two endpoints, so an APPROVER, CLIENT, or ADMIN user receives 403.
Required body:
approvers_quantity(integer, 1 to 100)min_amount(BRL cents, positive) → payments from this amount on require approval
Optional body:
approver_master_required(boolean)approver_master_quantity(integer, 1 to 100) → required whenapprover_master_requiredistrue
{
"approvers_quantity": 2,
"min_amount": 100000000,
"approver_master_required": true,
"approver_master_quantity": 1
}
Returns: id, created_at
Important:
approver_master_required = truewithoutapprover_master_quantityis rejected- Only one setting exists per wallet, currency, and transaction type. Creating a second one is rejected
- Settings cannot be edited. To change the quantities, delete the current setting and create a new one
See Approval Rules before choosing the quantities.
Replacing a Setting
DELETE /permissions/transaction-approval-settings/{id}
Settings are immutable — to change the quantities or min_amount, delete the current setting and create a new one. Wallet owner only. The request is rejected while the setting still has PENDING approval requests, so cancel or wait for them first.
Step 3: Decode the Pix Key
POST /pix/payments/decode/by-key
Decode the destination Pix key and save the returned id. The approval request references the decoded key instead of the raw key.
Step 4: Create the Approval Request
POST /permissions/transaction-approval-requests/pix-payment-by-key
Create the approval request for a Pix payment by key. This replaces the direct payment call when the amount falls under an existing setting.
Required body:
decoded_pix_key_id(from Step 3)value(BRL cents, positive)
Optional body:
payment_date(YYYY-MM-DD, today or later)description
Returns: id, render_request_body, state, created_at
Expected initial state: PENDING
Use render_request_body to display the pending payment to the approvers: it carries the payment data in a presentation-ready shape.
Step 5: Approve the Request
POST /permissions/transaction-approvals
Each approver calls this endpoint once. One call is one approval vote.
Required body:
transaction_approval_request_id
Returns: id, created_at
Integration rules:
- Authenticate each vote as the eligible user casting it. Do not use one user's credentials to represent other approvers
- Before voting, have the approver confirm the amount and beneficiary shown in the request's API response
- There is no reject endpoint. To refuse a payment, a user authorized to cancel requests must cancel it (Step 7)
- Only
PENDINGrequests accept votes - When the last required vote arrives, the request moves to
APPROVEDand the payment is released
Step 6: Check the Request State
GET /permissions/transaction-approval-requests/{id}
Source of truth for the current state of the request.
Returns: id, user_name, transaction_approval_setting_id, render_request_body, amount, transaction_type_tag, state, votes, approvers_quantity, created_at
There is no webhook for transaction approvals. Poll this endpoint to follow the request.
| State | Meaning | Action |
|---|---|---|
PENDING | Waiting for the remaining approval votes | Keep polling, or have the missing approvers call Step 5 |
APPROVED | Every required vote was cast | Payment released. Follow it through the Pix payment endpoints |
CANCELED | Canceled by a user of the wallet | Create a new request if the payment is still needed |
EXPIRED | Not approved by the end of the payment date — pending requests expire on the day after their payment_date | Create a new request |
Scheduled payments: expiration is keyed on the payment date, not on the creation date. A request created without payment_date uses the creation date, so it expires the day after it is created. A request scheduled for a future date stays PENDING and keeps accepting votes until the day after that date.
Reading votes: it is the total number of votes cast, master and common together. When approver_master_required is true, votes >= approvers_quantity alone does not mean the request is approved — use state, and GET /permissions/transaction-approvals if you need the breakdown.
Step 7: Cancel the Request
DELETE /permissions/transaction-approval-requests/{id}
Cancel a request that should not be paid. This is how a payment is refused.
Cancellation requires permission for this action in the selected wallet. An authorized caller can cancel a request created by another user of that wallet. The approver role alone does not grant cancellation permission. Only PENDING requests can be canceled.
Returns: id, user_name, transaction_approval_setting_id, render_request_body, amount, transaction_type_tag, state, votes, created_at
Resulting state: CANCELED
Minimal Integration Sequence
GET /permissions/transaction-approval-typesto confirm the transaction type.- Confirm that the wallet users have the required approval and request access permissions (see Prerequisite).
POST /permissions/transaction-approval-settings/pix-paymentand save the returnedid.- On each payment:
POST /pix/payments/decode/by-key, thenPOST /permissions/transaction-approval-requests/pix-payment-by-key. - Each approver calls
POST /permissions/transaction-approvalswith the requestid. - Poll
GET /permissions/transaction-approval-requests/{id}untilAPPROVED,CANCELED, orEXPIRED.
Other Endpoints
GET /permissions/transaction-approval-settings/pix-payment/{id}→ get one settingGET /permissions/transaction-approval-settings/pix-payment→ list settings, filter bycurrency_symbolortransaction_type_tagGET /permissions/transaction-approval-requests→ list requests, filter bystateortransaction_type_tagGET /permissions/transaction-approvals→ list the votes already cast, filter bytransaction_approval_request_id. Each item returnsuser_id,user_name,wallet_id,amount,permission_type_tag,created_at— usepermission_type_tagto tell master votes from common votes
Error Handling
403:
- The authenticated caller lacks permission for the requested action in the selected wallet
- Voting requires an eligible approver; reading and canceling requests require their respective permissions
Request not found:
GET /permissions/transaction-approval-requests/{id}returns200withnullwhen no request is available in the selected wallet- A create, approval or cancellation operation that references a missing request or setting returns
422(TRANSACTION_APPROVAL_REQUEST_NOT_FOUNDorTRANSACTION_APPROVAL_SETTING_NOT_FOUND)
422 on create setting:
approver_master_requiredistrueandapprover_master_quantityis missingapprovers_quantityorapprover_master_quantityoutside 1 to 100
422 on approve:
- The request is not
PENDING— it was already approved, canceled, or expired