How Notifizz works
Notifizz is event-driven end to end. Your backend emits one event with a flattrack(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 toPOST /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
Track the event
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.Match campaigns
eventName in the caller’s environment. Idempotency is enforced here: a duplicate idempotencyKey returns { duplicate: true } and skips re-enqueue.Create workflow instances
Run the AI orchestrator
Enqueue per-recipient sends
Dispatch through channels
Real-time client delivery
What you control
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
Why server-side routing instead of `track().workflow(slug, recipients)` like before?
Why server-side routing instead of `track().workflow(slug, recipients)` like before?
What happens if no campaign matches my event?
What happens if no campaign matches my event?
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.My event fired but the campaign didn't run.
My event fired but the campaign didn't run.
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.How does the orchestrator know who to notify?
How does the orchestrator know who to notify?
fetchUser({ userId })), and returns a recipient list. Each recipient must have at minimum id + email. See recipients for the patterns.Is there latency between `track()` and the user seeing the bell update?
Is there latency between `track()` and the user seeing the bell update?
How does the widget update in real time?
How does the widget update in real time?