Skip to main content

Orchestrator

The orchestrator is the code inside a campaign that runs server-side per matching event. It is generated by AI from your campaign description — you don’t write it from scratch. You iterate by prompting in natural language; the AI rewrites the diff. Marketing autonomy without hiding the dev half — that’s the point.

TL;DR

  • Every campaign owns an AI-generated orchestrator that runs server-side per matching event.
  • It builds the recipient list — directly from event properties, via enrichers, or via dynamic recipient sources.
  • The AI is the author. You describe what the campaign does; the AI produces the orchestrator. You review, accept, or ask for adjustments — no blank page.
  • The AI surfaces dev tasks for any gap (missing event property, undefined enricher, missing enricher field). They’re one-click executable from your IDE via the Notifizz MCP.

The pitch in three steps

  1. Plug any event from your backend — even incomplete. client.track("user.signed_up", { userId }) is enough to start.
  2. The AI orchestrator enriches it automatically with your live business data via enrichers. It reads your event catalog, your enricher catalog, and the campaign description, and produces orchestrator code that fills the gaps.
  3. The notification ships — across every channel the campaign configures. New campaign? Dashboard config, no code redeploy. Marketing’s intervention loop is dashboard-only.

What it does

For every event that matches a campaign, the orchestrator runs. Its code:
  1. Receives the event payload (event.eventName, event.properties, …).
  2. Calls enrichers (enrichWith("fetchUser", { userId })) to fetch live data not in the event.
  3. Builds the recipient list — an array of { id, email, ...customFields } objects.
  4. Returns that list. The channel processors take over from here.
The recipient list shape is documented at recipients. A simple AI-generated orchestrator looks like:
// AI-generated for "user.welcomed" campaign
const user = await enrichWith("fetchUser", { userId: event.properties.userId });
return [{
  id: user.id,
  email: user.email,
  displayName: user.displayName,
}];
A multi-recipient one looks like:
// AI-generated for "team.member_added" campaign — notify the new member + team admins
const member = await enrichWith("fetchUser", { userId: event.properties.memberId });
const admins = await enrichWith("fetchTeamAdmins", { teamId: event.properties.teamId });

return [
  { id: member.id, email: member.email, role: "new-member" },
  ...admins.map(a => ({ id: a.id, email: a.email, role: "admin" })),
];
The role custom field flows into the channel template — different message copy per recipient role, same orchestrator.

How the AI authors

You describe the campaign in plain language. The AI reads:
  • The event catalog for this org. Every event your code emits has a registered shape; the AI sees what subscription.upgraded carries.
  • The enricher catalog. Every enricher you’ve registered with its input/output schemas. The AI knows fetchUser exists and what it returns.
  • The campaign description Marketing wrote.
It produces a diff against the previous orchestrator version. You review, accept, or ask the AI to adjust (“also include the team admins”). Each iteration is incremental — no full regenerations.
1

Describe the campaign

“When a user signs up, send them a welcome message in the Notification Center.”
2

Pick the event

The AI inspects your event catalog and suggests the closest match (here user.signed_up). Confirm or override.
3

AI generates the orchestrator

A diff shows up — recipients built from event.properties.userId directly, or via an enricher if your description mentions live data (“send the user’s billing plan in the message”).
4

Iterate via prompts

Accept the diff, edit inline, or prompt the AI to adjust. Each iteration rewrites the diff incrementally.
5

Resolve dev tasks

The dashboard surfaces issues — missing event property, undefined enricher, missing enricher field. The AI proposes resolutions; click to execute them in your IDE via the Notifizz MCP.
6

Ship

Promote to Dev for testing on dev environments, then to Live once dev tasks are clean.

Dev tasks

The AI orchestrator validates its own output against your platform state. When something doesn’t line up, it emits a dev task — a structured proposal you (or your IDE, via MCP) can execute in one shot.
Dev taskTriggerResolution
Add event propertiesOrchestrator reads event.properties.foo but your event catalog has never seen that key.The AI generates the prompt to update your client.track call.
Create enricherOrchestrator calls enrichWith("notRegistered", ...).The AI generates a complete enricher scaffold with input/output schemas, ready to register in the Node SDK.
Add enricher fieldsOrchestrator reads a field on an enricher’s output that the enricher hasn’t produced yet.The AI generates the prompt to extend the enricher’s output schema.
Each dev task carries a ready-to-execute prompt. From the dashboard, click to copy it; from your IDE, the Notifizz MCP executes it directly. Most resolutions are one-click.

Iterate with the AI

The orchestrator code is yours — but you keep authoring through the AI. Common iteration patterns:
  • Tighten the recipient logic — “skip users with optOutMarketing: true”.
  • Add custom fields per recipient — “tag each recipient with their billing plan so the template can branch”.
  • Reorder enricher calls — “fetch admins in parallel, not sequentially”.
  • Encode business rules — “only send to users created more than 7 days ago”.
The dashboard editor is full TypeScript with auto-complete on the event/enricher schemas. After the AI proposes, you can also tweak inline before approving the diff.

End-to-end “I want a new campaign”

Total time for a simple campaign: under five minutes. Most of which is the dev-task back-and-forth — and that loop only fires when there’s something genuinely new to wire (a new event property, a new enricher).

FAQ

The AI is the author, but the code is yours — after the AI proposes, you can tweak inline before approving the diff. The next AI iteration sees your edits and respects them.
Each dev task carries a structured proposal: file/line to edit, the new content, and rationale. Most are one-click via the Notifizz MCP. If the proposal is wrong, prompt the AI again with your context — it re-evaluates.
Yes — every save creates a new campaign version, every version has a diff against the previous, and the activity log records who ran the AI and who approved the diff. See activity log.
No — the AI is the author. The platform’s value is exactly that you don’t start from a blank page; the AI sees your event catalog, your enricher catalog, and the campaign description, and produces a working draft you iterate on. If the AI’s proposal is wrong, prompt it; if you’d rather phrase the change as code, edit the diff before approving it.
Each save creates a new campaign version. The dashboard’s version history shows diffs between any two versions. Combine with the activity log to see “who proposed what when”.

See also

Campaigns

Statuses, lifecycle, versioning.

Recipients

The orchestrator’s output shape and validation rules.

Enrichers tutorial

Where enrichWith() calls go.

Activity log

Audit trail of orchestrator edits and AI proposals.