Skip to content

Building Safe AI Workflows with User Approval

Automation is powerful, but some decisions are too important to leave entirely to AI. That's why we built Flow User Approval - a feature that lets you pause automated workflows and get human confirmation before proceeding with critical actions.

The Challenge

You want to automate your business processes, but you're worried about:

  • Irreversible Actions: What if the AI deletes the wrong data?
  • Financial Risk: Can you trust AI to approve large transactions?
  • Compliance: Do regulations require human oversight?
  • User Trust: Will customers feel comfortable with fully automated decisions?

The solution? Human-in-the-Loop workflows that combine AI efficiency with human judgment.

What is Flow User Approval?

Flow User Approval lets you pause a workflow at any point, show users a custom message, and wait for their approval before continuing. Think of it as a safety checkpoint in your automation.

Key Features:

  • ⏸️ Pause execution at critical decision points
  • 💬 Show context-specific approval messages
  • ✅/❌ Branch based on approve/reject decisions
  • 🔄 Resume exactly where you left off
  • 💾 All data and context preserved

Real-World Use Cases

Let's explore how different industries use Flow User Approval to build safer, smarter workflows.


1. E-Commerce: Bulk Inventory Management

Scenario: An e-commerce platform wants to automate inventory cleanup by removing discontinued products, but needs human oversight before bulk deletions.

The Workflow

yaml
Trigger: Admin sends "cleanup discontinued inventory"

1. Query Database
   → Find products marked as discontinued
   → Filter: last_sale_date > 180 days ago
   → Output: {{products}} (array of 47 items)

2. User Approval Step
   Message: "Delete {{products.length}} discontinued products? 
            This will permanently remove them from inventory.
            Products include: {{products[0].name}}, {{products[1].name}}..."

   ├─ ✅ APPROVED
   │   ↓
   │   3. Execute Deletion Loop
   │      → For each product in {{products}}
   │      → Delete from inventory
   │      → Archive order history
   │      → Update analytics
   │   ↓
   │   4. Generate Report
   │      → Deleted: {{deletedCount}} items
   │      → Recovered space: {{totalSize}} GB
   │      → Estimated savings: ${{savings}}/month
   │   ↓
   │   5. Final: "✅ Successfully deleted 47 discontinued products. 
   │              Report sent to your email."

   └─ ❌ REJECTED

       Final: "❌ Deletion cancelled. Products remain in inventory."

User Experience

In the chat:

AI: I found 47 discontinued products that haven't sold in 6+ months.

┌──────────────────────────────────────────────┐
│ Delete 47 discontinued products?             │
│ This will permanently remove them from       │
│ inventory.                                   │
│                                              │
│ Top items:                                   │
│ • Vintage Phone Case (last sale: 201 days)  │
│ • Retro Headphones (last sale: 245 days)    │
│ • Old Charger Model (last sale: 189 days)   │
│                                              │
│   [✅ Approve]    [❌ Reject]                │
└──────────────────────────────────────────────┘

User clicks "Approve"

AI: ✅ Processing deletion...
    Deleted 47 items
    Recovered 2.3 GB storage space
    Estimated monthly savings: $185

    Full report sent to admin@store.com

Why This Works

  • Context is Clear: Shows exactly what will be deleted
  • Reversibility: Admin can reject if they spot important items
  • Audit Trail: All approvals are logged for compliance
  • Efficiency: AI does the analysis, human makes final call

2. Finance: Large Transaction Approval

Scenario: A fintech app automates bill payments, but requires approval for transactions over $1,000.

The Workflow

yaml
Trigger: Bill payment due date approaching

1. Fetch Bill Details
   → bill_id: {{billId}}
   → amount: {{amount}}
   → vendor: {{vendorName}}
   → due_date: {{dueDate}}

2. Condition: Check Amount
   If {{amount}} > 1000:

       3. User Approval Step
          Message: "Approve payment of ${{amount}} to {{vendorName}}?
                   Due date: {{dueDate}}
                   Account: {{accountLast4}}
                   Remaining balance after: ${{balanceAfter}}"

           ├─ ✅ APPROVED
           │   ↓
           │   4. Process Payment
           │   5. Send Confirmation
           │   6. Final: "✅ Payment of ${{amount}} processed successfully."

           └─ ❌ REJECTED

               7. Schedule Reminder
               8. Final: "⏰ Payment postponed. Reminder set for tomorrow."
   Else:

       Auto-process payment (no approval needed)

User Experience

Mobile notification:

💰 Payment Approval Required

Approve payment of $1,250.00 to 
Electric Company?

Due: Oct 25, 2025
Account: •••• 4532
Balance after: $3,140.89

[Approve] [Reject]

After approval:

✅ Payment Processed

$1,250.00 sent to Electric Company
Transaction ID: TXN-7839283
Receipt emailed to you

Why This Works

  • Risk Management: High-value transactions require human approval
  • Flexibility: Low-value payments auto-process for convenience
  • Transparency: Shows account balance impact before approval
  • Peace of Mind: Users control their money

3. Healthcare: Patient Data Access

Scenario: A healthcare system automates report generation but requires approval before sharing sensitive patient data externally.

The Workflow

yaml
Trigger: Doctor requests patient report for specialist

1. Gather Patient Data
   → Medical history
   → Recent test results
   → Current medications
   → Privacy flags

2. Generate Report
   → Format as PDF
   → Anonymize where required
   → Include relevant data only

3. User Approval Step
   Message: "Share medical report for Patient {{patientId}} with 
            Dr. {{specialistName}} at {{institution}}?
            
            Report includes:
            • Medical history (5 years)
            • Lab results (3 recent tests)
            • Current medications (4 items)
            
            Patient consent: {{consentStatus}}"

    ├─ ✅ APPROVED
    │   ↓
    │   4. Log Access
    │   5. Send Secure Email
    │   6. Notify Patient
    │   7. Final: "✅ Report shared securely. Patient notified."

    └─ ❌ REJECTED

        8. Log Rejection
        9. Final: "❌ Report sharing cancelled. Requesting physician notified."

User Experience

Doctor's dashboard:

┌────────────────────────────────────────────┐
│ Share Patient Medical Report?              │
│                                            │
│ Patient: PT-00289413                       │
│ Specialist: Dr. Sarah Chen                 │
│ Institution: Metro Cardiology Center       │
│                                            │
│ Report Contents:                           │
│ ✓ Medical history (past 5 years)          │
│ ✓ Recent lab results (3 tests)            │
│ ✓ Current medications (4 prescriptions)   │
│                                            │
│ Patient Consent: ✅ On File (valid)       │
│ HIPAA Compliance: ✅ Verified             │
│                                            │
│   [Approve & Share]    [Cancel]           │
└────────────────────────────────────────────┘

Why This Works

  • HIPAA Compliance: Human verification required for data sharing
  • Patient Privacy: Doctor confirms data is appropriate to share
  • Audit Trail: Complete log of who approved what and when
  • Informed Decisions: Shows consent status and compliance checks

4. Marketing: Campaign Launch

Scenario: A marketing team automates email campaigns but requires approval before sending to large audiences.

The Workflow

yaml
Trigger: Campaign scheduled for sending

1. Validate Campaign
   → Check email template
   → Verify recipient list
   → Test send to team
   → Calculate metrics

2. Generate Preview
   → Subject: {{subject}}
   → Recipients: {{recipientCount}}
   → Segments: {{segments}}
   → Expected open rate: {{expectedOpenRate}}%

3. Condition: Check List Size
   If {{recipientCount}} > 1000:

       4. User Approval Step
          Message: "Launch email campaign '{{campaignName}}'?
                   
                   Recipients: {{recipientCount}} contacts
                   Subject: {{subject}}
                   
                   Preview: {{previewLink}}
                   
                   Estimated metrics:
                   • Open rate: {{expectedOpenRate}}%
                   • Click rate: {{expectedClickRate}}%
                   • Cost: ${{estimatedCost}}"

           ├─ ✅ APPROVED
           │   ↓
           │   5. Send Campaign
           │   6. Start Tracking
           │   7. Final: "✅ Campaign launched to {{recipientCount}} recipients.
           │              Live dashboard: {{dashboardUrl}}"

           └─ ❌ REJECTED

               8. Save Draft
               9. Final: "📝 Campaign saved as draft for editing."
   Else:

       Auto-launch (test campaigns)

User Experience

Marketing Manager's approval:

🚀 Campaign Ready to Launch

Campaign: "Summer Sale 2025"
Recipients: 45,280 subscribers
Subject: "☀️ 50% Off Everything - Last Chance!"

Preview Email: [Click to view]

Expected Performance:
📊 Open Rate: 24.5% (~11,093 opens)
🖱️ Click Rate: 3.8% (~1,720 clicks)
💰 Est. Revenue: $34,200
🏷️ Cost: $226 (email credits)

ROI: 151x

[Launch Campaign] [Save as Draft]

After approval:

✅ Campaign Launched!

Sending to 45,280 recipients...
⏱️ Estimated completion: 25 minutes

Real-time dashboard: app.cognipeer.com/campaigns/summer-2025

You'll receive updates at key milestones:
• 25% sent
• 50% sent  
• 100% sent
• 1 hour metrics
• 24 hour metrics

Why This Works

  • Risk Mitigation: Prevents expensive mistakes (wrong subject, broken links)
  • Quality Control: Team can preview before mass send
  • Cost Awareness: Shows exact costs before committing
  • Performance Insight: Sets expectations with predicted metrics

5. DevOps: Database Migrations

Scenario: A DevOps team automates database migrations but requires approval before running on production.

The Workflow

yaml
Trigger: Developer merges migration PR

1. Analyze Migration
   → Detect schema changes
   → Estimate affected rows
   → Calculate downtime
   → Run on staging

2. Staging Validation
   → Execute migration on staging
   → Run test suite
   → Check performance impact

3. Generate Report
   → Changes: {{changes}}
   → Affected rows: {{affectedRows}}
   → Estimated time: {{estimatedTime}}
   → Rollback plan: {{rollbackSteps}}

4. User Approval Step
   Message: "Run migration on PRODUCTION?
            
            Migration: {{migrationName}}
            Changes: {{changes}}
            
            Impact:
            • Affected tables: {{tableCount}}
            • Estimated rows: {{affectedRows}}
            • Estimated time: {{estimatedTime}}
            • Downtime: {{downtimeRequired}}
            
            Staging: ✅ Passed all tests
            
            Rollback: {{rollbackPlan}}"

    ├─ ✅ APPROVED
    │   ↓
    │   5. Enable Maintenance Mode
    │   6. Backup Database
    │   7. Run Migration
    │   8. Validate Data
    │   9. Disable Maintenance Mode
    │   10. Final: "✅ Migration completed successfully.
    │               Affected {{affectedRows}} rows in {{actualTime}}.
    │               All systems operational."

    └─ ❌ REJECTED

        11. Notify Team
        12. Final: "⏸️ Migration postponed. Team notified."

User Experience

DevOps Slack channel:

🔧 Production Migration Approval Required

Migration: add_user_preferences_table
Author: @john.dev
PR: #1543

Impact Analysis:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📊 Tables: 3 affected
📈 Est. Rows: ~1.2M
⏱️ Est. Time: 3-5 minutes
⚠️ Downtime: None (online migration)

Staging Results:
✅ All tests passed (124/124)
✅ Performance: +0.2ms avg query time
✅ No conflicts detected

Rollback Plan:
→ Drop new table
→ Restore from backup
→ Est. rollback time: 1 minute

[Approve & Run] [Postpone]

After approval:

✅ Migration In Progress

⏳ Step 1/5: Backing up database... ✓
⏳ Step 2/5: Creating new table... ✓
⏳ Step 3/5: Migrating data... ⏳ (45%)

Live progress: devops.cognipeer.com/migrations/1543

Why This Works

  • Safety: Prevents accidental production changes
  • Visibility: Team sees exactly what will change
  • Confidence: Staging tests prove migration works
  • Quick Rollback: Clear plan if something goes wrong

Implementation Guide

Basic Setup (5 minutes)

1. Add User Approval Step to Your Flow

In the Flow Editor:

  1. Click "Add Step"
  2. Select "User Approval" from Workflow category
  3. Configure your message:
Approve payment of ${{amount}} to {{vendor}}?

This will be charged to card ending in {{cardLast4}}.
  1. Connect the approve/reject paths

2. Test Your Flow

Send a test message and verify:

  • ✅ Flow pauses at approval step
  • ✅ Approval message displays correctly
  • ✅ Buttons work (approve/reject)
  • ✅ Flow continues after decision
  • ✅ Correct path is taken

Advanced Patterns

Multi-Level Approval

yaml
Expense Request

User Approval 1: "Manager Approval Required"
    ├─ Approved → Amount > $5000?
    │               ├─ Yes → User Approval 2: "Director Approval Required"
    │               │           ├─ Approved → Process
    │               │           └─ Rejected → Deny
    │               └─ No → Process
    └─ Rejected → Deny

Conditional Approval

yaml
Calculate Risk Score

If risk > 7:
    User Approval: "High risk transaction detected!"
Else:
    Auto-approve

Approval with Timeout

yaml
User Approval: "Approve within 24 hours?"

External cron job:
    If no response after 24h → Auto-reject

Best Practices

✅ Do's

1. Be Specific

❌ "Approve action?"
✅ "Delete 47 products permanently?"

2. Show Context

❌ "Continue?"
✅ "Send email to 1,250 customers with subject 'Sale Alert'?"

3. State Consequences

❌ "Proceed?"
✅ "Charge $1,250 to card ending in 4532? This cannot be undone."

4. Use Variables

✅ "Delete {{count}} items from {{category}}? 
   Estimated storage saved: {{storageGB}} GB"

❌ Don'ts

1. Don't Overuse

❌ Too many approvals = friction
✅ Only critical actions need approval

2. Don't Be Vague

❌ "Approve?"
❌ "Are you sure?"
❌ "Continue processing?"

3. Don't Block Simple Actions

❌ Approval for reading data
✅ Approval for deleting data

Technical Details

State Preservation

When a flow pauses for approval:

  • Full execution context saved to database
  • All variables preserved
  • Loop positions maintained
  • Message status: pending_approval

Average state size: 5-50 KB Resume time: < 500ms

API Integration

For custom implementations:

javascript
// Resume with approval
await fetch('/api/v1/peer/message/:messageId/resume', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ decision: 'approve' })
});

WebChat Integration

Approval UI automatically appears in WebChat:

html
<div class="approval-box">
  <p class="message">{{approvalMessage}}</p>
  <button onclick="approve()">Approve</button>
  <button onclick="reject()">Reject</button>
</div>

Metrics & Analytics

Track approval effectiveness:

Approval Rate:

Approved / Total Requests

Average Decision Time:

Time from pause to decision

Rejection Patterns:

What gets rejected most often?
→ Improve AI accuracy

Real Results

E-Commerce Platform

  • Before: Manual inventory review took 4 hours/week
  • After: AI analysis + 2-minute approval = 95% time saved
  • Benefit: Focus on strategy instead of data entry

Fintech App

  • Before: All payments required manual review
  • After: Only high-value transactions need approval
  • Benefit: 10x faster payment processing

Healthcare System

  • Before: Paper forms for data sharing
  • After: Digital approval with audit trail
  • Benefit: HIPAA compliance + 80% faster

Conclusion

Flow User Approval gives you the best of both worlds:

  • AI Efficiency: Automate the analysis and preparation
  • Human Judgment: Make final decisions on critical actions
  • Safety: Prevent costly mistakes
  • Compliance: Meet regulatory requirements
  • Trust: Users stay in control

Getting Started

  1. Identify Critical Actions in your workflows
  2. Add User Approval Steps before those actions
  3. Test Both Paths (approve and reject)
  4. Monitor Metrics and optimize

Learn More

Try It Today

User Approval is available now for all Cognipeer users. Start building safer, smarter workflows today!


Have questions? Join our community forum or contact support.

Built something cool? Share your approval workflow on Twitter with #CognipeerWorkflows!

Built with VitePress