Skip to main content

How Notifizz works

Notifizz is event-driven end to end. Your backend emits one event with a flat track(eventName, properties) call — even an incomplete one. The platform resolves campaigns, the AI orchestrator enriches the event with your live business data and builds the recipient list, and notifications dispatch through every channel — all server-side, with no workflow or recipient targeting at the call site.

TL;DR

  • One call, one event. client.track(eventName, properties) posts to POST /v1/events/track.
  • Server-side routing. Campaigns matching the event name are looked up; one workflow instance is created per match.
  • AI orchestrator builds recipients. The campaign’s orchestrator runs against the event properties, calls enrichers to fetch live data, and produces the recipient list. The AI surfaces implementation tasks for any gap (missing event property, undefined enricher) — one-click executable from your IDE via MCP.
  • Channels dispatch. The queue delivers the resolved content per channel — Notification Center widget, web push, and email (channels).
  • Real-time front-end. The widget receives new messages instantly — no polling.

End-to-end pipeline

Each stage

1

Track the event

Your backend calls client.track(eventName, properties, { idempotencyKey }). The SDK posts to POST /v1/events/track with the SDK secret key as Bearer + X-Idempotency-Key. The backend acks acceptance within milliseconds — everything below runs asynchronously.
2

Match campaigns

The event handler looks up campaigns wired to this eventName in the caller’s environment. Idempotency is enforced here: a duplicate idempotencyKey returns { duplicate: true } and skips re-enqueue.
3

Create workflow instances

One workflow instance is created per matching campaign. Each instance carries the event properties, a correlation id, and the campaign version it ran against — so in-flight notifications run against the campaign version they started on, even if a newer version has shipped since.
4

Run the AI orchestrator

The orchestrator runs the campaign’s code: enrichment (calling registered enrichers via HMAC-signed webhooks to fetch live data your event didn’t carry), recipient resolution, branching. The AI generates this code from the campaign description; you review, edit, ship.
5

Enqueue per-recipient sends

Once the orchestrator produces a recipient list, the system enqueues one job per (recipient, channel) pair.
6

Dispatch through channels

Notifizz delivers to each channel: for the Notification Center, the message lands in the user’s inbox and the unread badge is bumped; web push sends an encrypted payload to each of the recipient’s browser subscriptions; email renders the template and hands it to the sending provider.
7

Real-time client delivery

The widget receives new messages in real time — the bell badge updates the moment the notification commits, with no polling and no SSE plumbing on your side.

What you control

The SDK call site never picks a campaign, channel, or recipient list. That separation is what makes the marketing/dev split workable: marketing edits campaigns without redeploying code, and the same event drives multiple campaigns over time.

Idempotency, retries, traceability

  • Idempotency — every track() carries a key (auto-UUID or caller-supplied). Duplicate keys short-circuit at the backend with { duplicate: true }.
  • Retries — the SDK retries transient failures twice (1s, 2s) before bubbling. Once the backend accepts the event, the internal queue owns retries downstream — failed steps land in the dead-letter queue with a correlation id you can trace.
  • Correlation ID — stamped at message creation time, propagates through every queue hop and every delivery write. Use it to follow a single delivery end-to-end.

FAQ

The chained shape forced the developer to know the campaign slug and the recipient list at the call site — two things that almost always change before the campaign ships. With server-side routing, marketing edits the campaign without a deploy, and the same event drives multiple campaigns over time.
The event is accepted (200) and recorded, but no workflow instance is created and no notification fires. This is intentional — you can register events ahead of building campaigns. The dashboard’s “missing properties” / “unrouted events” view surfaces these so you can wire up a campaign later.
Common causes in order: (1) campaign status is Editing (only Live delivers for real on prod; Implementation and Review run on dev environments only); (2) event-name mismatch (whitespace, case, source vs target); (3) campaign listening on the wrong environment. Check the dashboard delivery history — campaigns that didn’t match show a no-route entry.
The orchestrator is code (generated by the AI from the campaign description, editable). It reads the event properties, calls registered enrichers if needed (e.g. fetchUser({ userId })), and returns a recipient list. Each recipient must have at minimum id + email. See recipients for the patterns.
Acceptance is millisecond-fast. End-to-end latency depends on orchestrator complexity (especially enricher round trips) and queue depth. In normal operation, simple campaigns deliver in under a second; campaigns with cold enrichers can take a few seconds.
The widget subscribes to the user’s inbox over a real-time stream — new writes propagate instantly to the dropdown and badge, with no SSE plumbing or polling on your side. Reconnection and offline queueing are handled for you.

See also

Events and workflows

Events, properties, campaigns, recipients — the building blocks.

Channels

In-app, web push, email, and what’s on the roadmap.

Authentication

Widget auth modes — Firebase, backend token, publicly-signed JWT, none.

Backend quickstart

Send your first event in under five minutes.