Human approval for agent payments with Slack
Caps decide what an AI agent may pay on its own. Some payments should still wait for a person: the first call to a new seller, a dataset that costs dollars instead of cents, anything above what you would let a script spend unattended. This guide sets up step-up approval in Burnbound: payments at or above a USD threshold wait for a human, you get a Slack message, and the agent continues once you approve, without being charged twice.
How an approval works
- The agent calls
fetch_paid. The seller's price is allowed by every rule, but it is at or above the agent's approval threshold. - Nothing is signed.
fetch_paidreturnsstatus: "pending_approval"with anapprovalId, theamountUsd, thethresholdUsd, thehostand anidempotencyKey. - Burnbound posts a message to your Slack channel and, if you turned it on, emails the organization's owners.
- A human opens the payment in the dashboard's approvals inbox (amount, host, payee, network) and approves or denies it.
- The agent polls
get_approval_statuswith theapprovalId. Once it isapproved, it callsfetch_paidagain with the sameurl,method,headers,bodyandidempotencyKey, and the payment is signed and sent.
The idempotency key ties the retry to the approved purchase. A retry with the same key never creates a second payment; a different request with that key fails with idempotency_key_reused.
Step 1: Turn on step-up approval for the agent
Open the agent in the dashboard, go to its Política (policy) tab, turn on step-up approval and set the threshold in USD. Save. The change creates a new policy version and applies to the agent's next payment.
Pick the threshold from what the agent normally buys. If it pays Exa search at 0.007 USDC or CoinGecko at 0.01 USDC per call, a threshold of 0.25 USD lets routine calls through and stops anything unusual. Prices of other sellers are in the x402 API catalog.
The threshold is checked after every other rule. A payment over the maximum per payment or the daily cap is denied outright; it is never sent for approval. So the order is: rules first, then the human, then the signature.
Step 2: Create a Slack incoming webhook
Burnbound notifies Slack through an incoming webhook, which posts to one channel. In Slack (official guide):
- Create a Slack app at api.slack.com/apps in your workspace.
- Open Incoming Webhooks and turn on Activate Incoming Webhooks.
- Click Add New Webhook to Workspace, choose the channel and authorize.
- Copy the webhook URL. It starts with
https://hooks.slack.com/services/.
Treat the URL as a secret: anyone who has it can post to that channel.
Step 3: Add the webhook in Burnbound
In the dashboard, open Ajustes (settings) → Avisos de aprobación (approval notifications). Only an owner of the organization can change it.
- Paste the webhook URL and save it. Burnbound accepts only
https://hooks.slack.com/services/…URLs, stores the URL encrypted and never shows it again (only its last characters). - Click Enviar prueba (send test) and check that the test message reaches the channel.
- Optionally, turn on email to the organization's owners.
Slack and email notifications are part of the Pro plan, and Pro is free during the beta. The approvals inbox itself works on every plan, so on Free you can still approve payments; you just open the dashboard to see them.
What the Slack message contains
Each pending payment posts one message with:
- the amount and the threshold, for example
Approval needed: 0.50 USD (threshold 0.25 USD); - the host and the resource the seller named;
- when the approval expires;
- an Open in dashboard button.
There is no approve button in Slack, on purpose. Approving spends money, so it happens in the dashboard, signed in, where you can see the payee and the network. The host and resource come from the seller, so they are shown as plain text: a seller cannot format or link anything in your channel. Notifications are rate limited per organization (20 Slack messages and 10 emails per hour); a payment never notifies twice.
Step 4: Let the agent wait and retry
Most agents handle pending_approval on their own when the tool result explains it, but a line in your instructions makes it reliable:
If fetch_paid returns pending_approval, tell me the amount and host, then poll
get_approval_status every 30 seconds. When it is approved, call fetch_paid again
with exactly the same url, method, headers, body and idempotencyKey. If it is
denied or expired, do not retry.
get_approval_status returns pending, approved, denied or expired, plus intentId once the approved payment was made. An agent key only sees its own agent's approvals.
Timeouts and limits
| What | Value |
|---|---|
| A pending approval expires after | 15 minutes by default. An owner can set 5 minutes to 24 hours in the same settings. |
| After approval, the agent must retry | Within 10 minutes. |
| Pending approvals at once | 5 per agent and 20 per organization. Past that: approval_queue_full. |
| A denied approval | approval_denied on retry. Do not retry it. |
| An expired approval | approval_expired. Call fetch_paid without idempotencyKey to ask again. |
Try it on Base Sepolia
With an agent on Base Sepolia and demo.burnbound.dev in its allowed hosts, set the threshold to 0.50 USD and ask the agent to fetch https://demo.burnbound.dev/report, which costs 0.50 test USDC. You get pending_approval, a Slack message and an entry in the inbox. Approve it and the agent's retry is paid. The demo seller only sells on Base Sepolia, for test USDC with no value.
Related
- Every limit that applies before the approval: How to limit an AI agent's spending.
- The approval flow in reference form: Concepts.
- New to Burnbound? Start with the Quickstart.