[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-novu-novu-dashboard-workflows":3,"mdc--j41kkz-key":35,"related-org-novu-novu-dashboard-workflows":1091,"related-repo-novu-novu-dashboard-workflows":1196},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":12,"stars":23,"repoUrl":24,"updatedAt":25,"license":26,"forks":27,"topics":28,"repo":30,"sourceUrl":33,"mdContent":34},"novu-dashboard-workflows","author Novu workflow step content","Author step content for Novu workflows defined in the Dashboard or generated\u002Fedited via the Novu MCP. Use when filling in step controls (subject, body, editorType, headers, body, conditions) for email, in-app, sms, push, chat, delay, digest, throttle, or HTTP Request steps.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},"novu","Novu","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fnovu.png","novuhq",[13,17,20],{"name":14,"slug":15,"type":16},"MCP","mcp","tag",{"name":18,"slug":19,"type":16},"Workflow Automation","workflow-automation",{"name":21,"slug":22,"type":16},"Notifications","notifications",1,"https:\u002F\u002Fgithub.com\u002Fnovuhq\u002Fskills","2026-07-13T06:21:22.380822",null,2,[29,22,8],"notification",{"repoUrl":24,"stars":23,"forks":27,"topics":31,"description":32},[29,22,8],"Novu Skill Set for AI Agents ","https:\u002F\u002Fgithub.com\u002Fnovuhq\u002Fskills\u002Ftree\u002FHEAD\u002Fskills\u002Fdashboard-workflows","---\nname: novu-dashboard-workflows\ndescription: Author step content for Novu workflows defined in the Dashboard or generated\u002Fedited via the Novu MCP. Use when filling in step controls (subject, body, editorType, headers, body, conditions) for email, in-app, sms, push, chat, delay, digest, throttle, or HTTP Request steps.\ninputs:\n  - name: NOVU_SECRET_KEY\n    description: \"Server-side API key from https:\u002F\u002Fdashboard.novu.co\u002Fapi-keys. Used by the Novu MCP and Dashboard automation.\"\n    required: true\n    type: secret\n---\n\n# Dashboard Workflows\n\nRules for authoring **step content** (subject, body, `editorType`, headers, body, conditions) on workflows that live in the Novu Dashboard — whether you're editing them by hand or via the Novu MCP.\n\n> Authoring **in code** with [`@novu\u002Fframework`](..\u002Fframework-integration)? Skip this skill — the Framework SDK encodes these constraints in its types and helpers.\n>\n> Still need to **decide** what the workflow should look like (channels, severity, critical, digest, templates)? Start with [`design-workflow\u002F`](..\u002Fdesign-workflow), then come back here to fill in the step content.\n\n## When to use this skill\n\nUse it whenever you write or edit the **controls** of a Dashboard \u002F MCP step:\n\n- \"Set the email subject and body for this step\"\n- \"Update the in-app notification copy\"\n- \"Add headers to this HTTP Request step\"\n- \"Change the digest window to 1 hour\"\n- \"Skip this step when the subscriber is offline\" (step condition)\n- Any Novu MCP tool call that writes step content (`create_workflow`, `update_workflow_step`, etc.)\n\n## Step Content Guidelines\n\nThese rules apply to **every** step type.\n\n- Use Liquid variables in control values for personalization. Variables must be wrapped in double curly braces `{{` and `}}`. Example: `{{ subscriber.firstName }}`, `{{ payload.* }}`.\n- **EXCEPTION:** In Block Editor (`editorType: \"block\"`) node attributes, never use curly braces — use bare variable names like `payload.actionUrl` instead of `{{ payload.actionUrl }}`. See [`references\u002Femail-step.md`](.\u002Freferences\u002Femail-step.md) for the full Block Editor rules.\n- For steps **after** an HTTP Request step, use `{{ steps.\u003Chttp-step-id>.\u003Cproperty> }}` to reference response data. Only properties defined in that HTTP step's `responseBodySchema` are available — never invent arbitrary response fields. Example: if HTTP step `fetch-user` defines `responseBodySchema` with `name` and `email`, use `{{ steps.fetch-user.name }}` and `{{ steps.fetch-user.email }}`.\n- Never hardcode URLs, names, or product names — use variables instead.\n- Keep content consistent with other workflow steps.\n- Modify the content according to the user's intent.\n- Preserve everything not explicitly asked to change.\n- Keep the same `editorType` (`block` or `html` for email) and structure.\n\n## Step Types\n\nEach step type has its own content rules. Open the matching reference before writing controls.\n\n| Step type      | Reference                                                       | Use it for                                                  |\n| -------------- | --------------------------------------------------------------- | ----------------------------------------------------------- |\n| Email          | [`references\u002Femail-step.md`](.\u002Freferences\u002Femail-step.md)         | Detailed content, formal communications, receipts           |\n| In-App         | [`references\u002Fin-app-step.md`](.\u002Freferences\u002Fin-app-step.md)       | Real-time updates, activity feeds, high engagement          |\n| SMS            | [`references\u002Fsms-step.md`](.\u002Freferences\u002Fsms-step.md)             | Urgent alerts, verification codes, time-sensitive messages  |\n| Push           | [`references\u002Fpush-step.md`](.\u002Freferences\u002Fpush-step.md)           | Mobile engagement, re-engagement, time-sensitive updates    |\n| Chat           | [`references\u002Fchat-step.md`](.\u002Freferences\u002Fchat-step.md)           | Slack \u002F Discord \u002F Teams team & developer alerts             |\n| Delay          | [`references\u002Fdelay-step.md`](.\u002Freferences\u002Fdelay-step.md)         | Pause workflow execution before a channel step              |\n| Digest         | [`references\u002Fdigest-step.md`](.\u002Freferences\u002Fdigest-step.md)       | Batch multiple notifications into one                       |\n| Throttle       | [`references\u002Fthrottle-step.md`](.\u002Freferences\u002Fthrottle-step.md)   | Limit notification frequency, prevent fatigue               |\n| HTTP Request   | [`references\u002Fhttp-request-step.md`](.\u002Freferences\u002Fhttp-request-step.md) | Call external APIs \u002F webhooks; fetch data for later steps   |\n| Step condition | [`references\u002Fstep-conditions.md`](.\u002Freferences\u002Fstep-conditions.md) | JSON-Logic for \"send only if…\", merge \u002F replace \u002F remove    |\n\n## Common Pitfalls\n\n1. **Curly braces inside Block Editor attributes** — Maily TipTap node attrs (`url`, `text`, `src`, `id`, `each`, `href`, `externalLink`) take **bare** variable names. `\"{{ payload.actionUrl }}\"` is wrong; `\"payload.actionUrl\"` is right. See [`references\u002Femail-step.md`](.\u002Freferences\u002Femail-step.md).\n2. **Referencing undeclared HTTP response fields** — `{{ steps.\u003Chttp-step-id>.\u003Cproperty> }}` only works for properties listed in that step's `responseBodySchema`. Add the property to the schema first.\n3. **Hardcoding array items instead of looping** — when the payload contains an array (`payload.items`, `payload.providers`), iterate with a Block Editor `repeat` node or an HTML `{% for %}` loop. Don't list array items as separate nodes \u002F elements.\n4. **Empty key\u002Fvalue entries in HTTP headers or body** — use an empty array `[]` when not needed. Never `[{ \"key\": \"\", \"value\": \"\" }]`.\n5. **Hardcoded URLs \u002F product names** — always pull from `payload.*` or `subscriber.*` so the workflow stays portable.\n6. **Changing `editorType` when editing email** — keep `block` as `block` and `html` as `html` unless the user explicitly asks to switch.\n7. **Replacing a step condition when the user said \"add\"** — \"add\" \u002F \"also\" \u002F \"and\" merges with `{ \"and\": [...] }`; \"change to\" \u002F \"set to\" replaces; \"remove\" \u002F \"clear\" returns `null`. See [`references\u002Fstep-conditions.md`](.\u002Freferences\u002Fstep-conditions.md).\n\n## See Also\n\n- [`design-workflow\u002F`](..\u002Fdesign-workflow) — choose channels, severity, `critical`, digest defaults, and pick a workflow template **before** authoring step content\n- [`framework-integration\u002F`](..\u002Fframework-integration) — author the same workflows in code with `@novu\u002Fframework` instead\n- [`trigger-notification\u002F`](..\u002Ftrigger-notification) — fire a workflow once it's authored\n",{"data":36,"body":43},{"name":4,"description":6,"inputs":37},[38],{"name":39,"description":40,"required":41,"type":42},"NOVU_SECRET_KEY","Server-side API key from https:\u002F\u002Fdashboard.novu.co\u002Fapi-keys. Used by the Novu MCP and Dashboard automation.",true,"secret",{"type":44,"children":45},"root",[46,55,78,131,138,150,201,207,219,423,429,434,725,731,1018,1024],{"type":47,"tag":48,"props":49,"children":51},"element","h1",{"id":50},"dashboard-workflows",[52],{"type":53,"value":54},"text","Dashboard Workflows",{"type":47,"tag":56,"props":57,"children":58},"p",{},[59,61,67,69,76],{"type":53,"value":60},"Rules for authoring ",{"type":47,"tag":62,"props":63,"children":64},"strong",{},[65],{"type":53,"value":66},"step content",{"type":53,"value":68}," (subject, body, ",{"type":47,"tag":70,"props":71,"children":73},"code",{"className":72},[],[74],{"type":53,"value":75},"editorType",{"type":53,"value":77},", headers, body, conditions) on workflows that live in the Novu Dashboard — whether you're editing them by hand or via the Novu MCP.",{"type":47,"tag":79,"props":80,"children":81},"blockquote",{},[82,107],{"type":47,"tag":56,"props":83,"children":84},{},[85,87,92,94,105],{"type":53,"value":86},"Authoring ",{"type":47,"tag":62,"props":88,"children":89},{},[90],{"type":53,"value":91},"in code",{"type":53,"value":93}," with ",{"type":47,"tag":95,"props":96,"children":98},"a",{"href":97},"..\u002Fframework-integration",[99],{"type":47,"tag":70,"props":100,"children":102},{"className":101},[],[103],{"type":53,"value":104},"@novu\u002Fframework",{"type":53,"value":106},"? Skip this skill — the Framework SDK encodes these constraints in its types and helpers.",{"type":47,"tag":56,"props":108,"children":109},{},[110,112,117,119,129],{"type":53,"value":111},"Still need to ",{"type":47,"tag":62,"props":113,"children":114},{},[115],{"type":53,"value":116},"decide",{"type":53,"value":118}," what the workflow should look like (channels, severity, critical, digest, templates)? Start with ",{"type":47,"tag":95,"props":120,"children":122},{"href":121},"..\u002Fdesign-workflow",[123],{"type":47,"tag":70,"props":124,"children":126},{"className":125},[],[127],{"type":53,"value":128},"design-workflow\u002F",{"type":53,"value":130},", then come back here to fill in the step content.",{"type":47,"tag":132,"props":133,"children":135},"h2",{"id":134},"when-to-use-this-skill",[136],{"type":53,"value":137},"When to use this skill",{"type":47,"tag":56,"props":139,"children":140},{},[141,143,148],{"type":53,"value":142},"Use it whenever you write or edit the ",{"type":47,"tag":62,"props":144,"children":145},{},[146],{"type":53,"value":147},"controls",{"type":53,"value":149}," of a Dashboard \u002F MCP step:",{"type":47,"tag":151,"props":152,"children":153},"ul",{},[154,160,165,170,175,180],{"type":47,"tag":155,"props":156,"children":157},"li",{},[158],{"type":53,"value":159},"\"Set the email subject and body for this step\"",{"type":47,"tag":155,"props":161,"children":162},{},[163],{"type":53,"value":164},"\"Update the in-app notification copy\"",{"type":47,"tag":155,"props":166,"children":167},{},[168],{"type":53,"value":169},"\"Add headers to this HTTP Request step\"",{"type":47,"tag":155,"props":171,"children":172},{},[173],{"type":53,"value":174},"\"Change the digest window to 1 hour\"",{"type":47,"tag":155,"props":176,"children":177},{},[178],{"type":53,"value":179},"\"Skip this step when the subscriber is offline\" (step condition)",{"type":47,"tag":155,"props":181,"children":182},{},[183,185,191,193,199],{"type":53,"value":184},"Any Novu MCP tool call that writes step content (",{"type":47,"tag":70,"props":186,"children":188},{"className":187},[],[189],{"type":53,"value":190},"create_workflow",{"type":53,"value":192},", ",{"type":47,"tag":70,"props":194,"children":196},{"className":195},[],[197],{"type":53,"value":198},"update_workflow_step",{"type":53,"value":200},", etc.)",{"type":47,"tag":132,"props":202,"children":204},{"id":203},"step-content-guidelines",[205],{"type":53,"value":206},"Step Content Guidelines",{"type":47,"tag":56,"props":208,"children":209},{},[210,212,217],{"type":53,"value":211},"These rules apply to ",{"type":47,"tag":62,"props":213,"children":214},{},[215],{"type":53,"value":216},"every",{"type":53,"value":218}," step type.",{"type":47,"tag":151,"props":220,"children":221},{},[222,258,304,375,380,385,390,395],{"type":47,"tag":155,"props":223,"children":224},{},[225,227,233,235,241,243,249,250,256],{"type":53,"value":226},"Use Liquid variables in control values for personalization. Variables must be wrapped in double curly braces ",{"type":47,"tag":70,"props":228,"children":230},{"className":229},[],[231],{"type":53,"value":232},"{{",{"type":53,"value":234}," and ",{"type":47,"tag":70,"props":236,"children":238},{"className":237},[],[239],{"type":53,"value":240},"}}",{"type":53,"value":242},". Example: ",{"type":47,"tag":70,"props":244,"children":246},{"className":245},[],[247],{"type":53,"value":248},"{{ subscriber.firstName }}",{"type":53,"value":192},{"type":47,"tag":70,"props":251,"children":253},{"className":252},[],[254],{"type":53,"value":255},"{{ payload.* }}",{"type":53,"value":257},".",{"type":47,"tag":155,"props":259,"children":260},{},[261,266,268,274,276,282,284,290,292,302],{"type":47,"tag":62,"props":262,"children":263},{},[264],{"type":53,"value":265},"EXCEPTION:",{"type":53,"value":267}," In Block Editor (",{"type":47,"tag":70,"props":269,"children":271},{"className":270},[],[272],{"type":53,"value":273},"editorType: \"block\"",{"type":53,"value":275},") node attributes, never use curly braces — use bare variable names like ",{"type":47,"tag":70,"props":277,"children":279},{"className":278},[],[280],{"type":53,"value":281},"payload.actionUrl",{"type":53,"value":283}," instead of ",{"type":47,"tag":70,"props":285,"children":287},{"className":286},[],[288],{"type":53,"value":289},"{{ payload.actionUrl }}",{"type":53,"value":291},". See ",{"type":47,"tag":95,"props":293,"children":295},{"href":294},".\u002Freferences\u002Femail-step.md",[296],{"type":47,"tag":70,"props":297,"children":299},{"className":298},[],[300],{"type":53,"value":301},"references\u002Femail-step.md",{"type":53,"value":303}," for the full Block Editor rules.",{"type":47,"tag":155,"props":305,"children":306},{},[307,309,314,316,322,324,330,332,338,340,345,346,352,353,359,361,367,368,374],{"type":53,"value":308},"For steps ",{"type":47,"tag":62,"props":310,"children":311},{},[312],{"type":53,"value":313},"after",{"type":53,"value":315}," an HTTP Request step, use ",{"type":47,"tag":70,"props":317,"children":319},{"className":318},[],[320],{"type":53,"value":321},"{{ steps.\u003Chttp-step-id>.\u003Cproperty> }}",{"type":53,"value":323}," to reference response data. Only properties defined in that HTTP step's ",{"type":47,"tag":70,"props":325,"children":327},{"className":326},[],[328],{"type":53,"value":329},"responseBodySchema",{"type":53,"value":331}," are available — never invent arbitrary response fields. Example: if HTTP step ",{"type":47,"tag":70,"props":333,"children":335},{"className":334},[],[336],{"type":53,"value":337},"fetch-user",{"type":53,"value":339}," defines ",{"type":47,"tag":70,"props":341,"children":343},{"className":342},[],[344],{"type":53,"value":329},{"type":53,"value":93},{"type":47,"tag":70,"props":347,"children":349},{"className":348},[],[350],{"type":53,"value":351},"name",{"type":53,"value":234},{"type":47,"tag":70,"props":354,"children":356},{"className":355},[],[357],{"type":53,"value":358},"email",{"type":53,"value":360},", use ",{"type":47,"tag":70,"props":362,"children":364},{"className":363},[],[365],{"type":53,"value":366},"{{ steps.fetch-user.name }}",{"type":53,"value":234},{"type":47,"tag":70,"props":369,"children":371},{"className":370},[],[372],{"type":53,"value":373},"{{ steps.fetch-user.email }}",{"type":53,"value":257},{"type":47,"tag":155,"props":376,"children":377},{},[378],{"type":53,"value":379},"Never hardcode URLs, names, or product names — use variables instead.",{"type":47,"tag":155,"props":381,"children":382},{},[383],{"type":53,"value":384},"Keep content consistent with other workflow steps.",{"type":47,"tag":155,"props":386,"children":387},{},[388],{"type":53,"value":389},"Modify the content according to the user's intent.",{"type":47,"tag":155,"props":391,"children":392},{},[393],{"type":53,"value":394},"Preserve everything not explicitly asked to change.",{"type":47,"tag":155,"props":396,"children":397},{},[398,400,405,407,413,415,421],{"type":53,"value":399},"Keep the same ",{"type":47,"tag":70,"props":401,"children":403},{"className":402},[],[404],{"type":53,"value":75},{"type":53,"value":406}," (",{"type":47,"tag":70,"props":408,"children":410},{"className":409},[],[411],{"type":53,"value":412},"block",{"type":53,"value":414}," or ",{"type":47,"tag":70,"props":416,"children":418},{"className":417},[],[419],{"type":53,"value":420},"html",{"type":53,"value":422}," for email) and structure.",{"type":47,"tag":132,"props":424,"children":426},{"id":425},"step-types",[427],{"type":53,"value":428},"Step Types",{"type":47,"tag":56,"props":430,"children":431},{},[432],{"type":53,"value":433},"Each step type has its own content rules. Open the matching reference before writing controls.",{"type":47,"tag":435,"props":436,"children":437},"table",{},[438,462],{"type":47,"tag":439,"props":440,"children":441},"thead",{},[442],{"type":47,"tag":443,"props":444,"children":445},"tr",{},[446,452,457],{"type":47,"tag":447,"props":448,"children":449},"th",{},[450],{"type":53,"value":451},"Step type",{"type":47,"tag":447,"props":453,"children":454},{},[455],{"type":53,"value":456},"Reference",{"type":47,"tag":447,"props":458,"children":459},{},[460],{"type":53,"value":461},"Use it for",{"type":47,"tag":463,"props":464,"children":465},"tbody",{},[466,491,517,543,569,595,621,647,673,699],{"type":47,"tag":443,"props":467,"children":468},{},[469,475,486],{"type":47,"tag":470,"props":471,"children":472},"td",{},[473],{"type":53,"value":474},"Email",{"type":47,"tag":470,"props":476,"children":477},{},[478],{"type":47,"tag":95,"props":479,"children":480},{"href":294},[481],{"type":47,"tag":70,"props":482,"children":484},{"className":483},[],[485],{"type":53,"value":301},{"type":47,"tag":470,"props":487,"children":488},{},[489],{"type":53,"value":490},"Detailed content, formal communications, receipts",{"type":47,"tag":443,"props":492,"children":493},{},[494,499,512],{"type":47,"tag":470,"props":495,"children":496},{},[497],{"type":53,"value":498},"In-App",{"type":47,"tag":470,"props":500,"children":501},{},[502],{"type":47,"tag":95,"props":503,"children":505},{"href":504},".\u002Freferences\u002Fin-app-step.md",[506],{"type":47,"tag":70,"props":507,"children":509},{"className":508},[],[510],{"type":53,"value":511},"references\u002Fin-app-step.md",{"type":47,"tag":470,"props":513,"children":514},{},[515],{"type":53,"value":516},"Real-time updates, activity feeds, high engagement",{"type":47,"tag":443,"props":518,"children":519},{},[520,525,538],{"type":47,"tag":470,"props":521,"children":522},{},[523],{"type":53,"value":524},"SMS",{"type":47,"tag":470,"props":526,"children":527},{},[528],{"type":47,"tag":95,"props":529,"children":531},{"href":530},".\u002Freferences\u002Fsms-step.md",[532],{"type":47,"tag":70,"props":533,"children":535},{"className":534},[],[536],{"type":53,"value":537},"references\u002Fsms-step.md",{"type":47,"tag":470,"props":539,"children":540},{},[541],{"type":53,"value":542},"Urgent alerts, verification codes, time-sensitive messages",{"type":47,"tag":443,"props":544,"children":545},{},[546,551,564],{"type":47,"tag":470,"props":547,"children":548},{},[549],{"type":53,"value":550},"Push",{"type":47,"tag":470,"props":552,"children":553},{},[554],{"type":47,"tag":95,"props":555,"children":557},{"href":556},".\u002Freferences\u002Fpush-step.md",[558],{"type":47,"tag":70,"props":559,"children":561},{"className":560},[],[562],{"type":53,"value":563},"references\u002Fpush-step.md",{"type":47,"tag":470,"props":565,"children":566},{},[567],{"type":53,"value":568},"Mobile engagement, re-engagement, time-sensitive updates",{"type":47,"tag":443,"props":570,"children":571},{},[572,577,590],{"type":47,"tag":470,"props":573,"children":574},{},[575],{"type":53,"value":576},"Chat",{"type":47,"tag":470,"props":578,"children":579},{},[580],{"type":47,"tag":95,"props":581,"children":583},{"href":582},".\u002Freferences\u002Fchat-step.md",[584],{"type":47,"tag":70,"props":585,"children":587},{"className":586},[],[588],{"type":53,"value":589},"references\u002Fchat-step.md",{"type":47,"tag":470,"props":591,"children":592},{},[593],{"type":53,"value":594},"Slack \u002F Discord \u002F Teams team & developer alerts",{"type":47,"tag":443,"props":596,"children":597},{},[598,603,616],{"type":47,"tag":470,"props":599,"children":600},{},[601],{"type":53,"value":602},"Delay",{"type":47,"tag":470,"props":604,"children":605},{},[606],{"type":47,"tag":95,"props":607,"children":609},{"href":608},".\u002Freferences\u002Fdelay-step.md",[610],{"type":47,"tag":70,"props":611,"children":613},{"className":612},[],[614],{"type":53,"value":615},"references\u002Fdelay-step.md",{"type":47,"tag":470,"props":617,"children":618},{},[619],{"type":53,"value":620},"Pause workflow execution before a channel step",{"type":47,"tag":443,"props":622,"children":623},{},[624,629,642],{"type":47,"tag":470,"props":625,"children":626},{},[627],{"type":53,"value":628},"Digest",{"type":47,"tag":470,"props":630,"children":631},{},[632],{"type":47,"tag":95,"props":633,"children":635},{"href":634},".\u002Freferences\u002Fdigest-step.md",[636],{"type":47,"tag":70,"props":637,"children":639},{"className":638},[],[640],{"type":53,"value":641},"references\u002Fdigest-step.md",{"type":47,"tag":470,"props":643,"children":644},{},[645],{"type":53,"value":646},"Batch multiple notifications into one",{"type":47,"tag":443,"props":648,"children":649},{},[650,655,668],{"type":47,"tag":470,"props":651,"children":652},{},[653],{"type":53,"value":654},"Throttle",{"type":47,"tag":470,"props":656,"children":657},{},[658],{"type":47,"tag":95,"props":659,"children":661},{"href":660},".\u002Freferences\u002Fthrottle-step.md",[662],{"type":47,"tag":70,"props":663,"children":665},{"className":664},[],[666],{"type":53,"value":667},"references\u002Fthrottle-step.md",{"type":47,"tag":470,"props":669,"children":670},{},[671],{"type":53,"value":672},"Limit notification frequency, prevent fatigue",{"type":47,"tag":443,"props":674,"children":675},{},[676,681,694],{"type":47,"tag":470,"props":677,"children":678},{},[679],{"type":53,"value":680},"HTTP Request",{"type":47,"tag":470,"props":682,"children":683},{},[684],{"type":47,"tag":95,"props":685,"children":687},{"href":686},".\u002Freferences\u002Fhttp-request-step.md",[688],{"type":47,"tag":70,"props":689,"children":691},{"className":690},[],[692],{"type":53,"value":693},"references\u002Fhttp-request-step.md",{"type":47,"tag":470,"props":695,"children":696},{},[697],{"type":53,"value":698},"Call external APIs \u002F webhooks; fetch data for later steps",{"type":47,"tag":443,"props":700,"children":701},{},[702,707,720],{"type":47,"tag":470,"props":703,"children":704},{},[705],{"type":53,"value":706},"Step condition",{"type":47,"tag":470,"props":708,"children":709},{},[710],{"type":47,"tag":95,"props":711,"children":713},{"href":712},".\u002Freferences\u002Fstep-conditions.md",[714],{"type":47,"tag":70,"props":715,"children":717},{"className":716},[],[718],{"type":53,"value":719},"references\u002Fstep-conditions.md",{"type":47,"tag":470,"props":721,"children":722},{},[723],{"type":53,"value":724},"JSON-Logic for \"send only if…\", merge \u002F replace \u002F remove",{"type":47,"tag":132,"props":726,"children":728},{"id":727},"common-pitfalls",[729],{"type":53,"value":730},"Common Pitfalls",{"type":47,"tag":732,"props":733,"children":734},"ol",{},[735,826,850,891,916,941,984],{"type":47,"tag":155,"props":736,"children":737},{},[738,743,745,751,752,757,758,764,765,771,772,778,779,785,786,792,794,799,801,807,809,815,817,825],{"type":47,"tag":62,"props":739,"children":740},{},[741],{"type":53,"value":742},"Curly braces inside Block Editor attributes",{"type":53,"value":744}," — Maily TipTap node attrs (",{"type":47,"tag":70,"props":746,"children":748},{"className":747},[],[749],{"type":53,"value":750},"url",{"type":53,"value":192},{"type":47,"tag":70,"props":753,"children":755},{"className":754},[],[756],{"type":53,"value":53},{"type":53,"value":192},{"type":47,"tag":70,"props":759,"children":761},{"className":760},[],[762],{"type":53,"value":763},"src",{"type":53,"value":192},{"type":47,"tag":70,"props":766,"children":768},{"className":767},[],[769],{"type":53,"value":770},"id",{"type":53,"value":192},{"type":47,"tag":70,"props":773,"children":775},{"className":774},[],[776],{"type":53,"value":777},"each",{"type":53,"value":192},{"type":47,"tag":70,"props":780,"children":782},{"className":781},[],[783],{"type":53,"value":784},"href",{"type":53,"value":192},{"type":47,"tag":70,"props":787,"children":789},{"className":788},[],[790],{"type":53,"value":791},"externalLink",{"type":53,"value":793},") take ",{"type":47,"tag":62,"props":795,"children":796},{},[797],{"type":53,"value":798},"bare",{"type":53,"value":800}," variable names. ",{"type":47,"tag":70,"props":802,"children":804},{"className":803},[],[805],{"type":53,"value":806},"\"{{ payload.actionUrl }}\"",{"type":53,"value":808}," is wrong; ",{"type":47,"tag":70,"props":810,"children":812},{"className":811},[],[813],{"type":53,"value":814},"\"payload.actionUrl\"",{"type":53,"value":816}," is right. See ",{"type":47,"tag":95,"props":818,"children":819},{"href":294},[820],{"type":47,"tag":70,"props":821,"children":823},{"className":822},[],[824],{"type":53,"value":301},{"type":53,"value":257},{"type":47,"tag":155,"props":827,"children":828},{},[829,834,836,841,843,848],{"type":47,"tag":62,"props":830,"children":831},{},[832],{"type":53,"value":833},"Referencing undeclared HTTP response fields",{"type":53,"value":835}," — ",{"type":47,"tag":70,"props":837,"children":839},{"className":838},[],[840],{"type":53,"value":321},{"type":53,"value":842}," only works for properties listed in that step's ",{"type":47,"tag":70,"props":844,"children":846},{"className":845},[],[847],{"type":53,"value":329},{"type":53,"value":849},". Add the property to the schema first.",{"type":47,"tag":155,"props":851,"children":852},{},[853,858,860,866,867,873,875,881,883,889],{"type":47,"tag":62,"props":854,"children":855},{},[856],{"type":53,"value":857},"Hardcoding array items instead of looping",{"type":53,"value":859}," — when the payload contains an array (",{"type":47,"tag":70,"props":861,"children":863},{"className":862},[],[864],{"type":53,"value":865},"payload.items",{"type":53,"value":192},{"type":47,"tag":70,"props":868,"children":870},{"className":869},[],[871],{"type":53,"value":872},"payload.providers",{"type":53,"value":874},"), iterate with a Block Editor ",{"type":47,"tag":70,"props":876,"children":878},{"className":877},[],[879],{"type":53,"value":880},"repeat",{"type":53,"value":882}," node or an HTML ",{"type":47,"tag":70,"props":884,"children":886},{"className":885},[],[887],{"type":53,"value":888},"{% for %}",{"type":53,"value":890}," loop. Don't list array items as separate nodes \u002F elements.",{"type":47,"tag":155,"props":892,"children":893},{},[894,899,901,907,909,915],{"type":47,"tag":62,"props":895,"children":896},{},[897],{"type":53,"value":898},"Empty key\u002Fvalue entries in HTTP headers or body",{"type":53,"value":900}," — use an empty array ",{"type":47,"tag":70,"props":902,"children":904},{"className":903},[],[905],{"type":53,"value":906},"[]",{"type":53,"value":908}," when not needed. Never ",{"type":47,"tag":70,"props":910,"children":912},{"className":911},[],[913],{"type":53,"value":914},"[{ \"key\": \"\", \"value\": \"\" }]",{"type":53,"value":257},{"type":47,"tag":155,"props":917,"children":918},{},[919,924,926,932,933,939],{"type":47,"tag":62,"props":920,"children":921},{},[922],{"type":53,"value":923},"Hardcoded URLs \u002F product names",{"type":53,"value":925}," — always pull from ",{"type":47,"tag":70,"props":927,"children":929},{"className":928},[],[930],{"type":53,"value":931},"payload.*",{"type":53,"value":414},{"type":47,"tag":70,"props":934,"children":936},{"className":935},[],[937],{"type":53,"value":938},"subscriber.*",{"type":53,"value":940}," so the workflow stays portable.",{"type":47,"tag":155,"props":942,"children":943},{},[944,956,958,963,965,970,971,976,977,982],{"type":47,"tag":62,"props":945,"children":946},{},[947,949,954],{"type":53,"value":948},"Changing ",{"type":47,"tag":70,"props":950,"children":952},{"className":951},[],[953],{"type":53,"value":75},{"type":53,"value":955}," when editing email",{"type":53,"value":957}," — keep ",{"type":47,"tag":70,"props":959,"children":961},{"className":960},[],[962],{"type":53,"value":412},{"type":53,"value":964}," as ",{"type":47,"tag":70,"props":966,"children":968},{"className":967},[],[969],{"type":53,"value":412},{"type":53,"value":234},{"type":47,"tag":70,"props":972,"children":974},{"className":973},[],[975],{"type":53,"value":420},{"type":53,"value":964},{"type":47,"tag":70,"props":978,"children":980},{"className":979},[],[981],{"type":53,"value":420},{"type":53,"value":983}," unless the user explicitly asks to switch.",{"type":47,"tag":155,"props":985,"children":986},{},[987,992,994,1000,1002,1008,1009,1017],{"type":47,"tag":62,"props":988,"children":989},{},[990],{"type":53,"value":991},"Replacing a step condition when the user said \"add\"",{"type":53,"value":993}," — \"add\" \u002F \"also\" \u002F \"and\" merges with ",{"type":47,"tag":70,"props":995,"children":997},{"className":996},[],[998],{"type":53,"value":999},"{ \"and\": [...] }",{"type":53,"value":1001},"; \"change to\" \u002F \"set to\" replaces; \"remove\" \u002F \"clear\" returns ",{"type":47,"tag":70,"props":1003,"children":1005},{"className":1004},[],[1006],{"type":53,"value":1007},"null",{"type":53,"value":291},{"type":47,"tag":95,"props":1010,"children":1011},{"href":712},[1012],{"type":47,"tag":70,"props":1013,"children":1015},{"className":1014},[],[1016],{"type":53,"value":719},{"type":53,"value":257},{"type":47,"tag":132,"props":1019,"children":1021},{"id":1020},"see-also",[1022],{"type":53,"value":1023},"See Also",{"type":47,"tag":151,"props":1025,"children":1026},{},[1027,1055,1076],{"type":47,"tag":155,"props":1028,"children":1029},{},[1030,1038,1040,1046,1048,1053],{"type":47,"tag":95,"props":1031,"children":1032},{"href":121},[1033],{"type":47,"tag":70,"props":1034,"children":1036},{"className":1035},[],[1037],{"type":53,"value":128},{"type":53,"value":1039}," — choose channels, severity, ",{"type":47,"tag":70,"props":1041,"children":1043},{"className":1042},[],[1044],{"type":53,"value":1045},"critical",{"type":53,"value":1047},", digest defaults, and pick a workflow template ",{"type":47,"tag":62,"props":1049,"children":1050},{},[1051],{"type":53,"value":1052},"before",{"type":53,"value":1054}," authoring step content",{"type":47,"tag":155,"props":1056,"children":1057},{},[1058,1067,1069,1074],{"type":47,"tag":95,"props":1059,"children":1060},{"href":97},[1061],{"type":47,"tag":70,"props":1062,"children":1064},{"className":1063},[],[1065],{"type":53,"value":1066},"framework-integration\u002F",{"type":53,"value":1068}," — author the same workflows in code with ",{"type":47,"tag":70,"props":1070,"children":1072},{"className":1071},[],[1073],{"type":53,"value":104},{"type":53,"value":1075}," instead",{"type":47,"tag":155,"props":1077,"children":1078},{},[1079,1089],{"type":47,"tag":95,"props":1080,"children":1082},{"href":1081},"..\u002Ftrigger-notification",[1083],{"type":47,"tag":70,"props":1084,"children":1086},{"className":1085},[],[1087],{"type":53,"value":1088},"trigger-notification\u002F",{"type":53,"value":1090}," — fire a workflow once it's authored",{"items":1092,"total":1195},[1093,1109,1115,1127,1141,1161,1172,1184],{"slug":1094,"name":1094,"fn":1095,"description":1096,"org":1097,"tags":1098,"stars":1106,"repoUrl":1107,"updatedAt":1108},"env-setup","configure Novu environment variables","Create or update Novu environment variables in the user's project safely (never expose the secret key to the client). Complements the official Novu skills by covering project-level env configuration.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1099,1102,1105],{"name":1100,"slug":1101,"type":16},"Configuration","configuration",{"name":1103,"slug":1104,"type":16},"Environment Variables","environment-variables",{"name":21,"slug":22,"type":16},39301,"https:\u002F\u002Fgithub.com\u002Fnovuhq\u002Fnovu","2026-07-13T06:21:58.740401",{"slug":4,"name":4,"fn":5,"description":6,"org":1110,"tags":1111,"stars":23,"repoUrl":24,"updatedAt":25},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1112,1113,1114],{"name":14,"slug":15,"type":16},{"name":21,"slug":22,"type":16},{"name":18,"slug":19,"type":16},{"slug":1116,"name":1116,"fn":1117,"description":1118,"org":1119,"tags":1120,"stars":23,"repoUrl":24,"updatedAt":1126},"novu-design-workflow","design Novu notification workflows","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\u002Fframework`) 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.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1121,1124,1125],{"name":1122,"slug":1123,"type":16},"Messaging","messaging",{"name":21,"slug":22,"type":16},{"name":18,"slug":19,"type":16},"2026-07-16T06:02:17.656187",{"slug":1128,"name":1128,"fn":1129,"description":1130,"org":1131,"tags":1132,"stars":23,"repoUrl":24,"updatedAt":1140},"novu-framework-integration","build code-first notification workflows","Build code-first notification workflows with @novu\u002Fframework. Use when defining workflows in TypeScript (Zod \u002F JSON Schema \u002F Class Validator), composing channel steps (email, SMS, push, chat, in-app) with action steps (delay, digest, custom), exposing Step Controls for non-technical teammates, rendering React\u002FVue\u002FSvelte Email templates, hosting the Bridge Endpoint inside Next.js, Express, NestJS, Remix, Nuxt, SvelteKit, H3, or AWS Lambda, syncing to Novu Cloud via CLI \u002F GitHub Actions, securing production with HMAC, or implementing translations, hydration, multi-channel orchestration, and LLM-powered notification logic in code.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1133,1136,1137],{"name":1134,"slug":1135,"type":16},"Backend","backend",{"name":21,"slug":22,"type":16},{"name":1138,"slug":1139,"type":16},"TypeScript","typescript","2026-07-13T06:21:20.83585",{"slug":1142,"name":1142,"fn":1143,"description":1144,"org":1145,"tags":1146,"stars":23,"repoUrl":24,"updatedAt":1160},"novu-inbox-integration","integrate Novu in-app notification inbox","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.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1147,1150,1153,1156,1157],{"name":1148,"slug":1149,"type":16},"Frontend","frontend",{"name":1151,"slug":1152,"type":16},"JavaScript","javascript",{"name":1154,"slug":1155,"type":16},"Next.js","next-js",{"name":21,"slug":22,"type":16},{"name":1158,"slug":1159,"type":16},"React","react","2026-07-13T06:21:11.359078",{"slug":1162,"name":1162,"fn":1163,"description":1164,"org":1165,"tags":1166,"stars":23,"repoUrl":24,"updatedAt":1171},"novu-manage-preferences","configure Novu notification preferences","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\u002Fopt-out, configuring per-channel delivery preferences, or building a preferences management UI.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1167,1168],{"name":21,"slug":22,"type":16},{"name":1169,"slug":1170,"type":16},"Operations","operations","2026-07-13T06:21:30.061407",{"slug":1173,"name":1173,"fn":1174,"description":1175,"org":1176,"tags":1177,"stars":23,"repoUrl":24,"updatedAt":1183},"novu-manage-subscribers","manage Novu notification subscribers and topics","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.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1178,1181,1182],{"name":1179,"slug":1180,"type":16},"API Development","api-development",{"name":1122,"slug":1123,"type":16},{"name":21,"slug":22,"type":16},"2026-07-16T06:00:28.792114",{"slug":1185,"name":1185,"fn":1186,"description":1187,"org":1188,"tags":1189,"stars":23,"repoUrl":24,"updatedAt":1194},"novu-trigger-notification","trigger Novu notification workflows","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.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1190,1193],{"name":1191,"slug":1192,"type":16},"Automation","automation",{"name":21,"slug":22,"type":16},"2026-07-13T06:21:23.63132",8,{"items":1197,"total":1240},[1198,1204,1210,1216,1224,1229,1235],{"slug":4,"name":4,"fn":5,"description":6,"org":1199,"tags":1200,"stars":23,"repoUrl":24,"updatedAt":25},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1201,1202,1203],{"name":14,"slug":15,"type":16},{"name":21,"slug":22,"type":16},{"name":18,"slug":19,"type":16},{"slug":1116,"name":1116,"fn":1117,"description":1118,"org":1205,"tags":1206,"stars":23,"repoUrl":24,"updatedAt":1126},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1207,1208,1209],{"name":1122,"slug":1123,"type":16},{"name":21,"slug":22,"type":16},{"name":18,"slug":19,"type":16},{"slug":1128,"name":1128,"fn":1129,"description":1130,"org":1211,"tags":1212,"stars":23,"repoUrl":24,"updatedAt":1140},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1213,1214,1215],{"name":1134,"slug":1135,"type":16},{"name":21,"slug":22,"type":16},{"name":1138,"slug":1139,"type":16},{"slug":1142,"name":1142,"fn":1143,"description":1144,"org":1217,"tags":1218,"stars":23,"repoUrl":24,"updatedAt":1160},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1219,1220,1221,1222,1223],{"name":1148,"slug":1149,"type":16},{"name":1151,"slug":1152,"type":16},{"name":1154,"slug":1155,"type":16},{"name":21,"slug":22,"type":16},{"name":1158,"slug":1159,"type":16},{"slug":1162,"name":1162,"fn":1163,"description":1164,"org":1225,"tags":1226,"stars":23,"repoUrl":24,"updatedAt":1171},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1227,1228],{"name":21,"slug":22,"type":16},{"name":1169,"slug":1170,"type":16},{"slug":1173,"name":1173,"fn":1174,"description":1175,"org":1230,"tags":1231,"stars":23,"repoUrl":24,"updatedAt":1183},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1232,1233,1234],{"name":1179,"slug":1180,"type":16},{"name":1122,"slug":1123,"type":16},{"name":21,"slug":22,"type":16},{"slug":1185,"name":1185,"fn":1186,"description":1187,"org":1236,"tags":1237,"stars":23,"repoUrl":24,"updatedAt":1194},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1238,1239],{"name":1191,"slug":1192,"type":16},{"name":21,"slug":22,"type":16},7]