skills/design-workflow/SKILL.md
Design notification workflows the Novu way — choose channels, set severity, decide when a workflow is critical, configure digests, and route based on subscriber state. Applies to BOTH dashboard-authored and code-first (`@novu/framework`) workflows. Use when planning a new workflow, deciding which channels to include, picking severity, configuring digest behavior, or matching a use case (order confirmation, payment failed, account suspended, comment, trial expiring, password reset, webhook fan-out, fetch-then-notify) to a proven template.
npx skillsauth add novuhq/skills novu-design-workflowInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Design rules for any Novu workflow — independent of whether you author it in the Dashboard (no-code) or in code with @novu/framework. The decisions here (channels, severity, critical, digest, conditions) are the same on both surfaces; only the syntax differs.
Authoring in code? Pair this skill with
framework-integration/forworkflow(...),step.*,controlSchema, and Bridge Endpoint setup. Authoring in the Dashboard or via the Novu MCP? After designing here, fill in step content (subject, body,editorType, headers, conditions) usingdashboard-workflows/.
Use it whenever you need to decide what a workflow should look like:
Do not use it for: triggering an existing workflow (trigger-notification/), authoring code wrappers (framework-integration/), or rendering severity in the UI (inbox-integration/).
Two independent dials. Most workflows set neither.
| Dial | Values | Default | Effect |
| ---------- | ------------------------------- | ------------ | ------------------------------------------------------------------------------- |
| severity | LOW / MEDIUM / HIGH | unset | Visual prioritization in the Inbox (color, glow); informs digest skip rules. |
| critical | true / false | false | Bypass subscriber preferences, skip digest, no delays, all available channels. |
Rules of thumb:
severity unset for most workflows. Only set it when visual prioritization is needed.HIGH = "deal with this today" (payment failed, trial expiring tomorrow).critical: true = "deliver regardless of preferences" (account suspended, security alert, password reset).critical: true ⇒ digest is automatically skipped and channels deliver immediately.See references/severity-and-critical.md for the full behavior matrix and the readOnly vs critical distinction.
Use only those channels. Do not add fallbacks. Do not add extras. If the requested channel isn't configured in the organization, add it anyway because the user explicitly asked for it.
"Send a push notification when the order ships" → one
pushstep. Nothing else.
Pick from channels configured in the organization, in this priority order, up to 3 channels:
In-App > Email > Chat > Push > SMS
| Channel | Use it for | Skip it when |
| ------- | --------------------------------------------------------------------------------------------------- | ----------------------------------------------------------- |
| In-App | Default for in-product content. Always include if the user is in your product. | The recipient can't see it (password reset, OTP, pre-signup) |
| Email | Receipts, documentation, async communication. Default fallback after In-App. | Pure conversational pings inside the product |
| Chat | If configured AND severity >= MEDIUM. Slack/Teams for ops & internal flows. | Marketing or low-severity nudges |
| Push | Fallback when subscriber is offline but needs immediate awareness. | Subscriber is online (use In-App instead) |
| SMS | Last resort. Only when no other channel works (true emergencies, OTP, regulatory). | Anything that fits in Email or Push |
See references/channel-selection.md for the full decision tree.
When you add a digest step, default to:
type: "regular"subscriberId (and +threadId for conversational flows)Skip the digest when:
severity: HIGH, orcritical: trueSee references/digest-defaults.md for digest key composition and conversational examples.
Adapt routing based on whether the subscriber is online:
| State | Behavior | | -------- | ------------------------------------------------------------------------------------------------------- | | Online | Send In-App immediately. Skip Push. Delay Email/Chat based on severity. | | Offline | Use Push or Chat to get attention. |
Default delays:
The condition for "subscriber offline" is the same on both surfaces — see references/step-conditions.md.
Match the use case to a template and copy its shape. Each template specifies severity, critical, actionable, and interaction type, plus the step ordering.
| # | Use case | Severity | Critical | Notes |
| - | ------------------------------ | -------- | -------- | ------------------------------------------------ |
| 1 | Order Confirmation | none | false | Digested, In-App + Email + Push (offline only) |
| 2 | Comment on Your Post | none | false | Digested by subscriberId + threadId |
| 3 | Payment Failed | HIGH | false | In-App + Chat + Email + Push (offline) |
| 4 | Account Suspended | HIGH | true | All channels, no preferences, no digest |
| 5 | Forgot Password | none | true | Email + SMS only, no In-App |
| 6 | Trial Expiring Tomorrow | HIGH | false | In-App + Chat + Email + Push (offline) |
| 7 | Explicit Channel Request | n/a | n/a | Use only the channels the user specified |
| 8 | Webhook / External API Call | varies | varies | Add step.http after channel steps |
| 9 | Fetch Data then Notify | varies | varies | step.http first; declare responseBodySchema |
Full ASCII flows + per-template metadata in references/workflow-templates.md.
Conditions decide whether a step runs. Use them for "send only if subscriber is offline", "send email only if In-App wasn't seen", and similar fallbacks.
{ "==": [{ "var": "subscriber.isOnline" }, "false"] }skip: () => boolean callback to the step.The semantics are identical. See references/step-conditions.md for the canonical snippets and the variables available in each scope.
critical: true is not the same as readOnly: true — readOnly only hides the workflow from the Preferences UI; critical bypasses preferences and digests at runtime. See references/severity-and-critical.md.critical: true — critical workflows must deliver immediately. The digest step is auto-skipped.+threadId, a comment on Post A and a comment on Post B end up in the same digest.responseBodySchema — without it, downstream steps can't read response properties via {{ steps.<id>.<prop> }}.readOnly vs criticalskip equivalentsdashboard-workflows/ — author step content (subject, body, editorType, headers, conditions) for Dashboard or Novu MCP workflowsframework-integration/ — implement these designs in code (workflow(), step.*, controlSchema, Bridge)manage-preferences/ — how critical interacts with subscriber-level preferencesinbox-integration/ — how severity surfaces visually in the Inboxtrigger-notification/ — invoking a workflow once it's designeddata-ai
Trigger Novu notification workflows to send messages across email, SMS, push, chat, and in-app channels. Supports single triggers, bulk triggers, broadcast to all subscribers, topic-based targeting, and cancellation. Use when sending transactional notifications, alerts, or any event-driven messages.
testing
Create, update, search, and delete subscribers in Novu. Manage topics for group-based notification targeting. Set subscriber credentials for push and chat channels. Use when managing notification recipients, creating subscriber records, organizing subscribers into topics, or configuring channel-specific credentials.
development
Configure notification preferences in Novu at the workflow and subscriber level. Set default channel preferences (email, SMS, push, chat, in-app), mark preferences as read-only or subscriber-editable, and manage subscriber-specific overrides. Use when setting up notification opt-in/opt-out, configuring per-channel delivery preferences, or building a preferences management UI.
development
Integrate Novu's in-app notification inbox into web applications. Supports React, Next.js, and vanilla JavaScript. Includes the Inbox component (bell icon + notification feed), composable components (Bell, Notifications, InboxContent, Preferences), headless hooks, branded theming, custom render props, multi-tenancy via contexts, tabs, localization, and HMAC security. Use when adding an in-app notification center, bell icon, notification feed, real-time notification updates, or building a personalized and branded notification experience.