Skip to Content
CampaignsCampaigns

Campaigns

This folder documents the Campaigns section of Leadmetrics — a unified hub for planning, executing, and measuring marketing campaigns across all channels.

Related: Workflow Model — how campaigns link to Strategy → Deliverables → Activities | Channels — connected channel integrations | Agents — AI workers used in campaign generation

Contents


Overview

Campaigns is a first-class section of the Leadmetrics platform. It provides a unified hub with channel-specific detail views for managing all marketing campaigns — paid ads, email marketing, social media, SEO outreach, and review generation.

Design principles:

  • Unified model: One Campaign entity with type and channel[] fields rather than separate tables per campaign type. Channel-specific behaviour surfaces in the detail views.
  • AI-assisted at every stage: Agents help generate briefs, write copy, suggest audiences, and recommend optimisations. Every AI action is gated behind human approval.
  • DM creates, client approves: The DM team manages the full campaign lifecycle. Clients are brought in at the client_review stage to approve before launch.
  • Optional workflow integration: Campaigns can exist standalone or be linked to a DeliverablePeriod so they appear in the monthly deliverables plan.
  • Double-approval for auto-pilot: When auto-pilot is enabled for paid ads campaigns, every AI-initiated optimisation batch still requires DM + client approval before executing on the platform.
  • Import or create: Paid ads campaigns can be imported from a connected platform (Google Ads, Meta Ads, LinkedIn Ads) or created in Leadmetrics first. Either way, metrics are synced back per campaign once a CampaignExternalMapping is established.

Campaign Types

TypeChannelsPrimary AI Workers
paid_adsGoogle Ads, Meta Ads, LinkedIn Adsgoogle-ads-writer, meta-ads-writer, linkedin-ads-writer, ads-analyst
email_marketingMailchimp, Klaviyoemail-writer, campaign-brief-writer
social_mediaFacebook, Instagram, LinkedIn, X, TikToksocial-post-writer, social-post-designer, campaign-brief-writer
seo_outreachEmail (backlink outreach)backlink-outreach-writer
review_generationEmail, SMS (GBP review drip)review-campaign-writer

Existing Foundations

The following are already built and will be reused or extended:

  • Models: Campaign + CampaignEmail (currently backlink-outreach only) — to be generalised
  • Workers: google-ads-writer, meta-ads-writer, ads-analyst, google-ads-insights, meta-ads-insights, email-writer, backlink-outreach-writer
  • Channel integrations: Google Ads, Meta Ads, LinkedIn Ads, Facebook, Instagram, LinkedIn, GBP (all via ConnectedChannel)
  • Platform API wrappers: getCampaignsAsLookup() (Google Ads) and getMetaCampaignPerformanceSummary() (Meta) already exist in the provider packages — used by Flow A and Flow B
  • Workflow pattern: dm_review → dm_approved → client_review → client_approved — same as blog/social
  • DM portal: Existing campaign routes at GET/PATCH /dm/v1/campaigns — to be aligned with the new unified model

Open Questions

  1. Activity FK: Should Activity gain a campaignId FK to link generated content back to the campaign?ResolvedActivity.campaignId FK added (model #7 in data-model.md).
  2. Credits / quota: Should campaign content generation draw from the existing deliverable-period quota, or should campaigns have a separate credit budget tracked at the campaign level?
  3. Notifications: Should status transitions trigger in-app + email notifications to relevant users?Resolved — notification triggers are fully spec’d in workflow.md.
  4. Scheduled sync frequency: How often should the daily metrics sync run for active paid_ads campaigns? (Suggested: once per day at midnight tenant-local time, or a fixed UTC schedule.)
  5. LinkedIn Ads metrics: Does the LinkedIn Ads provider need new methods for per-campaign metrics?Resolved — new packages/providers/linkedin/src/linkedin-ads.ts provider file spec’d in api.md.

Out of Scope (v1)

  • SMS infrastructure (beyond review drip trigger)
  • WhatsApp campaigns
  • TikTok Ads
  • Native A/B test framework (variants are written by the agent but split-testing infrastructure is deferred)
  • In-app SMTP (email sending continues via Mailchimp / Klaviyo)

Future Work (Post-v1 Backlog)

Identified gaps to be specced and built after v1. Grouped by priority.

High Priority

UTM Parameter Management Every campaign URL should have auto-generated UTM parameters (utm_source, utm_medium, utm_campaign, utm_content). Without this, Google Analytics cannot attribute traffic to campaigns.

  • Add CampaignUtmConfig model (or UTM fields on Campaign) — source, medium, campaign name, content variant, optional custom slug
  • UTM builder step in the creation wizard (Step 2 — Details)
  • Short-link / redirect option (integrate with a link shortener or use Leadmetrics tracking domain)
  • UTM preview + copy-to-clipboard per campaign URL
  • All ad copy and email CTAs should reference the configured UTM-appended URL

Budget Pacing & Spend Alerts Campaign.budget exists but there is no pacing logic. A campaign burning through its monthly budget in week 2 needs an alert.

  • Add totalSpent as a computed/rolled-up field (sum of CampaignMetrics.spend)
  • Add pacing indicator: spent % vs time elapsed % — shown on the Overview tab and Performance tab
  • Add budget_overpace recommendation type to CampaignOptimizationRecommendation (threshold: spent > 60% of budget in first 40% of the campaign period)
  • Add budget_underpace alert too — campaign is underdelivering

Campaign Goal / KPI Progress Tracking Campaign.brief holds KPI targets as free text only. The “goal progress widget” on the Overview tab has no structured data source.

  • Add target KPI fields to Campaign: targetImpressions, targetClicks, targetLeads, targetConversions, targetRoas, targetReviews, targetBacklinks — nullable, filled by the DM during setup or by campaign-brief-writer
  • Overview tab progress bars: each KPI field vs the matching metric from CampaignMetrics
  • campaign-brief-writer should write structured KPI targets as JSON alongside the free-text brief

Contact List Management ReviewCampaign.contactListId and CampaignAudience reference contact lists, but there is no spec for how those lists are built.

  • Define how contacts are selected: CRM lead tag filter, saved query, manual CSV upload, or dynamic query (re-evaluated on each enroll run)
  • Add a Contact List builder UI step in the wizard for email_marketing and review_generation campaigns
  • Show enrolled count, pending count, completed count, opted-out count on the Sequence tab
  • Handle unsubscribes / opt-outs — sync back from ESP or flag manually; exclude from future steps

Campaign Templates DMs setting up the same type of campaign repeatedly should be able to start from a pre-built template.

  • Add CampaignTemplate model: type, channels, goal, brief skeleton, default sequence steps, default audience filters, optional UTM config skeleton
  • Template picker in the Creation Wizard step 1 — “Start from template” or “Start from scratch”
  • Platform-seeded templates: e.g. “Local Business Google Ads Lead Gen”, “B2B LinkedIn Ads Awareness”, “Post-Purchase Review Drip”, “Monthly Newsletter”, “Backlink Outreach — Resource Page”
  • DMs can save any completed campaign as a template

Medium Priority

Campaign Cloning / Duplication A DM should be able to duplicate an existing campaign into a new draft — useful when re-running the same campaign for a new month or a similar client.

  • Add POST /tenant/v1/campaigns/:id/clone endpoint
  • Clones: brief, audiences, sequence structure, UTM config, target KPIs — with a new name and reset status to draft
  • Does NOT clone: metrics, external mappings, generated content (Activities)
  • Clone button on the Campaign Detail Settings tab

Email Platform Sync (Flow A/B for Email) Paid ads have import (Flow A) and metrics sync (Flow B). Email marketing campaigns have neither. The email metrics fields in CampaignMetrics currently have no data source.

  • Flow A: import existing Mailchimp / Klaviyo campaigns into Leadmetrics (GET /campaigns/import?channel=mailchimp)
  • Flow B: sync open rates, click rates, unsubscribes back from the ESP per campaign on a daily schedule
  • Requires new provider methods in packages/providers/mailchimp/ and packages/providers/klaviyo/ (or a shared email-provider abstraction)
  • Optionally: push sequences created in Leadmetrics to the ESP as an automation flow

Social Media Post Scheduling social_media campaigns generate content but there is no scheduling model. There is no link between a generated post (Activity) and a publish date.

  • Add scheduledAt and publishedAt fields to the Activity model (or a join table CampaignPostSchedule)
  • Calendar view in the Campaign Content tab showing scheduled posts per platform per day
  • Integrate with the existing social-calendar-planner worker — it should write scheduled dates per post back to the campaign
  • Publish action: when scheduledAt is reached, enqueue a publish job per connected social channel

Campaign Activity Feed / Timeline No per-campaign timeline view. DMs and clients need a chronological log of everything that happened inside a campaign.

  • Add a Timeline tab (or collapsible panel) to Campaign Detail
  • Renders filtered audit log entries scoped to entityId === campaign.id and linked Activity / CampaignOptimizationRecommendation records
  • Events to surface: brief generated, content approved, campaign submitted, client approved, metrics synced, optimisation applied, status changes
  • Add GET /tenant/v1/campaigns/:id/timeline endpoint

Landing Page Association Paid ads and email campaigns drive traffic to a landing page. Associating a landing page with a campaign enables full-funnel reporting (ad CTR → landing page conversion rate) in one view.

  • Add optional landingPageUrl and landingPageId (FK to LandingPage if one exists in the system) fields on Campaign
  • Performance tab: show landing page conversion rate alongside ad/email CTR if a landing page is associated
  • Set in wizard Step 2 — Details

Campaign Labels / Tags Simple string tags on Campaign for filtering and grouping.

  • Add tags as String[] on Campaign
  • Multi-select tag input in the wizard and Settings tab
  • Tag filter on the Campaigns Hub list and analytics page
  • Suggested tags: quarter (Q1 2026), theme (Product Launch, Evergreen, Seasonal), client initiative

Lower Priority (V2)

Behaviour-based Email Sequence Triggers CampaignSequence.triggerType supports on_subscribe | on_date | manual — no behavioural branching.

  • “Re-enroll contact if they didn’t open in 14 days”
  • “Exit sequence if lead converts”
  • “Branch to alternate sequence if contact clicked link A but not link B”
  • Requires a sequence branching model and a trigger evaluation job

Campaign-scoped Performance Report DMs should be able to generate a client-friendly PDF/rich report for a single campaign, not just a deliverable period.

  • Trigger report-writer scoped to a campaign — passes CampaignMetrics, brief KPIs, and optimisation history as context
  • Add POST /tenant/v1/campaigns/:id/generate-report endpoint
  • Output stored as an Activity linked to the campaign

Multi-Campaign Linking / Campaign Groups No concept of campaign relationships. A Google Ads campaign and a retargeting email sequence targeting the same converted leads should be linkable.

  • Add relatedCampaignIds String[] on Campaign, or a CampaignGroup model (name, tenantId, campaignIds[])
  • Group view in the analytics page: show combined funnel across linked campaigns
  • A/B path tracking: if two campaigns target the same audience with different approaches, compare conversion rates side by side

Rules-based Pause / Resume Auto-pause/resume without requiring manual HITL approval for threshold-based financial guardrails.

  • “Pause this campaign if daily spend > $X” — set in Settings tab, respected by the optimizer scheduler
  • “Resume when ROAS > 2.0 for 3 consecutive days”
  • Only available for admin users; requires explicit opt-in per campaign
  • Distinct from the existing auto-pilot (which generates recommendations but never executes automatically)

© 2026 Leadmetrics — Internal use only