Skip to main content
Once a policy is enforced, Create transaction no longer always means “sent”. Your integration has to handle three outcomes: the transfer goes ahead, it is held, or it is blocked.

Branch on the response

In both 202 cases the transaction is persisted and its funds are locked. It executes on its own once approved or once the time lock expires.
Never resubmit a held transaction to “unstick” it. A second Create transaction with a new idempotency key creates a second transfer, which is held or sent on its own. Use the same Idempotency-Key for retries after network errors, as described in Making requests.

Track held transactions to the end

A held transaction can stay non-terminal for hours. Track it the same way as any other transaction, through webhooks first and polling as a fallback:
  • Subscribe to transaction.signed, transaction.completed, transaction.failed, and transaction.cancelled. A held transaction that is approved, or whose time lock expires, emits transaction.signed and then follows the normal path.
  • Subscribe to policy.violation, sent when a block rule blocks a transaction, and policy.alert, sent when an alert rule matches.
  • Poll Get transaction for anything still non-terminal after your expected window, and stop at a terminal status: completed, failed, cancelled, or rejected.
rejected means an approver turned the transfer down. It is terminal. Return the funds to the customer’s balance in your ledger and tell them. Webhooks covers signature verification, and Best practices covers reconciling missed events.

Tell customers the truth

Map each status to something a customer can act on. Don’t show a held transfer as “sent”. Don’t expose rule names or thresholds to customers. They describe your controls, and showing them helps someone find the amount just below a limit.

Reconcile ledger balances

Treat the funds of a held transaction as reserved. Debit the customer’s available balance when Create transaction returns 201 or 202. Release the reservation only on failed, cancelled, or rejected. This prevents a customer from spending the same balance twice while an approval is pending.