#3220·listmonk

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:

  1. 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_approval instead of directly to scheduled
  2. 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
  3. 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
  4. 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
  5. 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.approve permission 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

  1. An intern/operator creates a campaign "Summer Promo" and schedules it for Friday at 10 AM
  2. Campaign status → pending_approval
  3. Manager receives notification "Campaign pending approval"
  4. Manager reviews the campaign (subject, content, recipient list) in the dashboard
  5. 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:

  1. Design Approval: Is the proposed approach (status workflow, permission structure, notification flow) aligned with Listmonk's architecture?
  2. Implementation Approach: Any specific patterns or libraries I should follow? (e.g., for audit logging, permission checking)
  3. Database Schema: Should I prepare a migration approach for backward compatibility?
  4. 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.