Approval flow
When approval is triggered
Section titled “When approval is triggered”Any payout where the policy engine returns require_approval triggers this flow — the request does not fail, and it does not block. POST /v1/withdraws / request_payout return right away with status: "pending_approval".
-
Agent calls
request_payout(MCP) orPOST /v1/withdraws(REST) with an amount/destination that trips one of the threshold rules. -
nuez creates the payout attempt (
status: "pending_approval") and anapprovalrecord with a 6-character challenge token and an expiry (ApprovalExpiryMinutes, default 5 minutes). The call returns immediately:{"id": "b3f1...","status": "pending_approval","decision": "require_approval","reasons": ["per_tx_limit"],"approval_id": "9a02...","expires_in": 300} -
A notification is sent to whichever channel the user has linked — WhatsApp or Telegram. It includes the amount, destination, and Approve/Reject buttons (or plain-text instructions).
-
The owner replies. Buttons send a fixed string; plain text also works if typed manually:
APPROVE:XXXXXXorA-XXXXXX→ approveREJECT:XXXXXXorR-XXXXXX→ reject
(
XXXXXXis the 6-character challenge token from step 2.) nuez’s WhatsApp/Telegram integration receives the reply and resolves the approval. -
If approved: the payout attempt moves to
approved, then nuez submits it to the bank rail (submitted, laterconfirmed). Webhooks fire in order:payout.approved→payout.submitted→payout.confirmed.If rejected: the payout attempt moves to
rejectedand apayout.rejectedwebhook fires. There is no error response to catch — you find out by polling or by webhook.
Timeout behavior
Section titled “Timeout behavior”If no reply arrives within the expiry window, a background worker (polling every WORKER_INTERVAL_SECONDS, default 30s) marks the approval expired and the payout attempt expired, firing a payout.expired webhook. There’s no automatic retry — the agent has to call request_payout again with a fresh idempotency_key if it wants to retry.
Checking status
Section titled “Checking status”Since neither call blocks, poll for resolution:
- MCP:
get_payout_statuswith thepayout_id - REST:
GET /v1/withdraws/{id}
or just listen for the webhook — see Webhooks for the full event list.
Testing the approval flow
Section titled “Testing the approval flow”Set a low require_approval_above_ars via PUT /v1/thresholds (or the propose_threshold_change tool, which itself always requires a WhatsApp confirmation) against the sandbox environment. Every payout above that amount will trigger the flow without moving real money.