External Approval Channels
This guide walks through setting up approval notifications so your team can approve or reject payments from wherever they already work. This is the setup walkthrough. For the concepts (when to use approval workflows, trigger conditions, patterns), see Approval workflows. For the channel API reference (endpoints, request shapes), see Notification channels.Prerequisites
What You’ll Build
By the end of this guide, your approval flow will look like this:Step 1: Set Up an Approval Workflow
If you haven’t already, create an approval workflow that triggers on the conditions you care about.Create the workflow
Go to Policies in the dashboard. Create a new Approval Workflow with:
| Field | Example Value |
|---|---|
| Name | Large Payment Review |
| Amount Threshold | $100 |
| Required Approvals | 1 |
| Timeout | 24 hours |
| Approver Roles | OWNER, ADMIN |
Verify it triggers
Request a payment above your threshold and confirm it enters
PENDING_APPROVAL status.
SDK payment requests and external-wallet /api/sdk/payments/approve calls with a matching
workflow also return an approvalRequestId, which is handy when you are testing external
verifier flows end to end.Step 2: Add a Notification Channel
Configure the channel
Fill in the platform-specific fields.For Slack:
- Bot Token:
xoxb-...(from your Slack app) - Channel ID:
C0123456789
- Recipients:
cfo@company.com, finance@company.com
- Bot Token: from @BotFather
- Chat ID: your group chat ID
Select events
At minimum, enable
approval.requested. Consider also enabling:approval.escalatedfor time-sensitive visibilityapproval.expiredso nothing falls through the crackspayment.executedonWEBHOOKchannels if your verifier needs to mark invoices as paid
Step 3: Test the Full Flow
Trigger a payment that needs approval
Use the SDK or dashboard to request a payment above your approval threshold.
Check your channel
Within a few seconds, you should receive a notification on your configured channel with payment details and Approve/Reject buttons.
Approve or reject
Complete the approval from the email confirmation page or the Conto dashboard. The payment should move to
APPROVED status and execute automatically if you are using Conto-managed wallets.Multiple Channels
You can configure multiple channels simultaneously. When an approval request is created, notifications are sent to all active channels that subscribe to theapproval.requested event. The first approver to act from any channel resolves the request.
Each channel delivers independently via background jobs. If one channel fails (e.g., Slack API is
down), other channels still deliver. Failed deliveries retry up to 3 times with exponential
backoff.
Webhook Integration for Custom Systems
If you already have your own approval system, use the Webhook channel type to receive approval requests and hand the final decision off to an authenticated Conto approver.Attaching verification metadata
Programmatic approvers can optionally attach averification {} block to the
decision call. Conto persists it on the approval decision and the associated
DeltaVerification record when the consumed token was issued for the
WEBHOOK channel. This is the seam used by the Delta Mandate pilot to
return its proof reference alongside the APPROVE/REJECT decision.
verification block is strict: only the documented keys are accepted;
unknown keys cause a 400. proofType accepts delta_signed (signed JSON
receipt) or delta_mandate_sp1 (SP1 zk proof).
Preferred service-to-service callback
For long-running automated verifiers, prefer the HMAC-authenticated internal decision endpoint instead of the token callback. It uses the samesecret
configured on the Delta webhook channel and signs the exact string
${X-Conto-Timestamp}.${rawBody} with HMAC-SHA256.
/api/approvals/action flow remains available for demos, email-style click
throughs, and simple webhook integrations.
For SDK-driven payment requests and external-wallet /api/sdk/payments/approve
calls, Conto automatically opens the approval request when a workflow matches
and returns the resulting approvalRequestId in the initial API response. That
ID is the same one used in the callback route above.
Troubleshooting
Notifications not arriving
Notifications not arriving
- Check that the channel is active (toggle is on) in Settings > Channels
- Check the
lastErrorfield on the channel for API errors - Verify your bot token or credentials are correct
- For Slack, confirm the bot is invited to the target channel
- For Telegram, confirm the webhook URL is set correctly
Token expired or already used
Token expired or already used
Action tokens are one-time use and expire with the approval request. If the approval request has already been resolved (by another approver or from the dashboard), the token is no longer valid.
Slack buttons not working
Slack buttons not working
Next Steps
Channel Reference
Full configuration reference for all channel types
Policy Testing
Test your approval workflows before going to production