require_approval rule holds a matching transaction in pending_authorization until enough approvers approve it. The transaction is persisted and its funds are locked while it waits. Once approved, it signs and broadcasts without being resubmitted.
This guide builds a tiered approval policy for a treasury team:
Choose your approvers
List approver candidates returns every user and role you can name. Each entry’sid and type go into the rule’s approvers list.
- Roles (
"type": "role") cover everyone who holds the role at the time a transaction is held.member_countshows how many people that is now. Prefer roles. - Users (
"type": "user") name one person. Use them only when a specific person must sign off, and plan for that person being away.
Write the rules
Rules run in order and the first match wins, so order them from most to least restrictive. The sweep rule comes first so automated internal moves never wait for a person.approvers and required_approvals are both required. Saving the draft rejects a rule without them, or with an unknown key. The values destination_type takes aren’t listed in the API reference: dry-run a real transfer between your own vaults and check the value in failed_condition.actual.Test each tier
Dry-run one request per row of the table, against the draft. Each should stop at the rule you expect.
The fourth row is worth checking closely: the sweep rule is above the block rule, so it lets a $300,000 automated sweep through. If that isn’t what you want, add an
amount_usd cap to the sweep rule.
When every row matches, validate the stored draft and activate it.
What approvers see
When a transfer is held, the dry-run fieldsrequired_approvals and expiry_hours describe the approval request it opens. Approvals expire after 24 hours by default. Approvers act on the request in the Bitnob dashboard. The transaction then moves on:
- Approved: it continues to signing and broadcast, and you receive
transaction.signedand thentransaction.completedas normal. - Rejected: its status becomes
rejected, which is terminal. Nothing is signed or broadcast. - Expired: the request lapses without enough approvals, and the transaction does not execute.