N8n Subworkflows Official
n8nOfficialPublished by n8n
- Skill
- Tool integration
- Automation and integrations
- Apache-2.0
- No issues found
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
Sub-workflows are the primary mechanism for reuse in n8n, allowing you to encapsulate logic into function-shaped units. By defining clear input contracts and return shapes, you can create modular components that are easier to test, maintain, and replace. This skill provides the standards for building, tagging, and discovering these components, ensuring that logic is centralized rather than duplicated across your instance.
What it does
- Encapsulates repeatable logic into independent, reusable sub-workflows.
- Establishes a search-before-build protocol to prevent logic duplication.
- Defines standards for input/output contracts using typed fields.
- Provides patterns for stateless pure logic and deliberate stateful operations.
- Supports advanced execution patterns like fire-and-forget parallelization.
- Implements tagging conventions for efficient discovery and organization.
When to use it
- When building multi-step logic that is likely to be needed in other workflows.
- When a workflow exceeds 10 nodes and requires better organization.
- When you need to perform generic concerns like auth, retries, or data parsing.
- When you need to isolate logic for independent testing or replaceability.
- When you need to expose a specific capability as an agent tool.
Advantages
- Reduces maintenance overhead by centralizing bug fixes.
- Improves readability by keeping top-level workflows linear and focused.
- Enables independent testing of logical chunks.
- Allows for swapping underlying implementations without affecting callers.
- Facilitates better discovery through standardized tagging.
Usage examples
- “I have a 15-node block that parses and formats customer data. How should I handle this?”
- Extract the logic into a sub-workflow named 'Format Customer Data', tag it with 'customer' and 'subworkflow', and call it from your main workflow using the Execute Workflow node.
- “I need to perform an audit log write after every step, but I don't want to slow down the main process.”
- Create a stateful sub-workflow for the audit log and call it with 'waitForSubWorkflow: false' to fire-and-forget the operation.
Install
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/n8n-io/n8n-subworkflows-official/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip n8n-subworkflows-official.zip -d .agents/skills
Documentation by n8n
n8n Sub-workflows
Sub-workflows are reusable functions. The Execute Workflow Trigger declares input parameters, the body does work, the last node returns output. Callers invoke it like any other node.
That framing opens up the function-shaped wins: encapsulation, reuse, testability, replaceability. It's the primary reuse mechanism in n8n, and unfortunately underused.
Without sub-workflows, the same logic gets duplicated across workflows. Bug fixes happen in multiple places, one gets missed, and "identical" copies drift.
Non-negotiables
Search before you build. Before writing logic that handles a generic problem, check if a sub-workflow already exists. Filter by tag (
search_workflows({ tags: ['subworkflow'] }), a domain tag) and/or keyword (query: '<keyword>'). Tags are the discovery mechanism (n8n 2.27.0+).Execute Workflow Triggeruses "Define Below" with typed fields, not passthrough. Define Below is the only mode that lets agent tools (fromAi) and structured callers pass values in. Two exceptions: (a) the sub-workflow specifically needs to receive binary (then it can't be wired as an agent tool directly), or (b) the sub-workflow takes no inputs at all (Define Below requires at least one field). See "Sub-workflow inputs and outputs" below.
Strong defaults
Anything reusable becomes a sub-workflow. If a logical chunk could plausibly be needed elsewhere, extract it. Exception: trivial wrappers (one HTTP call, no logic) and tightly-coupled-to-this-caller chunks.
Default to stateless for pure logic (input → output, no external state). For state-touching logic, build deliberately stateful sub-workflows that abstract the operation behind a clean contract (the ORM / repository pattern). What to avoid is accidental state: a "validate" sub-workflow that quietly writes to a log table.
Tag for discovery: every sub-workflow gets
subworkflow, a domain tag (customer), and/ortool. Tags are whatsearch_workflows({ tags })filters on; names stay plain and descriptive (Parse RFC2822 date). Seereferences/NAMING_AND_DISCOVERY.md.Description carries keywords. Input/output shape + representative terms, so varied queries surface it.
Split when input contracts genuinely differ (binary vs JSON, sync vs async, divergent auth schemes). Don't fit divergent contracts under one trigger via passthrough + internal branching. See
references/SUBWORKFLOW_PATTERNS.md"Splitting by input shape".
Decision tree: should this be a sub-workflow?
About to write a chunk of logic?
├── Could this plausibly be needed in another workflow?
│ ├── Yes → extract to sub-workflow
│ └── No → keep inline
│
├── Is this chunk >5 nodes and conceptually one thing?
│ └── Extract if you want testability, isolation, or reuse; if it's only for a cleaner canvas, group it inline instead (see below).
│
├── Is this chunk dealing with a generic concern (auth, retry, parsing, formatting)?
│ └── Almost certainly extract. These are the canonical reusable sub-workflows.
│
└── Is this chunk doing one HTTP call with no logic around it?
└── Don't extract. Extra workflow boundary for nothing.When the only motivation is a cleaner canvas (not reuse, isolation, testability, or an agent tool), a canvas node group is the tool for readability-only sectioning: faster (no sub-execution per call) and simpler (no input/output contract), with the logic staying inline. Group it where the section is connected, trigger-free, and faces outward at no more than one member in each direction (n8n-workflow-lifecycle-official references/NODE_GROUPS.md); split a too-branchy section into smaller valid slices rather than leaving the whole stage ungrouped (a sticky note annotates, it doesn't group). Extract to a sub-workflow only when you genuinely need reuse, isolation, independent testing, or an agent tool. See n8n-workflow-lifecycle-official Readability.
Stateless vs. stateful sub-workflows
Both are first-class. The choice is about intent and encapsulation.
Stateless
Takes input, returns output. No I/O outside the inputs/outputs. Default for pure logic.
Examples:
Parse RFC2822 date(tagsubworkflow). Input: date string. Output: ISO date or error.Compute MRR from subscription(tagsubworkflow). Input: subscription object. Output: MRR number.Format invoice as HTML(tagsubworkflow). Input: invoice data. Output: HTML string.
When you need the logic again, call it without worrying about side effects firing.
Stateful (deliberate)
Reads or writes external state behind a clean input/output contract. Comparable to a repository pattern: the sub-workflow abstracts the state operation so callers think in domain terms, not implementation.
Examples:
Get customer by id(tagcustomer). Input: id. Output: customer object or{ ok: false, error: 'not_found' }. Reads the DB.Write customer billing record(tagscustomer,billing). Input: record. Output:{ ok: true, id }. Writes the DB.Append audit event(tagaudit). Input: event. Output:{ ok: true, eventId }. Writes to a logging store.Send to on-call(tagnotification). Input: channel, message. Output:{ ok: true, messageId }. Calls Slack/SMTP.
The point of building these as sub-workflows:
Callers think in domain terms (
get customer by id), not in storage (SELECT * FROM customers ...).Swap the underlying store/API behind it (Postgres → Supabase, native node → HTTP) without touching callers.
Idempotency, retry, and validation become the sub-workflow's responsibility, centralized in one place.
What to avoid is accidental state: a sub-workflow named/described as pure that quietly writes to a log table. That ambushes callers who reasonably assumed it was safe to retry or compose. Either make the side effect part of the contract (rename, document, return its result) or move it out.
When to extract
The two main signals:
1. Conceptual coherence
When a chunk of nodes does one logical thing, even unreused, extraction can be worth it for:
Testability. Run the sub-workflow on its own with pinned data.
Replaceability. Swapping implementations doesn't ripple to callers.
Readability alone is not a reason to extract: a node group collapses five nodes into one labeled box more cheaply (no sub-execution, no input/output contract). Extract when you also want testability, replaceability, or reuse.
1.5 The fire-and-forget audit-log pattern
Audit logging is used here as a concrete illustration of the fire-and-forget stateful pattern. Don't add audit logging to a workflow unless the user asked for it. The pattern itself (fire a sub-workflow async, don't block on it) generalizes to any side observation: metrics, notifications, etc.
A deliberately stateful audit-log sub-workflow invoked with Execute Workflow's waitForSubWorkflow: false so the caller doesn't block on the write.
Caller ──→ [Execute Workflow: DB audit log]
{ title: 'Email Confirmation Received',
description: <serialized data> }
waitForSubWorkflow: false
↓ (caller continues immediately)
──→ [Continue with next step]The sub-workflow takes a title and description, writes to a logging table (or Slack, or both), returns. The caller doesn't wait. Audit log is a side observation, not the critical path.
When the user has asked for it, fire one at every meaningful state transition ("email confirmation received", "user verified", "processing started", "eligibility decision made") so the timeline reconstructs from logs.
Why it's valuable:
Observability for free. Per-execution timeline when something goes wrong.
No coupling. Implementation (DB, Slack, both) can change without touching callers.
Async by default.
waitForSubWorkflow: falsemeans the audit doesn't slow the main workflow.
The audit-log workflow is the right kind of stateful sub-workflow. The side effect is the point.
1.7 The middleware pattern
When a webhook workflow is API-shaped, treat it like one. Sub-workflows become middleware: small stateless functions that run before the main handler and either pass through or short-circuit with a 4xx.
Webhook
→ [Verify JWT] # decode + validate; 401 on failure
→ [Rate limit] # check + bump counter; 429 on failure
→ IF (all middleware ok)
→ Main handler logic
→ Respond 200
→ ELSE → Respond with the 4xx the middleware returnedCanonical example: custom JWT auth rolled inside n8n. Verify JWT (tag subworkflow) takes the raw Authorization header, decodes, validates signature and expiry, returns { ok: true, user_id } or { ok: false, status: 401, message }. The caller IFs on ok, responds early on failure, continues on success.
Why a sub-workflow and not inline: every webhook that needs auth calls the same one. Swap the library, rotate the signing key, or add refresh-token logic in a single place. The reuse target is exact, the contract is small, and the failure response shape is consistent across every API endpoint.
Pairs with n8n-error-handling-official for 4xx/5xx response shapes and n8n-credentials-and-security-official for the underlying secret handling.
2. Repetition pattern
You're about to build something you've built before. Stop. Search.
search_workflows({ query: 'date' })
search_workflows({ tags: ['customer'] })
search_workflows({ tags: ['subworkflow'] })If something matches, use it. If not, build it as a sub-workflow and tag it so the next search finds it. The tag convention (subworkflow, domain tags, tool) is what makes that work.
Linear, long workflows are fine when most of the work is in sub-workflows
A workflow can have 20+ nodes and still be readable if it's mostly a linear orchestration of sub-workflow calls and decisions. The shape (audit-log nodes shown only because they're a vivid example of "side observation between real steps", include them only if the user asked for audit logging):
Webhook
→ Audit log (sub-workflow)
→ Validate
→ Audit log (sub-workflow)
→ IF auth ok
→ Look up user (or sub-workflow)
→ Audit log (sub-workflow)
→ Process step 1 (sub-workflow)
→ Audit log (sub-workflow)
→ Process step 2 (sub-workflow)
→ Audit log (sub-workflow)
→ Decide eligibility (sub-workflow)
→ Audit log (sub-workflow)
→ Send notification (sub-workflow)
→ RespondEach "logical step" is a sub-workflow call. The caller is a long but linear narrative, easy to follow top-to-bottom. Logic lives in the sub-workflows.
This is not the same as a 20-node workflow with 20 inline transformations. That's hard to read. The pattern above is fine because:
Each node has one purpose (call a specific sub-workflow).
Node groups mark sections, sticky notes annotate them (per
n8n-workflow-lifecycle-official"Readability").Inspecting a section means opening the sub-workflow it calls. That's encapsulation.
Orchestration logic at the top level is visible without reading implementations.
If your workflow is well past 7 top-level boxes and isn't mostly Execute Workflow calls and branches, extract more where reuse or testing warrants it, and group the rest inline (node groups).
When NOT to extract
One HTTP call with no logic. A sub-workflow that's just
Execute Workflow → HTTP Request → returnadds a boundary for nothing. Inline it.Tightly coupled to the caller's specific shape. If the chunk takes a deeply nested input that only this caller produces, extracting it just relocates the coupling. Fix the data shape first.
Performance-critical hot paths. Each sub-workflow call adds latency (small, but real). For high-throughput workflows, profile before adding boundaries.
Search-before-build protocol
When the user describes something multi-step or generic-sounding:
1. search_workflows with relevant tags and/or query (e.g. `tags: ['subworkflow']`, a domain tag, the operation keyword)
2. If candidates appear, fetch get_workflow_details on the top 1-3
3. Confirm fit by reading the inputs/outputs and (briefly) the body
4. If a fit exists → use it. Tell the user "I found `<name>`. Using that."
5. If no fit exists → build new and tag it (`subworkflow`, domain, `tool`) so the next search finds itThe "tell the user" step matters. They benefit from knowing what's already in their library.
If a workflow you expect to find isn't appearing, the most common cause is per-workflow MCP access not being enabled. See n8n-workflow-lifecycle-official references/MCP_ACCESS_PER_WORKFLOW.md.
Sub-workflow inputs and outputs
Sub-workflows are triggered by Execute Workflow Trigger nodes. The trigger declares the input schema. The caller passes data via Execute Workflow, and the sub-workflow returns whatever its last node outputs.
Always use "Define Below" with explicit fields
The Execute Workflow Trigger has two input modes. Default to "Define Below" (typed fields). This is the only mode that lets agent tools (via fromAi()) and any structured caller pass values in. Without declared fields, the agent has no schema to fill and the sub-workflow can't be wired as a toolWorkflow cleanly.
Shape:
const subTrigger = trigger({
type: 'n8n-nodes-base.executeWorkflowTrigger',
config: {
parameters: {
workflowInputs: {
values: [
{ name: 'list_of_ids', type: 'array' },
{ name: 'include_transcript', type: 'boolean' },
{ name: 'session_id', type: 'string' },
],
},
},
},
})Each declared input becomes a typed parameter the caller can fill. Inside the workflow, access via $json.list_of_ids, etc., or $('When Executed by Another Workflow').first().json.<field> from anywhere downstream.
Pick types deliberately (string, number, boolean, array, object). The model uses these as the required types when filling agent tool parameters, and humans rely on them when wiring callers.
Exception 1: passthrough mode for binary
If the sub-workflow needs to receive binary (image, file, PDF), Define Below doesn't work because typed fields are JSON only. Switch to passthrough:
const subTrigger = trigger({
type: 'n8n-nodes-base.executeWorkflowTrigger',
config: {
parameters: {
inputSource: 'passthrough',
},
},
})In passthrough mode, the sub-workflow receives the caller's items as-is, including the binary slot. Cost: no typed input schema, so agent tools can't pass parameters through fromAi(). Use this mode for sub-workflows called by other workflows (not agents) where binary needs to flow through.
For sub-workflows that need binary AND are called by an agent, see n8n-binary-and-data-official references/AGENT_TOOL_BINARY.md (agent tools can't pass binary directly).
Exception 2: passthrough for sub-workflows with no inputs
Define Below requires at least one declared field. A sub-workflow that genuinely takes no inputs (a "list active credentials" tool, a "current count" lookup, any zero-arg operation) has nowhere to put the empty schema, so passthrough is the only option.
When using passthrough specifically for the no-input case:
Start the body with a
Set(Edit Fields) node in "Keep Only Set" mode with no fields. This clears the caller's JSON so downstream nodes don't accidentally read fields from whatever shape the caller happened to pass. Without it, the body silently picks up whatever the caller forwarded.Add a sticky note on the trigger documenting that no inputs are expected. Future readers (and the agent re-wiring this as a tool) need to know passthrough isn't here for binary, it's here because the schema is empty by design.
Agent-tool wiring still works in the no-input case: toolWorkflow accepts a sub-workflow whose input mapping has no fields. The agent's only decision is whether to invoke. The pattern from n8n-ai-nodes-official references/TOOLS.md ("zero fromAi parameters") applies directly.
Other conventions
Document inputs and outputs in the workflow
description. Field names, types, purpose. The description is what callers (humans and agents) read for the contract.Return a consistent shape. For expected failures (e.g., parse error), return
{ success: false, error: '...' }rather than throwing. Callers can branch without wrapping error outputs.Treat the input schema as a contract once it has callers. Adding optional fields is safe. Renaming or removing fields can be done, but only carefully: enumerate every caller (
search_workflowsfor the sub-workflow's name + manual scan), migrate them in the same change, and verify withvalidate_workflow+get_workflow_detailsbefore publishing. A silent break here is hard to detect because n8n won't error on an unrecognized input field. The sub-workflow just seesundefinedand the caller has no idea.Use a final Set / Edit Fields node to shape the return. Optional, sometimes required (when the last computation node carries noise fields), and good practice for sub-workflows even when not strictly required. It makes the return contract explicit at the boundary, so readers see the API by reading one node. This is the legitimate exception to the Set-node antipattern from
n8n-expressions-official: the implicit consumer of a sub-workflow's last node is every caller, so the Set earns its place as the explicit API boundary. Name itReturnorReturn <thing>.Return natural shapes, not storage shapes. A sub-workflow that owns a Data Table, a file in S3, or any storage layer should hide that representation from callers. Arrays return as arrays, objects as objects, dates as ISO strings, regardless of whether the underlying storage was JSON-stringified text or another internal format. The return contract is the interface. The storage layout is implementation detail.
Common slip: a sub-workflow has a "fresh" path (data just produced, natural shape) and a "cached" path (data just read from a
_objectcolumn, still stringified). Wrong instinct: stringify the fresh path "to match" the cached path. Right instinct: parse the cached path so both return the natural shape. Callers shouldn't have to know which they got.
For sub-workflows wired as agent tools specifically, see n8n-ai-nodes-official references/SUBWORKFLOW_AS_TOOL.md (AI Agent node) or n8n-agents-official references/TOOLS.md (first-class n8n Agent). A first-class Agent's workflow tool must also be in the same project as the Agent and published, and its fixed / expression inputs can't read the caller's trigger data.
Calling sub-workflows: Execute Workflow modes
Two settings on the caller-side Execute Workflow node beyond inputs/workflowId:
modedefaults to'all': the sub-workflow runs once with all N items as input. Items still flow through nodes per-item like any other workflow. Setmode: 'each'to run the sub-workflow N separate times, one item per execution. For sub-workflows whose body just processes items normally, the two are equivalent. The split matters when the sub-workflow's body assumes it sees exactly one item (per-run aggregation, "this is THE customer to operate on" logic, a final write that should fire once per input).mode: 'each'matches that assumption,mode: 'all'breaks it. When you DO need per-item iteration, prefermode: 'each'over a Loop Over Items node inside the sub-workflow.waitForSubWorkflowdefaults totrue. Settingoptions.waitForSubWorkflow: falsefires the call and immediately moves on, and the sub-workflow continues in the background. The caller's downstream sees no return data.
mode: 'each' + waitForSubWorkflow: false is the only true parallelization n8n offers: N sub-workflow executions dispatched without waiting, running concurrently (still bounded by per-instance concurrency limits and per-call overhead). Useful for "kick off N independent jobs, poll/aggregate later". For example: dispatch a long-running job per item, track each in a Data Table, then loop until all rows mark themselves complete or time out.
For the polling-after-fire-and-forget pattern, see references/SUBWORKFLOW_PATTERNS.md "Fire-and-forget parallelization".
Reference files
| File | Read when |
|---|---|
references/SUBWORKFLOW_PATTERNS.md | mode: 'all' vs 'each' default, splitting by input shape (binary/passthrough vs Define Below), fire-and-forget parallelization with Data Table polling |
references/NAMING_AND_DISCOVERY.md | Naming and tagging a new sub-workflow, searching for existing ones, the tag convention |
Anti-patterns
| Anti-pattern | What goes wrong | Fix |
|---|---|---|
| Duplicating the same date-parsing nodes in three workflows | Bug fixes happen in two places, miss the third | Extract to a single Parse <format> date sub-workflow (tag subworkflow) once |
| Building a new sub-workflow without searching | Library grows duplicates, and future searches find both | Always search_workflows first |
| Sub-workflow named/described as pure that quietly writes to a log table | Callers can't reason about retry or idempotency, side effect ambushes them | Either make the side effect part of the contract (rename, document, return its result) or move it out |
Sub-workflow with no description | Won't be found in future searches, nobody knows what it does | Set description with input/output shape and purpose |
Sub-workflow named Helper 3 | Name doesn't tell anyone what it does | Verb-first descriptive name (Parse RFC2822 date), see n8n-workflow-lifecycle-official NAMING_CONVENTIONS.md |
| Untagged sub-workflow | Won't show up under any tags filter, future you can't find it | Tag it (subworkflow, domain, tool) right after create via update_workflow addTags |
Execute Workflow Trigger set to passthrough when not handling binary and not deliberately zero-input | No typed schema means agent tools can't fill parameters via fromAi, structured callers can't pass values cleanly | Use "Define Below" with declared workflowInputs.values (name + type per field). The exceptions are binary-receiving sub-workflows and sub-workflows that genuinely take no inputs (see "Exception 2") |
| Passthrough trigger for a zero-input sub-workflow without a Set-to-clear node and explanatory sticky | Body silently reads stray fields from whatever the caller forwarded; future readers think passthrough is for binary | Add a Set ("Keep Only Set", no fields) at the top of the body and a sticky on the trigger noting no inputs are expected |
| Sub-workflow called as an agent tool that expects binary input | Agent tools can't pass binary directly | See n8n-binary-and-data-official AGENT_TOOL_BINARY.md for the right pattern |
| 30-node workflow with no extraction | Hard to read, hard to test, hard to replace | Extract logical sections into sub-workflows |
Files
- ATTRIBUTION.mdAdded by AutoGineer856 B
- LICENSELicence file added by AutoGineer11.0 KiB
- SKILL.md23.1 KiB
- references/NAMING_AND_DISCOVERY.md6.4 KiB
- references/SUBWORKFLOW_PATTERNS.md5.9 KiB
LICENSE
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for describing the origin of the Work and
reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may accept and charge a
fee for accepting support, warranty, indemnity, or other liability
obligations and/or rights consistent with this License. However, in
accepting such obligations, You may act only on Your own behalf
and on Your sole responsibility, not on behalf of any other
Contributor, and only if You agree to indemnify, defend, and hold
each Contributor harmless for any liability incurred by, or claims
asserted against, such Contributor by reason of your accepting any
such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2026 n8n GmbH
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Needs Node.js
Security
No issues found by our static scan· No issues found
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Published by
- n8n
- Publisher
- n8n (Official)
- Source
- n8n-io/skills · skills/n8n-subworkflows-official · commit 27b6b9f
- Licence
- Apache License 2.0 (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by n8n.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download n8n-subworkflows-official.zip