Campaigns page

Campaign = workflow + audience

A campaign holds:

Workflow (graph)

Nodes + edges drawn in the builder. Each node = one step (send, wait, branch, exit…). Stored in the Node table + campaign.data (layout).

Audience

A segment or a list of customers. Customers matching the audience enroll into a workflow run.

Triggers (optional)

Webhook URL, cron schedule, event listener. See Triggers.

Products link (optional)

Attach the campaign to one or more products → analytics split per product, messages can reference product info.

Statuses

StatusEnrolls new customers?Existing customers?
draft
activeKeep running
pausedFrozen at their current node
completedContinue until end-of-flow
archived❌ — read-only analytics

Create a campaign

1

+ New campaign

The create campaign modal opens. Fields:
  • Name (required)
  • Description
  • Audience (segment or all customers)
  • Owner (defaults to you)
2

Open the builder

Auto-redirect to /campaigns/:id/builder — full-screen, no sidebar.
3

Draw the workflow

Drop nodes + connect edges. See Builder.
4

Validate

Builder header → Validate. The engine compiles the graph and surfaces any errors.
5

Activate

Campaign page → Activate. Audience customers start enrolling.

AI Generate workflow

Generate a graph from a natural-language prompt. See AI Generate.
1

Open a new campaign (draft)

2

Builder header → AI Generate

Modal opens. Type a prompt, for example:
3-step cold outreach for fintech leads in VN.
Step 1: intro email personalized by industry.
Wait 3 days.
Step 2: follow-up if no reply, cite product use case.
Wait 5 days.
Step 3: exit cooldown if no click.
If reply at any point → handoff to sales.
3

Generate

The LLM emits a JSON graph, the validator compiles + places layout. Replaces the campaign’s current nodes (warns if there are existing nodes).
4

Review + tweak

Open each node, adjust subject/body, swap in templates. AI generate is a starting skeleton — not the final shape.
AI Generate wipes the existing nodes of the campaign. If there’s work-in-progress, duplicate the campaign first and generate on the copy.

Duplicate

Campaign table → ”…” menu → Duplicate. Creates a new draft campaign with:
  • Name: “[Old name] (copy)”
  • All nodes + edges + layout
  • Does NOT copy the audience (pick again to avoid double-sends)
  • Does NOT copy triggers
  • Does NOT copy stats
Useful for A/B testing a variant without disturbing the original. Campaign → Products tab → pick one or more products. Effects:
  • Analytics splits metrics per product (compare product lines in one campaign).
  • Template variable {{product.*}} resolves to the primary product.
  • The fit criterion auto-resolves from the product when an adjust-score node doesn’t specify a criterion.

Enrollment lifecycle

1

Audience match

A new customer enters a segment, or a dynamic segment re-runs and finds a match.
2

Trigger fires

Trigger node type manual (kicked off manually), schedule (cron), webhook, or event.
3

Workflow run created

Every customer = one WorkflowRun. It traverses nodes following the edges.
4

End

On reaching an Exit node (Cooldown/Handoff/Suppress) or the end-of-flow → status success / partial / failed / canceled.
A customer doesn’t re-enter a campaign they already completed — unless an admin resets it via the ”…” menu → “Re-enroll”.

Manual run

On the campaign page → Run now (campaigns with a manual trigger or no trigger). Fires the trigger manually so the current audience enrolls immediately.