> ## Documentation Index
> Fetch the complete documentation index at: https://notifizz.com/llms.txt
> Use this file to discover all available pages before exploring further.

# AI Notification Orchestrator

> The AI orchestrator generates the campaign code that resolves recipients and enriches events with your live business data. You describe what the campaign should do; the AI ships the rest.

# 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](/docs/concepts/recipients). 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](/docs/concepts/recipients).

A simple AI-generated orchestrator looks like:

```ts theme={null}
// 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:

```ts theme={null}
// 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.

<Steps>
  <Step title="Describe the campaign">
    "When a user signs up, send them a welcome message in the Notification Center."
  </Step>

  <Step title="Pick the event">
    The AI inspects your event catalog and suggests the closest match (here `user.signed_up`). Confirm or override.
  </Step>

  <Step title="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").
  </Step>

  <Step title="Iterate via prompts">
    Accept the diff, edit inline, or prompt the AI to adjust. Each iteration rewrites the diff incrementally.
  </Step>

  <Step title="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](/docs/sdks/event-tracking/overview).
  </Step>

  <Step title="Ship">
    Promote to `Dev` for testing on dev environments, then to `Live` once dev tasks are clean.
  </Step>
</Steps>

## 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 task                 | Trigger                                                                                   | Resolution                                                                                                  |
| ------------------------ | ----------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| **Add event properties** | Orchestrator 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 enricher**      | Orchestrator calls `enrichWith("notRegistered", ...)`.                                    | The AI generates a complete enricher scaffold with input/output schemas, ready to register in the Node SDK. |
| **Add enricher fields**  | Orchestrator 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](/docs/sdks/event-tracking/overview) 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"

```mermaid theme={null}
sequenceDiagram
    participant Dev as You
    participant Dash as Dashboard AI
    participant Code as Orchestrator code
    participant Notifizz

    Dev->>Dash: "When user signs up, send NC welcome"
    Dash->>Code: Generate first version
    Dash-->>Dev: Show diff
    Dev->>Dash: Accept (or iterate)
    Dash-->>Dev: Dev task: "missing 'userId' in event"
    Dev->>Dev: Run dev task via MCP — adds userId to track call
    Dash-->>Dev: Dev task auto-resolved
    Dev->>Notifizz: Promote campaign to Dev
    Dev->>Notifizz: Fire test event
    Notifizz-->>Dev: Delivery in delivery history
    Dev->>Notifizz: Promote to Live
```

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

<AccordionGroup>
  <Accordion title="Edit AI-generated code by hand?">
    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.
  </Accordion>

  <Accordion title="Stuck on a dev task — how do I unblock?">
    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.
  </Accordion>

  <Accordion title="Review AI-generated code before ship?">
    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](/docs/concepts/activity-log).
  </Accordion>

  <Accordion title="Can I write the orchestrator from a blank file?">
    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.
  </Accordion>

  <Accordion title="Diff two AI iterations?">
    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".
  </Accordion>
</AccordionGroup>

## See also

<CardGroup cols={2}>
  <Card title="Campaigns" icon="diagram-project" href="/docs/concepts/campaigns">
    Statuses, lifecycle, versioning.
  </Card>

  <Card title="Recipients" icon="user" href="/docs/concepts/recipients">
    The orchestrator's output shape and validation rules.
  </Card>

  <Card title="Enrichers tutorial" icon="puzzle-piece" href="/docs/sdks/how-to/enrichers-tutorial">
    Where `enrichWith()` calls go.
  </Card>

  <Card title="Activity log" icon="clock-rotate-left" href="/docs/concepts/activity-log">
    Audit trail of orchestrator edits and AI proposals.
  </Card>
</CardGroup>
