Campaign Approval Workflow Before Scheduled Execution
Author: galeiroCreated Sep 8, 2026Updated Sep 8, 2026
Labelsquestion
Problem Statement
Currently, after a campaign is scheduled by an operator, it will run automatically at the scheduled time without any review or approval step. This creates a quality risk and responsibility gap, especially in teams with this structure:
- Operator/Intern: creates and schedules the campaign
- Manager/QA: accountable for campaign content quality and results
There is no mechanism to ensure a campaign passes quality gates before publication.
Proposed Solution
Add a Campaign Approval Workflow feature with the following specifications:
Campaign Status Enhancement
- Add new status:
pending_approval(in addition to existing: draft, scheduled, running, completed) - When an operator schedules a campaign, status changes to
pending_approvalinstead of directly toscheduled
- Add new status:
Approval Role & Permission
- Add new permission:
campaigns.approve - Users with specific roles (e.g., Manager/Admin) can approve or reject campaigns
- Multiple users can approve based on assigned role
- Add new permission:
Approval Interface
- In campaign detail view, add "Approval Status" section:
- Approve button (changes status to
scheduled, campaign runs at scheduled time) - Reject button (reverts to
draft, operator can revise and resubmit) - Optional reason/notes field for approval or rejection
- Audit trail: who approved/rejected, when, and reason
- Approve button (changes status to
- In campaign detail view, add "Approval Status" section:
Optional Flow Toggle
- Add setting at campaign type or global level:
require_approval(true/false) - If
false, approval workflow is skipped (current behavior — schedule runs immediately) - This makes the feature opt-in and backward compatible
- Add setting at campaign type or global level:
Notification
- Email or in-app notification to approvers when a campaign is pending approval
- Notification to operator when campaign is approved or rejected
Acceptance Criteria
- Campaign approval status is visible in campaign list and detail view
- Users with
campaigns.approvepermission can approve/reject pending campaigns - Approved campaigns run at scheduled time; rejected campaigns revert to draft
- Audit log records who approved/rejected, timestamp, and reason
- Approval requirement can be toggled per campaign or globally
- Notifications are sent to approver and operator
- Existing campaigns and workflows are unaffected (backward compatible)
Use Case
- An intern/operator creates a campaign "Summer Promo" and schedules it for Friday at 10 AM
- Campaign status →
pending_approval - Manager receives notification "Campaign pending approval"
- Manager reviews the campaign (subject, content, recipient list) in the dashboard
- Manager Approves → campaign status →
scheduled, campaign runs Friday at 10 AM- Or Rejects with reason "Typo in subject line" → campaign reverts to draft, operator revises and resubmits
Implementation Considerations
- Approval workflow could be enforced per campaign template or campaign type
- Could be extended to scheduled list imports, template approval, etc. (future enhancement)
- Consider webhook/API integration for approval automation (future)
- Minimal storage overhead for audit trail; scheduler logic needs update to check approval status before execution
Related Issues
- Reference #2327 (subscriber approval workflow) — similar concept, different scope
Contribution Intent
I am interested in implementing this feature and would like to contribute to this project. Before I start development, I would appreciate feedback on:
- Design Approval: Is the proposed approach (status workflow, permission structure, notification flow) aligned with Listmonk's architecture?
- Implementation Approach: Any specific patterns or libraries I should follow? (e.g., for audit logging, permission checking)
- Database Schema: Should I prepare a migration approach for backward compatibility?
- Timeline: Any constraints or priorities that would affect development?
I'm ready to open a draft PR for discussion once there's feedback on the design.
Source: knadh/listmonk