Skip to content

Resend campaign to non-openers #78

Description

@JuansesDev

Problem

Time-sensitive broadcasts — Black Friday deadlines, webinar last-call, end-of-trial reminders, important policy changes — frequently lose 10-20% of potential conversions simply because the recipient missed the email in their inbox flood. A common marketing pattern is to re-send the same campaign to subscribers who did not open the first one, with a different subject line, 24-48 hours later. EmailOctopus, Mailchimp, ConvertKit and most marketing tools all support this.

Today SendDock has the underlying signal (open tracking is shipped and reliable) but no UI or API to act on it. A user would have to manually query who opened a broadcast, build a subscriber list from the inverse, and create a new broadcast — too much friction for what should be one click.

This is intentionally lower priority than tags, custom fields, drips, and forms because (a) it is borderline misuse for non-time-sensitive content (mailing the same thing twice annoys recipients and hurts deliverability) and (b) it only has clear value at list sizes large enough that the absolute number of non-openers is meaningful (5k+ subscribers).

Proposal

A "Resend to non-openers" action available on any completed broadcast.

Flow

From a finished broadcast's detail page:

  1. New action button: "Resend to non-openers"
  2. Modal that pre-fills:
    • Recipients: the subset of the original recipient list with opened_at IS NULL at the time of the action (snapshot, not live)
    • Template: same template by default, switchable from the modal
    • Subject override: required field, defaults to "Re: " but the user must change it (subject reuse defeats the purpose and triggers spam filters)
    • Send time: now or schedule
  3. Guardrails:
    • Refuses to resend within 24 hours of the original send (configurable in project settings, default 24h minimum gap)
    • Refuses if the non-opener count is below a threshold (default 100 subscribers — below this, the resend is not worth the deliverability risk)
    • Warning banner if the original campaign's open rate was already high (>30%) — "Most recipients already saw this. Resending may annoy more people than it converts."
  4. The resend is tracked as a child broadcast of the original, with its own analytics row, but linked in the UI so the user can see combined stats.

Data model

No new tables — reuses existing campaigns table with a new nullable column:

ALTER TABLE campaigns ADD COLUMN parent_campaign_id UUID REFERENCES campaigns(id) ON DELETE SET NULL;
ALTER TABLE campaigns ADD COLUMN resend_type VARCHAR(20);  -- 'non_openers' | 'non_clickers' (future)

API

Method Endpoint Description
POST /api/v1/projects/{id}/campaigns/{cid}/resend Create a resend campaign from a finished broadcast. Body: { template_id?, subject, send_at?, type: 'non_openers' }

The endpoint validates the cooldown, computes the non-opener segment server-side at request time, and creates the new campaign in the same queue path as a regular broadcast.

UI

  • Broadcast detail page gains a "Resend to non-openers" button next to the existing actions (shown only when the broadcast status is sent or failed_partial).
  • The combined view shows the parent broadcast's stats with a collapsible row for each resend child.
  • Pre-Pro tier shows the button but with a "Pro feature" lock state that opens the upgrade modal on click.

Acceptance criteria

  • Action button visible on completed broadcasts only
  • Modal pre-fills non-opener subset and forces subject override
  • Cooldown enforced server-side (24h default, configurable per project)
  • Threshold enforced server-side (100 non-openers minimum, configurable)
  • High open-rate warning shown when applicable
  • Resend campaign linked to parent via parent_campaign_id and displayed nested in UI
  • Combined analytics view shows parent + all resends as one funnel

Tier

Pro — value is meaningful only on lists large enough to justify the analytics overhead and the deliverability risk. Pairs naturally with the existing Pro Analytics dashboard, which would gain a "resend lift" metric showing incremental opens / clicks from resends.

Blocked by

Nothing — open tracking and broadcast campaign infrastructure already exist. Can ship independently of other in-flight work.

Metadata

Metadata

Assignees

No one assigned

    Labels

    backendenhancementNew feature or requestfrontendproPro-tier feature (gated by license)roadmapPlanned for a future release

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions