> For the complete documentation index, see [llms.txt](https://docs.n8n.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.n8n.io/connect/n8n-api/n8n-package.md).

# N8n Package

Beta — breaking changes may still occur without major version bump.

## Beta: Export agents, workflows, folders, or projects as an n8n package

> \*\*Beta\*\* — breaking changes may still occur without major version bump.\
> \
> Export agents, workflows, and folders, or whole projects, as a gzipped tar\
> archive (.n8np). Provide \`agentIds\`/\`workflowIds\`/\`folderIds\`, or \`projectIds\`.\
> Do not combine these two groups. Each exported folder includes its nested\
> folders. Whole projects include their agents when the agents module is enabled.\
> Explicit agent selections require the agents module. Empty projects export\
> project metadata only. \`versionPolicy\` selects the version for both agents and\
> workflows and defaults to \`latest\`. \`dependencyPolicy\` applies to both entity\
> types and defaults to \`fail\` when a required definition is absent from the\
> package. The response is streamed as \`application/gzip\` with a \`Content-Disposition\`\
> attachment header. Requires the n8n Packages feature to be licensed.\
> \
> API key scopes: \`agent:export\` is required for explicitly selected agents.\
> \`workflow:export\` is required for explicitly selected workflows or folders.\
> \`project:export\` is sufficient for whole-project exports, including their\
> agents and workflows. Included dependencies need no additional API key scope.\
> The caller's project permissions apply to all included entities. When\
> \`includeVariableValues\` is true (the default) and exported entities reference\
> variables, \`variable:list\` is also required. Exports that reference no variables\
> do not need it.\
> \
> Agent definitions include referenced skills, custom tools, and schedules.\
> Knowledge base files and runtime data are excluded. Agent package imports\
> remain unavailable.<br>

```json
{"openapi":"3.0.0","info":{"title":"n8n Public API","version":"1.1.1"},"tags":[{"name":"N8nPackage","description":"Beta — breaking changes may still occur without major version bump."}],"servers":[{"url":"/api/v1","description":"Current n8n instance (self-hosted built-in playground)"},{"url":"{url}/api/v1","description":"Self-hosted n8n instance","variables":{"url":{"default":"https://example.com"}}}],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]},{"CookieAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-N8N-API-KEY"},"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"},"CookieAuth":{"type":"apiKey","in":"cookie","name":"n8n-auth"}},"schemas":{"exportPackageRequest":{"type":"object","additionalProperties":false,"description":"Selects what to export. Provide `agentIds`, `workflowIds`, and/or `folderIds` to export loose entities, or `projectIds` to export whole projects. Do not combine these two groups. Supply at least one ID.","properties":{"agentIds":{"type":"array","minItems":1,"maxItems":300,"description":"IDs of the agents to include. Requires the agents module.","items":{"type":"string","minLength":1}},"workflowIds":{"type":"array","maxItems":300,"description":"IDs of the workflows to include in the exported package.","items":{"type":"string","minLength":1}},"folderIds":{"type":"array","maxItems":300,"description":"IDs of the folders to include in the exported package. Each folder is exported with its nested folders.","items":{"type":"string","minLength":1}},"projectIds":{"type":"array","description":"IDs of the projects to include in the exported package. Includes their agents when the agents module is enabled.","items":{"type":"string","minLength":1}},"includeVariableValues":{"type":"boolean","default":true,"description":"Whether values of variables referenced by the exported entities are bundled into the package. When `false`, variables still travel as name/type files and are listed in the package requirements, but no values travel with the package."},"includeTags":{"type":"boolean","default":true,"description":"Whether tags assigned to the exported workflows are bundled into the package. When `false`, no tag files, tag references, or tag requirements travel with the package."},"dependencyPolicy":{"type":"string","enum":["fail","reference-only","include-in-package"],"description":"Policy for workflow and agent dependencies outside the selected package contents. Includes static workflow references and disabled agent references. `fail` aborts when a required workflow or agent is absent from the package. `include-in-package` adds accessible dependencies recursively. `reference-only` records external requirements without including those definitions. The same policy applies to workflows and agents.","default":"fail"},"versionPolicy":{"type":"string","enum":["published-strict","prefer-published","ignore-unpublished","latest"],"description":"Which version of each workflow and agent travels in the package. `latest` exports the current draft. `published-strict` requires a published version. `prefer-published` uses the published version when available and the draft otherwise. `ignore-unpublished` skips unpublished selections. Dependencies that cannot be included cause the export to fail only when `dependencyPolicy` is `fail` or `include-in-package`. With `reference-only`, the export records them as external requirements. The selected version supplies the definition and its references. Workflow names, settings, and tags always use their current values. Agent IDs, names, and MCP availability always use their current values.","default":"latest"},"credentialExportPolicy":{"type":"string","enum":["expression-values-only","no-values"],"description":"Whether expression values from credential data are bundled into the package. `expression-values-only` includes credential fields whose value is an n8n expression (for example `={{ $secrets.apiKey }}`); literal values never travel either way. `no-values` keeps credential data out of the package entirely, so each credential file carries only its id, name and type.","default":"expression-values-only"},"includeArchivedWorkflows":{"type":"boolean","description":"Whether folder and project exports include their archived workflows. When `false` (default) they are left out. When `true` they travel with `isArchived: true` and are archived on import. Workflows listed in `workflowIds` always export, also when archived.","default":false}}}},"responses":{"badRequest":{"description":"The request is invalid or provides malformed data."},"unauthorized":{"description":"Unauthorized"},"forbidden":{"description":"Forbidden"},"notFound":{"description":"The specified resource was not found."}}},"paths":{"/n8n-packages/export":{"post":{"tags":["N8nPackage"],"summary":"Beta: Export agents, workflows, folders, or projects as an n8n package","description":"**Beta** — breaking changes may still occur without major version bump.\n\nExport agents, workflows, and folders, or whole projects, as a gzipped tar\narchive (.n8np). Provide `agentIds`/`workflowIds`/`folderIds`, or `projectIds`.\nDo not combine these two groups. Each exported folder includes its nested\nfolders. Whole projects include their agents when the agents module is enabled.\nExplicit agent selections require the agents module. Empty projects export\nproject metadata only. `versionPolicy` selects the version for both agents and\nworkflows and defaults to `latest`. `dependencyPolicy` applies to both entity\ntypes and defaults to `fail` when a required definition is absent from the\npackage. The response is streamed as `application/gzip` with a `Content-Disposition`\nattachment header. Requires the n8n Packages feature to be licensed.\n\nAPI key scopes: `agent:export` is required for explicitly selected agents.\n`workflow:export` is required for explicitly selected workflows or folders.\n`project:export` is sufficient for whole-project exports, including their\nagents and workflows. Included dependencies need no additional API key scope.\nThe caller's project permissions apply to all included entities. When\n`includeVariableValues` is true (the default) and exported entities reference\nvariables, `variable:list` is also required. Exports that reference no variables\ndo not need it.\n\nAgent definitions include referenced skills, custom tools, and schedules.\nKnowledge base files and runtime data are excluded. Agent package imports\nremain unavailable.\n","requestBody":{"description":"Agents, workflows, folders, or projects to include in the exported package.","required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/exportPackageRequest"}}}},"responses":{"200":{"description":"A gzipped tar archive containing the exported package contents.","headers":{"X-N8n-Export-Counts":{"description":"JSON-serialized per-entity counts of what actually ended up in the\npackage (after folder bundling and auto-inclusion), e.g.\n`{\"agents\":1,\"workflows\":2,\"folders\":1,\"credentials\":0,\"dataTables\":0,\"variables\":0,\"tags\":0}`.\n","schema":{"type":"string"}}},"content":{"application/gzip":{"schema":{"type":"string","format":"binary"}}}},"400":{"$ref":"#/components/responses/badRequest"},"401":{"$ref":"#/components/responses/unauthorized"},"403":{"$ref":"#/components/responses/forbidden"},"404":{"$ref":"#/components/responses/notFound"}}}}}}
```

## Beta: Import an n8n package into a project

> \*\*Beta\*\* — breaking changes may still occur without major version bump.\
> \
> Imports a gzip-compressed tar package (\`.n8np\`) into the target project. Send the archive as the multipart field \`package\`. Optional routing uses form fields \`projectId\` and \`folderId\` (omit or send empty for defaults). Every optional mode/policy field (credential, workflow, project, folder, data table, variable, and tag) takes its default when omitted; the one non-fixed default is \`folderConflictPolicy\`, which follows \`projectConflictPolicy\` on a project package. The required \`workflowConflictPolicy\` field controls what happens when a package workflow matches an existing workflow by source id in the target project. Maximum upload size is \`N8N\_ENDPOINTS\_PAYLOAD\_SIZE\_MAX\` MB (default 16).\
> \
> The package must declare its manifest at \`manifest.json\` and include every file the manifest references.\
> \
> Credential references are resolved before any workflow is written.

```json
{"openapi":"3.0.0","info":{"title":"n8n Public API","version":"1.1.1"},"tags":[{"name":"N8nPackage","description":"Beta — breaking changes may still occur without major version bump."}],"servers":[{"url":"/api/v1","description":"Current n8n instance (self-hosted built-in playground)"},{"url":"{url}/api/v1","description":"Self-hosted n8n instance","variables":{"url":{"default":"https://example.com"}}}],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]},{"CookieAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-N8N-API-KEY"},"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"},"CookieAuth":{"type":"apiKey","in":"cookie","name":"n8n-auth"}},"schemas":{"importResultDto.generated":{"type":"object","properties":{"package":{"type":"object","properties":{"sourceN8nVersion":{"type":"string"},"sourceId":{"type":"string"},"exportedAt":{"type":"string","format":"date-time"}},"required":["sourceN8nVersion","sourceId","exportedAt"]},"workflows":{"type":"array","items":{"type":"object","properties":{"sourceWorkflowId":{"type":"string","description":"Workflow id as it appeared in the package."},"localId":{"type":"string","description":"Workflow id on the target instance: newly assigned for `created` (fresh under `workflowIdPolicy=new`, the package id under `source`), the existing workflow's id for `updated`/`skipped`."},"name":{"type":"string"},"projectId":{"type":"string"},"parentFolderId":{"type":"string","nullable":true},"activeVersionId":{"type":"string","nullable":true,"description":"Published version on the target instance, if any. `null` when the workflow is not published after import."},"isArchived":{"type":"boolean","description":"Whether the workflow is archived on the target after import. Under `new-version` this follows the package's `isArchived` flag. A skipped workflow keeps its own state."},"publishing":{"type":"object","properties":{"state":{"type":"string","enum":["published","unpublished","unchanged","blocked","failed"],"description":"`blocked` means the imported version could not be published and no version is active (for example because the workflow uses a stubbed credential, or uses a node type this instance does not have). When a prior published version remains active, `state` is `unchanged` with `skippedPublishReason` instead. `failed` means publish or unpublish was attempted but did not succeed."},"error":{"type":"string","description":"Present when `state` is `failed`. Explains why publish or unpublish could not be applied."},"blockedReason":{"type":"string","enum":["stub-credential","missing-node-type"],"description":"Present when `state` is `blocked`: the imported version could not be published and no version is active."},"skippedPublishReason":{"type":"string","enum":["stub-credential","missing-node-type"],"description":"Present when `state` is `unchanged` but the policy wanted to publish the imported version: a prior published version is still active (for example after an update with stubbed credentials)."}},"required":["state"],"description":"Outcome of applying the selected publishing policy to this workflow."},"status":{"type":"string","enum":["created","updated","skipped"],"description":"Import outcome for this package workflow."}},"required":["sourceWorkflowId","localId","name","projectId","parentFolderId","activeVersionId","isArchived","publishing","status"]}},"removedWorkflows":{"type":"array","items":{"type":"object","properties":{"workflowId":{"type":"string","description":"Id of the removed workflow on this instance."},"name":{"type":"string"},"projectId":{"type":"string","description":"Project the workflow was reconciled against."},"parentFolderId":{"type":"string","nullable":true,"description":"Folder that held the workflow, or null at the project root."},"deletion":{"type":"string","enum":["archived","deleted"],"description":"What actually happened, not what `overwriteDeletionPolicy` asked for: a `hard-delete` whose row could not be dropped yet is reported as `archived`."}},"required":["workflowId","name","projectId","parentFolderId","deletion"]},"description":"Workflows removed from the target during this import."},"removedFolders":{"type":"array","items":{"type":"object","properties":{"folderId":{"type":"string"},"name":{"type":"string"},"projectId":{"type":"string"},"parentFolderId":{"type":"string","nullable":true,"description":"Folder that held it, or null at the project root."}},"required":["folderId","name","projectId","parentFolderId"]},"description":"Folders the package does not define that reconciliation left empty, removed by `folderConflictPolicy=overwrite`. A folder still holding anything survives, so target-only content is never swept up. Empty under every other policy."},"folders":{"type":"array","items":{"type":"object","properties":{"sourceFolderId":{"type":"string","description":"Folder id as it appeared in the package."},"localId":{"type":"string","description":"Folder id on the target instance (equal to `sourceFolderId`; folder ids are reused)."},"name":{"type":"string"},"parentFolderId":{"type":"string","nullable":true,"description":"Resolved parent folder on the target, or `null` at the project root."},"status":{"type":"string","enum":["created","skipped"],"description":"Import outcome for this package folder."}},"required":["sourceFolderId","localId","name","parentFolderId","status"]},"description":"Folder shells created or skipped in the target project."},"projects":{"type":"array","items":{"type":"object","properties":{"sourceProjectId":{"type":"string","description":"Project id as it appeared in the package."},"localId":{"type":"string","description":"Project id on the target instance (equal to `sourceProjectId`; project ids are reused)."},"name":{"type":"string","description":"The project's name on the target: the package's under `overwrite`, the pre-existing one under `merge`."},"status":{"type":"string","enum":["created","updated","skipped"],"description":"Import outcome for this package project. `skipped` means the project already existed and `projectConflictPolicy=merge` left its details untouched — its contents were still imported."}},"required":["sourceProjectId","localId","name","status"]},"description":"Project shells created, or matched and then updated or left as-is (see `projectConflictPolicy`). Present for project packages; empty when importing loose workflows/folders."},"bindings":{"type":"object","properties":{"workflows":{"type":"object","additionalProperties":{"type":"string"}},"credentials":{"type":"object","additionalProperties":{"type":"string"},"description":"Credential id from `requirements.credentials` in the package manifest → resolved target credential id on the target instance. Covers both a matched existing credential and a credential created as a stub under `credentialMissingMode=create-stub`."}},"required":["workflows","credentials"],"description":"Source id → target id mappings produced during import, one map per entity type. Each value maps an id as it appeared in the package to the id on the target instance."},"credentials":{"type":"object","properties":{"matched":{"type":"array","items":{"type":"string"},"description":"Source credential ids from the package that matched existing credentials on the target instance."},"stubbed":{"type":"array","items":{"type":"string"},"description":"Source credential ids for which empty placeholder credentials were created in the target project."}},"required":["matched","stubbed"],"description":"Source credential ids grouped by whether they matched an existing credential or were created as stubs. Full source→target id mapping is in `bindings.credentials`."},"dataTables":{"type":"object","properties":{"matched":{"type":"integer","minimum":0},"created":{"type":"integer","minimum":0},"updated":{"type":"integer","minimum":0}},"required":["matched","created","updated"]},"variables":{"type":"object","properties":{"matched":{"type":"array","items":{"type":"string"},"description":"Variable names that resolved to an existing variable (importing project's scope first, then global) and were left untouched. A resolved variable this import rewrote is listed under `updated` instead."},"missing":{"type":"array","items":{"type":"string"},"description":"Variable names still unresolved after import. Under `variableMissingMode=do-nothing` these are warnings — the import still succeeds and nothing is created. A successful `create-stub` or `create-with-value` import normally leaves this empty."},"created":{"type":"array","items":{"type":"string"},"description":"Variable names created with a package value under `variableMissingMode=create-with-value`. Empty stubs are listed under `stubbed`."},"stubbed":{"type":"array","items":{"type":"string"},"description":"Variable names created with an empty value by this import under `variableMissingMode=create-stub`, or because `create-with-value` had no exported value. Empty for other outcomes."},"updated":{"type":"array","items":{"type":"string"},"description":"Variable names whose existing value this import replaced with the package value under `variableConflictPolicy=overwrite`. Empty for other policies."}},"required":["matched","missing","created","stubbed","updated"],"description":"Resolution of the package's variable requirements. Names only — values never travel in the response. For project packages these arrays are package-level unions of per-destination outcomes and may overlap (for example, a name may be created with a value in one project and stubbed in another); classification under concurrent external writes is best-effort."},"tags":{"type":"object","properties":{"matched":{"type":"array","items":{"type":"string"},"description":"Tags that resolved to an existing tag with the same id and name; attached as-is."},"created":{"type":"array","items":{"type":"string"},"description":"Tags created by this import, by name, under `tagMissingMode=create`."},"renamed":{"type":"array","items":{"type":"string"},"description":"Target tags renamed to the package name under `tagConflictPolicy=rename`; listed by their new name."},"reconciled":{"type":"array","items":{"type":"string"},"description":"Existing target tags re-keyed to the package (source) id on a name collision under `tagConflictPolicy=rename`; their name, workflow and folder taggings are kept."},"skipped":{"type":"array","items":{"type":"string"},"description":"Tags dropped from the import — not created, not renamed, and not attached to any imported workflow — under `tagMissingMode=do-nothing` or `tagConflictPolicy=skip`."}},"required":["matched","created","renamed","reconciled","skipped"],"description":"Resolution of the tags referenced by the imported workflows, matched by source id. Tag names only."}},"required":["package","workflows","removedWorkflows","removedFolders","folders","projects","bindings","credentials","dataTables","variables","tags"]},"importBlockingIssue.generated":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["workflow-conflict"]},"sourceWorkflowId":{"type":"string"},"existingWorkflowId":{"type":"string"},"name":{"type":"string"}},"required":["type","sourceWorkflowId","existingWorkflowId","name"],"description":"A workflow whose source id already matches one in the target project, under the `fail` conflict policy."},{"type":"object","properties":{"type":{"type":"string","enum":["workflow-lineage-conflict"]},"sourceWorkflowId":{"type":"string"},"projectId":{"type":"string"},"existingWorkflows":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"isArchived":{"type":"boolean"}},"required":["id","name","isArchived"]}}},"required":["type","sourceWorkflowId","projectId","existingWorkflows"],"description":"A package workflow whose source id matches multiple workflows in the target project. The import cannot choose a workflow safely."},{"type":"object","properties":{"type":{"type":"string","enum":["workflow-id-conflict"]},"sourceWorkflowId":{"type":"string"},"existingWorkflowId":{"type":"string"},"existingProjectId":{"type":"string","nullable":true,"description":"Project that owns the existing workflow, or null when no owning project could be determined."},"isArchived":{"type":"boolean","description":"Whether the existing workflow is archived."},"name":{"type":"string"}},"required":["type","sourceWorkflowId","existingWorkflowId","existingProjectId","isArchived","name"],"description":"A `source`-policy workflow whose id is already taken on the instance. Workflow ids are globally unique, so the id cannot be created in the target project. The existing workflow can be in another project, can lack an owner share, or can use a different source id. It can also be archived."},{"type":"object","properties":{"type":{"type":"string","enum":["workflow-folder-conflict"]},"sourceWorkflowId":{"type":"string"},"existingWorkflowId":{"type":"string"},"existingParentFolderId":{"type":"string","nullable":true,"description":"Folder that currently contains the matched workflow, or null when it lives at the project root."},"targetFolderId":{"type":"string","description":"Folder the import was requested to land in."},"name":{"type":"string"}},"required":["type","sourceWorkflowId","existingWorkflowId","existingParentFolderId","targetFolderId","name"],"description":"A workflow whose source id already matches one in the target project but lives outside the requested import folder. Folder-targeted imports cannot update workflows in place at a different location."},{"type":"object","properties":{"type":{"type":"string","enum":["workflow-archive-forbidden"]},"sourceWorkflowId":{"type":"string"},"existingWorkflowId":{"type":"string"},"name":{"type":"string"},"projectId":{"type":"string","description":"Project that owns the matched workflow."},"transition":{"type":"string","enum":["archive","unarchive"],"description":"The step the import needs to bring the workflow to the package's state."}},"required":["type","sourceWorkflowId","existingWorkflowId","name","projectId","transition"],"description":"A matched workflow whose archived state differs from the package, so the import must archive or unarchive it, but the caller lacks `workflow:delete` on it. Reported at plan time so nothing is written."},{"type":"object","properties":{"type":{"type":"string","enum":["credential-unresolved"]},"kind":{"type":"string","enum":["not_found","unknown_type","source_not_found","type_mismatch"]},"sourceId":{"type":"string"},"targetId":{"type":"string","description":"Target credential id: for `not_found`, the explicit binding that could not be resolved; for `type_mismatch`, the credential id that was resolved — via an explicit binding or automatic matching — but has the wrong type."},"expectedType":{"type":"string","description":"For `type_mismatch`: the credential type the package's workflow node requires."},"actualType":{"type":"string","description":"For `type_mismatch`: the actual type of the resolved target credential."},"usedBy":{"type":"array","items":{"$ref":"#/components/schemas/packageRequirementConsumer.generated"}}},"required":["type","kind","sourceId","usedBy"],"description":"A credential reference that could not be resolved in the target project."},{"type":"object","properties":{"type":{"type":"string","enum":["project-conflict"]},"kind":{"type":"string","enum":["fail-policy"]},"sourceProjectId":{"type":"string"},"name":{"type":"string","description":"The project's name as it appears in the package."}},"required":["type","kind","sourceProjectId","name"],"description":"A project defined by the package that already exists on this instance, under `projectConflictPolicy=fail`."},{"type":"object","properties":{"type":{"type":"string","enum":["folder-conflict"]},"kind":{"type":"string","enum":["parent-mismatch","id-in-other-project","fail-policy"]},"sourceFolderId":{"type":"string"},"name":{"type":"string"},"existingParentFolderId":{"type":"string","nullable":true,"description":"For `parent-mismatch`: the matched folder's current parent in the target."},"expectedParentFolderId":{"type":"string","nullable":true,"description":"For `parent-mismatch`: the parent the package would place the folder under."},"existingProjectId":{"type":"string","nullable":true,"description":"For `id-in-other-project`: the project that already owns the id."}},"required":["type","kind","sourceFolderId","name"],"description":"A package folder that cannot be imported as-is. `kind` distinguishes the cause: `parent-mismatch` (a folder matched by id sits under a different parent than the package places it), `id-in-other-project` (the folder id already exists in a different project — ids are globally unique), or `fail-policy` (the folder already exists and `folderConflictPolicy` is `fail`)."},{"type":"object","properties":{"type":{"type":"string","enum":["workflow-removal-forbidden"]},"workflowId":{"type":"string"},"name":{"type":"string"},"projectId":{"type":"string","description":"Project the workflow was being reconciled against."}},"required":["type","workflowId","name","projectId"],"description":"A workflow the import would remove but the caller lacks `workflow:delete` on: either `folderConflictPolicy=overwrite` would remove it because the package does not contain it, or it is named in the selection's `deletedWorkflowIds`. Reported instead of removing a subset, which would leave the project matching neither the package nor its previous state."},{"type":"object","properties":{"type":{"type":"string","enum":["workflow-removal-conflict"]},"sourceWorkflowId":{"type":"string"},"workflowId":{"type":"string","description":"The destination id of the selected workflow."},"projectId":{"type":"string"}},"required":["type","sourceWorkflowId","workflowId","projectId"],"description":"A selected workflow resolves to a destination id in `deletedWorkflowIds`. The import stops before any writes, including when the conflict policy is `skip`."},{"type":"object","properties":{"type":{"type":"string","enum":["folder-removal-forbidden"]},"folderId":{"type":"string"},"name":{"type":"string"},"projectId":{"type":"string","description":"Project the folder was being reconciled against."}},"required":["type","folderId","name","projectId"],"description":"A folder that `folderConflictPolicy=overwrite` would delete — the package does not define it and reconciliation leaves it empty — but the caller lacks `folder:delete` on the target project. Reported instead of removing a subset, which would leave the project matching neither the package nor its previous state."},{"type":"object","properties":{"type":{"type":"string","enum":["data-table-unresolved"]},"kind":{"type":"string","enum":["missing","id-conflict","name-conflict","schema-incompatible","module-disabled","permission-denied"]},"sourceId":{"type":"string","description":"Absent for import-wide failures (`module-disabled`, `permission-denied`)."},"name":{"type":"string"},"existingProjectId":{"type":"string","description":"For `id-conflict`: the project owning the conflicting target table."},"missingColumns":{"type":"array","items":{"type":"string"},"description":"For `schema-incompatible`: package columns absent from the target table."},"typeMismatches":{"type":"array","items":{"type":"object","properties":{"column":{"type":"string"},"expectedType":{"type":"string"},"actualType":{"type":"string"}},"required":["column","expectedType","actualType"]},"description":"For `schema-incompatible`: package columns whose target type differs."},"extraColumns":{"type":"array","items":{"type":"string"},"description":"For `schema-incompatible` under the `fail` policy: target columns not in the package schema."},"overwriteChanges":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","enum":["add-column"]},"column":{"type":"string"},"type":{"type":"string","enum":["string","number","boolean","date"]},"destructive":{"type":"boolean","enum":[false]}},"required":["kind","column","type","destructive"]},{"type":"object","properties":{"kind":{"type":"string","enum":["remove-column"]},"column":{"type":"string"},"type":{"type":"string","enum":["string","number","boolean","date"]},"destructive":{"type":"boolean","enum":[true]}},"required":["kind","column","type","destructive"]},{"type":"object","properties":{"kind":{"type":"string","enum":["change-column-type"]},"column":{"type":"string"},"from":{"type":"string","enum":["string","number","boolean","date"]},"to":{"type":"string","enum":["string","number","boolean","date"]},"destructive":{"type":"boolean","enum":[true]}},"required":["kind","column","from","to","destructive"]},{"type":"object","properties":{"kind":{"type":"string","enum":["rename-column"]},"from":{"type":"string"},"to":{"type":"string"},"destructive":{"type":"boolean","enum":[false]}},"required":["kind","from","to","destructive"]},{"type":"object","properties":{"kind":{"type":"string","enum":["reorder-columns"]},"destructive":{"type":"boolean","enum":[false]}},"required":["kind","destructive"]},{"type":"object","properties":{"kind":{"type":"string","enum":["rename-table"]},"from":{"type":"string"},"to":{"type":"string"},"destructive":{"type":"boolean","enum":[false]}},"required":["kind","from","to","destructive"]}],"description":"A single change `dataTableSchemaConflictPolicy=overwrite` would make (or made) to a matched target table's schema. `destructive` operations remove the values in a column.","type":"object"},"description":"For `schema-incompatible`: the changes `overwrite` would make to the target table."},"missingScope":{"type":"string","enum":["dataTable:create","dataTable:update"],"description":"For `permission-denied`: the project scope the user lacks."},"conflictingTableId":{"type":"string","description":"For `name-conflict`: the other table that holds or claims the name."},"currentName":{"type":"string","description":"For a rename `name-conflict`: the matched table's current name."},"usedBy":{"type":"array","items":{"$ref":"#/components/schemas/packageRequirementConsumer.generated"}}},"required":["type","kind","usedBy"],"description":"A data table referenced by the package's workflows that could not be resolved against the target project — under `dataTableMissingMode=must-preexist` or `dataTableSchemaConflictPolicy`, or because the data table module is disabled on this instance, or the caller lacks the scope the resolution needs."},{"type":"object","properties":{"type":{"type":"string","enum":["tag-unresolved"]},"kind":{"type":"string","enum":["rename-drift","name-collision","invalid-name","invalid-id","permission-denied"]},"sourceId":{"type":"string","description":"Tag id as it appears in the package. Absent for `permission-denied`."},"name":{"type":"string","description":"The (trimmed) package tag name. Absent for `permission-denied`."},"missingScope":{"type":"string","enum":["tag:create","tag:update"],"description":"For `permission-denied`: the global scope the importing user lacks."},"existingTagId":{"type":"string","description":"Id of the contested target tag — the different tag currently holding the wanted name, or the target tag a blocked reconcile would re-key. Absent when two package tags collide with each other rather than over a target tag."},"existingName":{"type":"string","description":"For `rename-drift`: the current name of the same-id target tag."},"usedBy":{"type":"array","items":{"$ref":"#/components/schemas/packageRequirementConsumer.generated"},"description":"Package consumers that reference the source tag. This excludes skipped consumers and workflows attached to the contested target tag."}},"required":["type","kind","usedBy"],"description":"A tag referenced by the package's workflows that could not be resolved on the target instance. `kind` distinguishes the cause: `rename-drift` (the same-id target tag carries a different name — under `tagConflictPolicy=fail`, or `rename` when the package name is held by another tag), `name-collision` (the id is free but the name belongs to a different tag under `tagMissingMode=create` with `tagConflictPolicy=fail`; also raised when two package tags collide with each other, or when the target tag a reconcile would re-key is claimed by another package tag), `invalid-name` / `invalid-id` (the package tag's name or id cannot be written on this instance), or `permission-denied` (the importing user lacks the global `tag:create` / `tag:update` scope the plan needs)."},{"type":"object","properties":{"type":{"type":"string","enum":["variable-unresolved"]},"name":{"type":"string","description":"Requirement name with no match in the target project or global scope."},"usedBy":{"type":"array","items":{"$ref":"#/components/schemas/packageRequirementConsumer.generated"}}},"required":["type","name","usedBy"],"description":"A variable reference that could not be resolved in the target project or the global scope, under `variableMissingMode=must-preexist`."},{"type":"object","properties":{"type":{"type":"string","enum":["variable-conflict"]},"name":{"type":"string","description":"Name of the variable whose value differs."},"projectId":{"type":"string","description":"Project owning the resolved variable. Absent when it resolved at the global scope."},"usedBy":{"type":"array","items":{"$ref":"#/components/schemas/packageRequirementConsumer.generated"}}},"required":["type","name","usedBy"],"description":"A variable that resolved in the target project or the global scope, but whose value differs from the one the package bundles for it, under `variableConflictPolicy=fail`. Also reported under `overwrite`, once per scope, when the projects of a package resolve one row and disagree about the value it should hold. Values are never reported — only the name and the scope the variable was found in."},{"type":"object","properties":{"type":{"type":"string","enum":["variable-limit-exceeded"]},"limit":{"type":"integer","description":"The instance variable quota."},"remaining":{"type":"integer","description":"Variable rows still available under the quota. The import is blocked because `requested` exceeds this, not because it exceeds `limit`."},"requested":{"type":"integer","description":"Number of new variable rows the import would create (destination-deduplicated)."},"names":{"type":"array","items":{"type":"string"},"description":"The unique variable names the import would create."},"usedBy":{"type":"array","items":{"$ref":"#/components/schemas/packageRequirementConsumer.generated"},"description":"Package consumers that reference any of the listed variables."}},"required":["type","limit","remaining","requested","names","usedBy"],"description":"Creating the package's variables under `create-stub` or `create-with-value` would exceed the instance variable quota (`quota:maxVariables`). Reported once for the whole import; nothing is created."},{"type":"object","properties":{"type":{"type":"string","enum":["missing-node-type"]},"nodeType":{"type":"string","description":"Full node type name as used by the package's workflows."},"typeVersion":{"type":"number","description":"Node type version the package's workflows use."},"usedBy":{"type":"array","items":{"$ref":"#/components/schemas/packageRequirementConsumer.generated"},"description":"Package consumers that use this node type and version."}},"required":["type","nodeType","typeVersion","usedBy"],"description":"A node type — or a version of a node type — used by a package workflow that this instance does not have, under `missingNodeTypeMode=fail`. One issue is reported per missing `(nodeType, typeVersion)` pair."},{"type":"object","properties":{"type":{"type":"string","enum":["policy-violation"]},"sourceWorkflowId":{"type":"string","description":"Workflow id as it appears in the package."},"name":{"type":"string"},"violations":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string"},"checkId":{"type":"string"},"message":{"type":"string"},"subject":{"type":"string"},"subjectType":{"type":"string"},"scope":{"type":"string"},"matchedRuleId":{"type":"string"}},"required":["kind","checkId","message"]}}},"required":["type","sourceWorkflowId","name","violations"],"description":"A workflow the content-import policy refused. Takes down the whole package rather than skipping the workflow: the import rewrites cross-workflow references to the ids each workflow would get, so dropping one leaves the workflows that call it pointing at a row nothing ever wrote."},{"type":"object","properties":{"type":{"type":"string","enum":["credential-policy-violation"]},"sourceId":{"type":"string","description":"Credential id as it appears in the package."},"name":{"type":"string"},"credentialType":{"type":"string"},"usedBy":{"type":"array","items":{"$ref":"#/components/schemas/packageRequirementConsumer.generated"},"description":"Package consumers that use this credential."},"violations":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string"},"checkId":{"type":"string"},"message":{"type":"string"},"subject":{"type":"string"},"subjectType":{"type":"string"},"scope":{"type":"string"},"matchedRuleId":{"type":"string"}},"required":["kind","checkId","message"]}}},"required":["type","sourceId","credentialType","usedBy","violations"],"description":"A credential the import would write that the credential-save policy refused, for example a stub of a credential type this instance does not allow. The import stops before any writes."}],"type":"object"},"packageRequirementConsumer.generated":{"type":"object","properties":{"kind":{"type":"string","enum":["workflow","agent"]},"id":{"type":"string","minLength":1}},"required":["kind","id"]}},"responses":{"badRequest":{"description":"The request is invalid or provides malformed data."},"unauthorized":{"description":"Unauthorized"},"forbidden":{"description":"Forbidden"},"notFound":{"description":"The specified resource was not found."},"contentTooLarge":{"description":"Content too large."},"unsupportedMediaType":{"description":"Unsupported media type."},"internalServerError":{"description":"Internal server error."}}},"paths":{"/n8n-packages/import":{"post":{"operationId":"importPackage","tags":["N8nPackage"],"summary":"Beta: Import an n8n package into a project","description":"**Beta** — breaking changes may still occur without major version bump.\n\nImports a gzip-compressed tar package (`.n8np`) into the target project. Send the archive as the multipart field `package`. Optional routing uses form fields `projectId` and `folderId` (omit or send empty for defaults). Every optional mode/policy field (credential, workflow, project, folder, data table, variable, and tag) takes its default when omitted; the one non-fixed default is `folderConflictPolicy`, which follows `projectConflictPolicy` on a project package. The required `workflowConflictPolicy` field controls what happens when a package workflow matches an existing workflow by source id in the target project. Maximum upload size is `N8N_ENDPOINTS_PAYLOAD_SIZE_MAX` MB (default 16).\n\nThe package must declare its manifest at `manifest.json` and include every file the manifest references.\n\nCredential references are resolved before any workflow is written.","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"package":{"type":"string","description":"Gzip-compressed tar package (`.n8np`).","format":"binary"},"projectId":{"type":"string","description":"Target project id. Omit or send empty to import into the caller's personal project."},"folderId":{"type":"string","description":"Optional folder within the target project. Omit or send empty for project root."},"credentialMatchingMode":{"type":"string","enum":["id-only","name-and-type","type-only"],"default":"id-only","description":"How credential references in `requirements.credentials` are matched on the target instance. `id-only` (default) matches by id. `name-and-type` matches credentials with the exact same name and type. `type-only` matches any credential of the same type. For `name-and-type` and `type-only`, candidates are ranked by scope — a credential owned by the target project wins over one merely shared into it, which in turn wins over a global credential; if several candidates remain in the winning scope, the most recently updated one is chosen."},"credentialMissingMode":{"type":"string","enum":["must-preexist","create-stub"],"default":"create-stub","description":"What to do when a credential reference cannot be resolved. `create-stub` (default) creates empty credential placeholders in the target project for missing references. `must-preexist` requires every referenced credential to already exist."},"bindings":{"type":"string","description":"Optional JSON object of explicit source→target id bindings, keyed by entity type. Only `credentials` is supported today: send `{\"credentials\":{\"<packageCredentialId>\":\"<targetCredentialId>\"}}` to map credential ids from the package to credential ids on the target instance. These explicit bindings are validated on type and applied before `credentialMatchingMode` resolution runs.","default":"{}"},"workflowConflictPolicy":{"type":"string","enum":["new-version","fail","skip"],"description":"`new-version` updates matching workflows and creates a new version; the archived state follows the package, so a matching workflow is archived or unarchived to match it. `fail` rejects the import when any matching workflow exists, and `skip` leaves matching workflows unchanged. Archived workflows in the target project match like any other. An archive state change also needs the `workflow:delete` scope."},"workflowPublishingPolicy":{"type":"string","enum":["preserve-published-state","match-source","publish-all","unpublish-all"],"default":"preserve-published-state","description":"Controls whether imported workflows are published after content is written. `preserve-published-state` (default) keeps new workflows inactive, and republishes an updated workflow only when it was already published and the package carries the version the source publishes — so drafts are never published. `match-source` publishes the version the package carries when the source publishes it, and unpublishes when the source publishes nothing; when the source publishes a version the package does not carry, the target keeps its published version. `publish-all` publishes every imported workflow. `unpublish-all` leaves new workflows inactive and unpublishes updated workflows that were published."},"workflowIdPolicy":{"type":"string","enum":["new","source"],"default":"source","description":"Controls the id each newly created workflow receives. `source` (default) reuses the package's own workflow id on the target instance, which best fits promotion use cases where the same workflow moves between environments. `new` mints a fresh id and records the package id as `sourceWorkflowId`, so the same package can be imported repeatedly without id collisions — best suited to marketplace imports. Workflows matched to an existing workflow in the target project (status `updated` or `skipped`) always keep that workflow's current id, regardless of policy."},"missingNodeTypeMode":{"type":"string","enum":["fail","import-anyway"],"default":"fail","description":"What to do when a workflow in the package uses a node type — or a version of a node type — this instance does not have. `fail` (default) rejects the import before anything is written, listing every missing `(nodeType, typeVersion)` pair and the workflows that use it. `import-anyway` imports the package; workflows containing missing node types are never published by this import, regardless of `workflowPublishingPolicy`."},"projectConflictPolicy":{"type":"string","enum":["merge","fail","overwrite"],"default":"merge","description":"What to do when a project the package defines already exists here (matched by id), and — unless `folderConflictPolicy` overrides it — how its contents are treated. `merge` (default) leaves the existing project's name, description, icon and custom span attributes untouched and adds the package's contents alongside. `overwrite` replaces those details with the package's; a detail the package omits is left as it is, not cleared. `fail` rejects the import before anything is written, with one `project-conflict` issue per existing project. A package project id belonging to a personal project, or to a team project the caller cannot update, always rejects the import. Ignored for workflow packages."},"folderConflictPolicy":{"type":"string","enum":["merge","fail","overwrite"],"description":"What to do when a package folder already exists at the same position in the target project. Defaults to whatever `projectConflictPolicy` is, so the intent is stated once; a workflow package defines no projects, so it defaults to `merge` there. `merge` reuses the existing folder and merges the package's children into it. `fail` rejects the import. `overwrite` reuses folders as `merge` does and additionally removes workflows the package does not contain — at a project's root and in folders the package defines, leaving target-only folders and their contents alone. Folders it does not define are then removed too, but only once nothing is left inside them. Removals are listed under `removedWorkflows` and `removedFolders`; see `overwriteDeletionPolicy`. A folder whose id sits under a different parent, or belongs to another project, always blocks the import. `overwrite` is project-packages-only, needs the `workflow:delete` and `folder:delete` scopes, is rejected against a `projectConflictPolicy` other than `overwrite`, and blocks up front if the caller cannot delete something it would remove. Folders need the `folder:create` scope and a folders-enabled licence."},"overwriteDeletionPolicy":{"type":"string","enum":["archive","hard-delete"],"default":"archive","description":"How `folderConflictPolicy=overwrite` removes a workflow the package does not contain. `archive` (default) archives it, so it stays recoverable along with its execution history. `hard-delete` archives it — the step that unpublishes it, which a delete will not do on its own — and then deletes the workflow and its executions permanently. Each entry in `removedWorkflows` reports what actually happened in its `deletion` field: a `hard-delete` whose row cannot be dropped yet, because unpublishing defers trigger teardown, is left `archived` rather than failing an import whose content is already written. Ignored unless `folderConflictPolicy` is `overwrite`."},"dataTableMatchingMode":{"type":"string","enum":["by-id"],"default":"by-id","description":"How data tables referenced by the package's workflows are matched against the target project. `by-id` matches the target-project table with the same id (imported tables keep their source id) and never falls back to name matching, so a match survives a rename on the target. Currently the only mode."},"dataTableMissingMode":{"type":"string","enum":["create","must-preexist","do-nothing"],"default":"create","description":"Controls what happens when a referenced data table has no match in the target project. `create` (default) creates it from the package schema, keeping the source id, with no rows; requires the `dataTable:create` scope. `must-preexist` rejects the import. `do-nothing` skips creation of missing tables. Under the `keep-existing`, `fail`, and `overwrite-non-destructive` schema conflict policies, matched tables are still validated for schema compatibility and can still block the import. The import never imports table rows. Matched tables change only under `dataTableSchemaConflictPolicy=overwrite` or `overwrite-non-destructive`, which keep their rows."},"dataTableSchemaConflictPolicy":{"type":"string","enum":["keep-existing","fail","overwrite","overwrite-non-destructive"],"default":"keep-existing","description":"How strictly a matched data table's schema is compared. `keep-existing` (default) accepts a target table that has every package column with the same name and type. The target table can have extra columns. `fail` rejects any difference, including target-only columns. Under `keep-existing` and `fail`, a missing package column or a type mismatch rejects the import, and the target table does not change.\n\n`overwrite` changes the matched target table to match the package. It can remove or retype columns. The values in those columns are removed. Rows and other columns are kept. When the package has column ids, a column that is only renamed keeps its values. The changes apply to all workflows that use the table. A blocked `keep-existing`, `fail`, or `overwrite-non-destructive` import lists them in `overwriteChanges`. Requires the `dataTable:update` scope only when a matched table changes.\n\n`overwrite-non-destructive` makes the same changes as `overwrite`, but rejects the import and writes nothing when a change removes or retypes a column. A target-only column counts as removed."},"variableMissingMode":{"type":"string","enum":["do-nothing","must-preexist","create-stub","create-with-value"],"default":"create-with-value","description":"Controls what happens when a variable referenced by the package's workflows is absent from the target project and the global scope (lookup order: project, then global). `create-with-value` (default) creates the variable with its package value and lists its name under `variables.created`. When the package carries no value for it — values were excluded at export, or the exported value was itself empty — it creates an empty stub listed under `variables.stubbed`. `do-nothing` imports without creating the variable and lists its name under `variables.missing`. `must-preexist` rejects the import unless every referenced variable already resolves. `create-stub` creates each missing variable with an empty value at the placement scope (see `variableParentPolicy`) and lists the created names under `variables.stubbed`. An import that actually creates a variable requires a license that permits variables and, for API key callers, the `variable:create` scope; a package whose variables all already resolve creates nothing and needs neither."},"variableConflictPolicy":{"type":"string","enum":["keep-existing","overwrite","fail"],"default":"keep-existing","description":"What to do when a referenced variable resolves in the target project or global scope but the package bundles a *different* value for it. `keep-existing` (default) leaves the target value untouched and reports the name under `variables.matched`. `overwrite` silently replaces the value of the existing variable at whichever scope it was found — the target project or the global scope, so a global variable other projects also read can be rewritten by this import — and reports the name under `variables.updated`; it needs a license that permits variables, the `variable:update` / `projectVariable:update` permission on that scope, and, for API key callers, the `variable:update` scope. `fail` rejects the import with a 409 instead. Every policy leaves a resolved variable alone when there is nothing to change — either the package bundles no value for it (values were excluded at export, or the exported value was itself empty), or the value it bundles already matches the target's. The reverse does not hold: a resolved variable holding an empty value — a stub an earlier import created, say — still counts as a value, so `overwrite` fills it and `fail` rejects it. Under `overwrite`, a project package whose projects hold *different* values for a name they all resolve to one row — a global none of them shadows, typically — is rejected with a 409: one row cannot carry both values, and the import will not pick for you. Give the projects their own variables in the target, or import them separately."},"variableParentPolicy":{"type":"string","enum":["project","global"],"description":"Where `create-with-value` and `create-stub` create missing variables for workflow/folder packages. `project` — also the behaviour when the field is omitted — creates them in the import target project (`projectId`, else the caller's personal project). `global` creates them at the global scope. The license and `variable:create` requirements described under `variableMissingMode` apply to both placements. Must be omitted for project packages, which reject it with a 400: their placement follows the package layout, where a variable bundled under a project is created in that project and one bundled at the top level is created globally."},"tagMissingMode":{"type":"string","enum":["create","do-nothing"],"default":"create","description":"What to do when a tag referenced by the package's workflows has no tag with the same id on the target instance (tags are matched by source id, never by name). `create` (default) creates the tag globally with its package (source) id and name; when the import would create a tag this needs an API key carrying the `tag:create` scope. `do-nothing` imports the workflows without the missing tags — nothing is created and the dropped names are listed under `tags.skipped`."},"tagConflictPolicy":{"type":"string","enum":["skip","fail","rename"],"default":"skip","description":"What to do when a referenced tag conflicts on the target instance — either the same-id target tag carries a different name (rename drift), or the tag's name is already held by a different tag (name collision). `skip` (default) drops the conflicted tags from the import (not created, not renamed, not attached anywhere; the import proceeds and lists them under `tags.skipped`). `fail` rejects the import with a 409. `rename` renames a drifted target tag to the package name, and reconciles a name collision by re-keying the existing tag to the package (source) id — its name, workflow and folder taggings follow; both need an API key carrying the `tag:update` scope when the import would rename or reconcile a tag. A drifted tag whose package name is held by another tag still rejects the import (rename degrades to fail)."}},"required":["package","workflowConflictPolicy"],"additionalProperties":false}}}},"responses":{"200":{"description":"Operation successful.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/importResultDto.generated"}}}},"400":{"$ref":"#/components/responses/badRequest"},"401":{"$ref":"#/components/responses/unauthorized"},"403":{"$ref":"#/components/responses/forbidden"},"404":{"$ref":"#/components/responses/notFound"},"409":{"description":"Import blocked by at least one conflict among the issues — a workflow source-id conflict, a folder conflict, a tag conflict (rename drift or name collision), a data table conflict (id owned by another project, or a name that another table in the project has), a variable whose bundled value differs from the resolved target, or a selected destination also named for deletion.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"issues":{"type":"array","items":{"$ref":"#/components/schemas/importBlockingIssue.generated"}}},"required":["message","issues"]}}}},"413":{"$ref":"#/components/responses/contentTooLarge"},"415":{"$ref":"#/components/responses/unsupportedMediaType"},"422":{"description":"Import blocked by non-conflict issues only — for example unresolved credentials or variables, node types this instance does not have, a delete the caller may not perform, or variable stubs whose creation would exceed the instance variable quota.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"issues":{"type":"array","items":{"$ref":"#/components/schemas/importBlockingIssue.generated"}}},"required":["message","issues"]}}}},"500":{"$ref":"#/components/responses/internalServerError"}}}}}}
```

## Beta: Import a selected subset of workflows from an n8n package

> \*\*Beta\*\* — breaking changes may still occur without major version bump.\
> \
> Imports a chosen subset of workflows from one source project of a gzip-compressed tar package (\`.n8np\`), instead of the whole package. Send the archive as the multipart field \`package\`. The import is \*\*additive\*\* (cherry-pick): it never removes a workflow the selection omits. It creates or updates only the workflows named in \`selectedWorkflowIds\`, and deletes only the destination workflows named in \`deletedWorkflowIds\`.\
> \
> \`selectedProjectId\` names the single source project the selection is scoped to (its id as it appears in the package). The selected workflows are written into the instance project whose id matches that source project, which is created if it does not yet exist; there is no separate target-project field. \`selectedWorkflowIds\` are source ids within that project; ids that belong to another project are dropped. \`deletedWorkflowIds\` are destination ids in the same project; an absent id is a tolerated no-op, and a delete needs the \`workflow:delete\` scope. A delete id must not match the destination id of a selected workflow, including when \`workflowConflictPolicy=skip\`. This overlap returns a 409 before any writes.\
> \
> The package must be a project package (a workflow package is rejected with a 400). The cherry-pick conflict policies (folder, tag, and project) are fixed and are not accepted here; only \`workflowConflictPolicy\`, \`workflowIdPolicy\`, and \`overwriteDeletionPolicy\` are configurable. Maximum upload size is \`N8N\_ENDPOINTS\_PAYLOAD\_SIZE\_MAX\` MB (default 16). The caller is authorised through the \`workflow:import\` scope.

```json
{"openapi":"3.0.0","info":{"title":"n8n Public API","version":"1.1.1"},"tags":[{"name":"N8nPackage","description":"Beta — breaking changes may still occur without major version bump."}],"servers":[{"url":"/api/v1","description":"Current n8n instance (self-hosted built-in playground)"},{"url":"{url}/api/v1","description":"Self-hosted n8n instance","variables":{"url":{"default":"https://example.com"}}}],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]},{"CookieAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-N8N-API-KEY"},"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"},"CookieAuth":{"type":"apiKey","in":"cookie","name":"n8n-auth"}},"schemas":{"importResultDto.generated":{"type":"object","properties":{"package":{"type":"object","properties":{"sourceN8nVersion":{"type":"string"},"sourceId":{"type":"string"},"exportedAt":{"type":"string","format":"date-time"}},"required":["sourceN8nVersion","sourceId","exportedAt"]},"workflows":{"type":"array","items":{"type":"object","properties":{"sourceWorkflowId":{"type":"string","description":"Workflow id as it appeared in the package."},"localId":{"type":"string","description":"Workflow id on the target instance: newly assigned for `created` (fresh under `workflowIdPolicy=new`, the package id under `source`), the existing workflow's id for `updated`/`skipped`."},"name":{"type":"string"},"projectId":{"type":"string"},"parentFolderId":{"type":"string","nullable":true},"activeVersionId":{"type":"string","nullable":true,"description":"Published version on the target instance, if any. `null` when the workflow is not published after import."},"isArchived":{"type":"boolean","description":"Whether the workflow is archived on the target after import. Under `new-version` this follows the package's `isArchived` flag. A skipped workflow keeps its own state."},"publishing":{"type":"object","properties":{"state":{"type":"string","enum":["published","unpublished","unchanged","blocked","failed"],"description":"`blocked` means the imported version could not be published and no version is active (for example because the workflow uses a stubbed credential, or uses a node type this instance does not have). When a prior published version remains active, `state` is `unchanged` with `skippedPublishReason` instead. `failed` means publish or unpublish was attempted but did not succeed."},"error":{"type":"string","description":"Present when `state` is `failed`. Explains why publish or unpublish could not be applied."},"blockedReason":{"type":"string","enum":["stub-credential","missing-node-type"],"description":"Present when `state` is `blocked`: the imported version could not be published and no version is active."},"skippedPublishReason":{"type":"string","enum":["stub-credential","missing-node-type"],"description":"Present when `state` is `unchanged` but the policy wanted to publish the imported version: a prior published version is still active (for example after an update with stubbed credentials)."}},"required":["state"],"description":"Outcome of applying the selected publishing policy to this workflow."},"status":{"type":"string","enum":["created","updated","skipped"],"description":"Import outcome for this package workflow."}},"required":["sourceWorkflowId","localId","name","projectId","parentFolderId","activeVersionId","isArchived","publishing","status"]}},"removedWorkflows":{"type":"array","items":{"type":"object","properties":{"workflowId":{"type":"string","description":"Id of the removed workflow on this instance."},"name":{"type":"string"},"projectId":{"type":"string","description":"Project the workflow was reconciled against."},"parentFolderId":{"type":"string","nullable":true,"description":"Folder that held the workflow, or null at the project root."},"deletion":{"type":"string","enum":["archived","deleted"],"description":"What actually happened, not what `overwriteDeletionPolicy` asked for: a `hard-delete` whose row could not be dropped yet is reported as `archived`."}},"required":["workflowId","name","projectId","parentFolderId","deletion"]},"description":"Workflows removed from the target during this import."},"removedFolders":{"type":"array","items":{"type":"object","properties":{"folderId":{"type":"string"},"name":{"type":"string"},"projectId":{"type":"string"},"parentFolderId":{"type":"string","nullable":true,"description":"Folder that held it, or null at the project root."}},"required":["folderId","name","projectId","parentFolderId"]},"description":"Folders the package does not define that reconciliation left empty, removed by `folderConflictPolicy=overwrite`. A folder still holding anything survives, so target-only content is never swept up. Empty under every other policy."},"folders":{"type":"array","items":{"type":"object","properties":{"sourceFolderId":{"type":"string","description":"Folder id as it appeared in the package."},"localId":{"type":"string","description":"Folder id on the target instance (equal to `sourceFolderId`; folder ids are reused)."},"name":{"type":"string"},"parentFolderId":{"type":"string","nullable":true,"description":"Resolved parent folder on the target, or `null` at the project root."},"status":{"type":"string","enum":["created","skipped"],"description":"Import outcome for this package folder."}},"required":["sourceFolderId","localId","name","parentFolderId","status"]},"description":"Folder shells created or skipped in the target project."},"projects":{"type":"array","items":{"type":"object","properties":{"sourceProjectId":{"type":"string","description":"Project id as it appeared in the package."},"localId":{"type":"string","description":"Project id on the target instance (equal to `sourceProjectId`; project ids are reused)."},"name":{"type":"string","description":"The project's name on the target: the package's under `overwrite`, the pre-existing one under `merge`."},"status":{"type":"string","enum":["created","updated","skipped"],"description":"Import outcome for this package project. `skipped` means the project already existed and `projectConflictPolicy=merge` left its details untouched — its contents were still imported."}},"required":["sourceProjectId","localId","name","status"]},"description":"Project shells created, or matched and then updated or left as-is (see `projectConflictPolicy`). Present for project packages; empty when importing loose workflows/folders."},"bindings":{"type":"object","properties":{"workflows":{"type":"object","additionalProperties":{"type":"string"}},"credentials":{"type":"object","additionalProperties":{"type":"string"},"description":"Credential id from `requirements.credentials` in the package manifest → resolved target credential id on the target instance. Covers both a matched existing credential and a credential created as a stub under `credentialMissingMode=create-stub`."}},"required":["workflows","credentials"],"description":"Source id → target id mappings produced during import, one map per entity type. Each value maps an id as it appeared in the package to the id on the target instance."},"credentials":{"type":"object","properties":{"matched":{"type":"array","items":{"type":"string"},"description":"Source credential ids from the package that matched existing credentials on the target instance."},"stubbed":{"type":"array","items":{"type":"string"},"description":"Source credential ids for which empty placeholder credentials were created in the target project."}},"required":["matched","stubbed"],"description":"Source credential ids grouped by whether they matched an existing credential or were created as stubs. Full source→target id mapping is in `bindings.credentials`."},"dataTables":{"type":"object","properties":{"matched":{"type":"integer","minimum":0},"created":{"type":"integer","minimum":0},"updated":{"type":"integer","minimum":0}},"required":["matched","created","updated"]},"variables":{"type":"object","properties":{"matched":{"type":"array","items":{"type":"string"},"description":"Variable names that resolved to an existing variable (importing project's scope first, then global) and were left untouched. A resolved variable this import rewrote is listed under `updated` instead."},"missing":{"type":"array","items":{"type":"string"},"description":"Variable names still unresolved after import. Under `variableMissingMode=do-nothing` these are warnings — the import still succeeds and nothing is created. A successful `create-stub` or `create-with-value` import normally leaves this empty."},"created":{"type":"array","items":{"type":"string"},"description":"Variable names created with a package value under `variableMissingMode=create-with-value`. Empty stubs are listed under `stubbed`."},"stubbed":{"type":"array","items":{"type":"string"},"description":"Variable names created with an empty value by this import under `variableMissingMode=create-stub`, or because `create-with-value` had no exported value. Empty for other outcomes."},"updated":{"type":"array","items":{"type":"string"},"description":"Variable names whose existing value this import replaced with the package value under `variableConflictPolicy=overwrite`. Empty for other policies."}},"required":["matched","missing","created","stubbed","updated"],"description":"Resolution of the package's variable requirements. Names only — values never travel in the response. For project packages these arrays are package-level unions of per-destination outcomes and may overlap (for example, a name may be created with a value in one project and stubbed in another); classification under concurrent external writes is best-effort."},"tags":{"type":"object","properties":{"matched":{"type":"array","items":{"type":"string"},"description":"Tags that resolved to an existing tag with the same id and name; attached as-is."},"created":{"type":"array","items":{"type":"string"},"description":"Tags created by this import, by name, under `tagMissingMode=create`."},"renamed":{"type":"array","items":{"type":"string"},"description":"Target tags renamed to the package name under `tagConflictPolicy=rename`; listed by their new name."},"reconciled":{"type":"array","items":{"type":"string"},"description":"Existing target tags re-keyed to the package (source) id on a name collision under `tagConflictPolicy=rename`; their name, workflow and folder taggings are kept."},"skipped":{"type":"array","items":{"type":"string"},"description":"Tags dropped from the import — not created, not renamed, and not attached to any imported workflow — under `tagMissingMode=do-nothing` or `tagConflictPolicy=skip`."}},"required":["matched","created","renamed","reconciled","skipped"],"description":"Resolution of the tags referenced by the imported workflows, matched by source id. Tag names only."}},"required":["package","workflows","removedWorkflows","removedFolders","folders","projects","bindings","credentials","dataTables","variables","tags"]},"importBlockingIssue.generated":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["workflow-conflict"]},"sourceWorkflowId":{"type":"string"},"existingWorkflowId":{"type":"string"},"name":{"type":"string"}},"required":["type","sourceWorkflowId","existingWorkflowId","name"],"description":"A workflow whose source id already matches one in the target project, under the `fail` conflict policy."},{"type":"object","properties":{"type":{"type":"string","enum":["workflow-lineage-conflict"]},"sourceWorkflowId":{"type":"string"},"projectId":{"type":"string"},"existingWorkflows":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"isArchived":{"type":"boolean"}},"required":["id","name","isArchived"]}}},"required":["type","sourceWorkflowId","projectId","existingWorkflows"],"description":"A package workflow whose source id matches multiple workflows in the target project. The import cannot choose a workflow safely."},{"type":"object","properties":{"type":{"type":"string","enum":["workflow-id-conflict"]},"sourceWorkflowId":{"type":"string"},"existingWorkflowId":{"type":"string"},"existingProjectId":{"type":"string","nullable":true,"description":"Project that owns the existing workflow, or null when no owning project could be determined."},"isArchived":{"type":"boolean","description":"Whether the existing workflow is archived."},"name":{"type":"string"}},"required":["type","sourceWorkflowId","existingWorkflowId","existingProjectId","isArchived","name"],"description":"A `source`-policy workflow whose id is already taken on the instance. Workflow ids are globally unique, so the id cannot be created in the target project. The existing workflow can be in another project, can lack an owner share, or can use a different source id. It can also be archived."},{"type":"object","properties":{"type":{"type":"string","enum":["workflow-folder-conflict"]},"sourceWorkflowId":{"type":"string"},"existingWorkflowId":{"type":"string"},"existingParentFolderId":{"type":"string","nullable":true,"description":"Folder that currently contains the matched workflow, or null when it lives at the project root."},"targetFolderId":{"type":"string","description":"Folder the import was requested to land in."},"name":{"type":"string"}},"required":["type","sourceWorkflowId","existingWorkflowId","existingParentFolderId","targetFolderId","name"],"description":"A workflow whose source id already matches one in the target project but lives outside the requested import folder. Folder-targeted imports cannot update workflows in place at a different location."},{"type":"object","properties":{"type":{"type":"string","enum":["workflow-archive-forbidden"]},"sourceWorkflowId":{"type":"string"},"existingWorkflowId":{"type":"string"},"name":{"type":"string"},"projectId":{"type":"string","description":"Project that owns the matched workflow."},"transition":{"type":"string","enum":["archive","unarchive"],"description":"The step the import needs to bring the workflow to the package's state."}},"required":["type","sourceWorkflowId","existingWorkflowId","name","projectId","transition"],"description":"A matched workflow whose archived state differs from the package, so the import must archive or unarchive it, but the caller lacks `workflow:delete` on it. Reported at plan time so nothing is written."},{"type":"object","properties":{"type":{"type":"string","enum":["credential-unresolved"]},"kind":{"type":"string","enum":["not_found","unknown_type","source_not_found","type_mismatch"]},"sourceId":{"type":"string"},"targetId":{"type":"string","description":"Target credential id: for `not_found`, the explicit binding that could not be resolved; for `type_mismatch`, the credential id that was resolved — via an explicit binding or automatic matching — but has the wrong type."},"expectedType":{"type":"string","description":"For `type_mismatch`: the credential type the package's workflow node requires."},"actualType":{"type":"string","description":"For `type_mismatch`: the actual type of the resolved target credential."},"usedBy":{"type":"array","items":{"$ref":"#/components/schemas/packageRequirementConsumer.generated"}}},"required":["type","kind","sourceId","usedBy"],"description":"A credential reference that could not be resolved in the target project."},{"type":"object","properties":{"type":{"type":"string","enum":["project-conflict"]},"kind":{"type":"string","enum":["fail-policy"]},"sourceProjectId":{"type":"string"},"name":{"type":"string","description":"The project's name as it appears in the package."}},"required":["type","kind","sourceProjectId","name"],"description":"A project defined by the package that already exists on this instance, under `projectConflictPolicy=fail`."},{"type":"object","properties":{"type":{"type":"string","enum":["folder-conflict"]},"kind":{"type":"string","enum":["parent-mismatch","id-in-other-project","fail-policy"]},"sourceFolderId":{"type":"string"},"name":{"type":"string"},"existingParentFolderId":{"type":"string","nullable":true,"description":"For `parent-mismatch`: the matched folder's current parent in the target."},"expectedParentFolderId":{"type":"string","nullable":true,"description":"For `parent-mismatch`: the parent the package would place the folder under."},"existingProjectId":{"type":"string","nullable":true,"description":"For `id-in-other-project`: the project that already owns the id."}},"required":["type","kind","sourceFolderId","name"],"description":"A package folder that cannot be imported as-is. `kind` distinguishes the cause: `parent-mismatch` (a folder matched by id sits under a different parent than the package places it), `id-in-other-project` (the folder id already exists in a different project — ids are globally unique), or `fail-policy` (the folder already exists and `folderConflictPolicy` is `fail`)."},{"type":"object","properties":{"type":{"type":"string","enum":["workflow-removal-forbidden"]},"workflowId":{"type":"string"},"name":{"type":"string"},"projectId":{"type":"string","description":"Project the workflow was being reconciled against."}},"required":["type","workflowId","name","projectId"],"description":"A workflow the import would remove but the caller lacks `workflow:delete` on: either `folderConflictPolicy=overwrite` would remove it because the package does not contain it, or it is named in the selection's `deletedWorkflowIds`. Reported instead of removing a subset, which would leave the project matching neither the package nor its previous state."},{"type":"object","properties":{"type":{"type":"string","enum":["workflow-removal-conflict"]},"sourceWorkflowId":{"type":"string"},"workflowId":{"type":"string","description":"The destination id of the selected workflow."},"projectId":{"type":"string"}},"required":["type","sourceWorkflowId","workflowId","projectId"],"description":"A selected workflow resolves to a destination id in `deletedWorkflowIds`. The import stops before any writes, including when the conflict policy is `skip`."},{"type":"object","properties":{"type":{"type":"string","enum":["folder-removal-forbidden"]},"folderId":{"type":"string"},"name":{"type":"string"},"projectId":{"type":"string","description":"Project the folder was being reconciled against."}},"required":["type","folderId","name","projectId"],"description":"A folder that `folderConflictPolicy=overwrite` would delete — the package does not define it and reconciliation leaves it empty — but the caller lacks `folder:delete` on the target project. Reported instead of removing a subset, which would leave the project matching neither the package nor its previous state."},{"type":"object","properties":{"type":{"type":"string","enum":["data-table-unresolved"]},"kind":{"type":"string","enum":["missing","id-conflict","name-conflict","schema-incompatible","module-disabled","permission-denied"]},"sourceId":{"type":"string","description":"Absent for import-wide failures (`module-disabled`, `permission-denied`)."},"name":{"type":"string"},"existingProjectId":{"type":"string","description":"For `id-conflict`: the project owning the conflicting target table."},"missingColumns":{"type":"array","items":{"type":"string"},"description":"For `schema-incompatible`: package columns absent from the target table."},"typeMismatches":{"type":"array","items":{"type":"object","properties":{"column":{"type":"string"},"expectedType":{"type":"string"},"actualType":{"type":"string"}},"required":["column","expectedType","actualType"]},"description":"For `schema-incompatible`: package columns whose target type differs."},"extraColumns":{"type":"array","items":{"type":"string"},"description":"For `schema-incompatible` under the `fail` policy: target columns not in the package schema."},"overwriteChanges":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","enum":["add-column"]},"column":{"type":"string"},"type":{"type":"string","enum":["string","number","boolean","date"]},"destructive":{"type":"boolean","enum":[false]}},"required":["kind","column","type","destructive"]},{"type":"object","properties":{"kind":{"type":"string","enum":["remove-column"]},"column":{"type":"string"},"type":{"type":"string","enum":["string","number","boolean","date"]},"destructive":{"type":"boolean","enum":[true]}},"required":["kind","column","type","destructive"]},{"type":"object","properties":{"kind":{"type":"string","enum":["change-column-type"]},"column":{"type":"string"},"from":{"type":"string","enum":["string","number","boolean","date"]},"to":{"type":"string","enum":["string","number","boolean","date"]},"destructive":{"type":"boolean","enum":[true]}},"required":["kind","column","from","to","destructive"]},{"type":"object","properties":{"kind":{"type":"string","enum":["rename-column"]},"from":{"type":"string"},"to":{"type":"string"},"destructive":{"type":"boolean","enum":[false]}},"required":["kind","from","to","destructive"]},{"type":"object","properties":{"kind":{"type":"string","enum":["reorder-columns"]},"destructive":{"type":"boolean","enum":[false]}},"required":["kind","destructive"]},{"type":"object","properties":{"kind":{"type":"string","enum":["rename-table"]},"from":{"type":"string"},"to":{"type":"string"},"destructive":{"type":"boolean","enum":[false]}},"required":["kind","from","to","destructive"]}],"description":"A single change `dataTableSchemaConflictPolicy=overwrite` would make (or made) to a matched target table's schema. `destructive` operations remove the values in a column.","type":"object"},"description":"For `schema-incompatible`: the changes `overwrite` would make to the target table."},"missingScope":{"type":"string","enum":["dataTable:create","dataTable:update"],"description":"For `permission-denied`: the project scope the user lacks."},"conflictingTableId":{"type":"string","description":"For `name-conflict`: the other table that holds or claims the name."},"currentName":{"type":"string","description":"For a rename `name-conflict`: the matched table's current name."},"usedBy":{"type":"array","items":{"$ref":"#/components/schemas/packageRequirementConsumer.generated"}}},"required":["type","kind","usedBy"],"description":"A data table referenced by the package's workflows that could not be resolved against the target project — under `dataTableMissingMode=must-preexist` or `dataTableSchemaConflictPolicy`, or because the data table module is disabled on this instance, or the caller lacks the scope the resolution needs."},{"type":"object","properties":{"type":{"type":"string","enum":["tag-unresolved"]},"kind":{"type":"string","enum":["rename-drift","name-collision","invalid-name","invalid-id","permission-denied"]},"sourceId":{"type":"string","description":"Tag id as it appears in the package. Absent for `permission-denied`."},"name":{"type":"string","description":"The (trimmed) package tag name. Absent for `permission-denied`."},"missingScope":{"type":"string","enum":["tag:create","tag:update"],"description":"For `permission-denied`: the global scope the importing user lacks."},"existingTagId":{"type":"string","description":"Id of the contested target tag — the different tag currently holding the wanted name, or the target tag a blocked reconcile would re-key. Absent when two package tags collide with each other rather than over a target tag."},"existingName":{"type":"string","description":"For `rename-drift`: the current name of the same-id target tag."},"usedBy":{"type":"array","items":{"$ref":"#/components/schemas/packageRequirementConsumer.generated"},"description":"Package consumers that reference the source tag. This excludes skipped consumers and workflows attached to the contested target tag."}},"required":["type","kind","usedBy"],"description":"A tag referenced by the package's workflows that could not be resolved on the target instance. `kind` distinguishes the cause: `rename-drift` (the same-id target tag carries a different name — under `tagConflictPolicy=fail`, or `rename` when the package name is held by another tag), `name-collision` (the id is free but the name belongs to a different tag under `tagMissingMode=create` with `tagConflictPolicy=fail`; also raised when two package tags collide with each other, or when the target tag a reconcile would re-key is claimed by another package tag), `invalid-name` / `invalid-id` (the package tag's name or id cannot be written on this instance), or `permission-denied` (the importing user lacks the global `tag:create` / `tag:update` scope the plan needs)."},{"type":"object","properties":{"type":{"type":"string","enum":["variable-unresolved"]},"name":{"type":"string","description":"Requirement name with no match in the target project or global scope."},"usedBy":{"type":"array","items":{"$ref":"#/components/schemas/packageRequirementConsumer.generated"}}},"required":["type","name","usedBy"],"description":"A variable reference that could not be resolved in the target project or the global scope, under `variableMissingMode=must-preexist`."},{"type":"object","properties":{"type":{"type":"string","enum":["variable-conflict"]},"name":{"type":"string","description":"Name of the variable whose value differs."},"projectId":{"type":"string","description":"Project owning the resolved variable. Absent when it resolved at the global scope."},"usedBy":{"type":"array","items":{"$ref":"#/components/schemas/packageRequirementConsumer.generated"}}},"required":["type","name","usedBy"],"description":"A variable that resolved in the target project or the global scope, but whose value differs from the one the package bundles for it, under `variableConflictPolicy=fail`. Also reported under `overwrite`, once per scope, when the projects of a package resolve one row and disagree about the value it should hold. Values are never reported — only the name and the scope the variable was found in."},{"type":"object","properties":{"type":{"type":"string","enum":["variable-limit-exceeded"]},"limit":{"type":"integer","description":"The instance variable quota."},"remaining":{"type":"integer","description":"Variable rows still available under the quota. The import is blocked because `requested` exceeds this, not because it exceeds `limit`."},"requested":{"type":"integer","description":"Number of new variable rows the import would create (destination-deduplicated)."},"names":{"type":"array","items":{"type":"string"},"description":"The unique variable names the import would create."},"usedBy":{"type":"array","items":{"$ref":"#/components/schemas/packageRequirementConsumer.generated"},"description":"Package consumers that reference any of the listed variables."}},"required":["type","limit","remaining","requested","names","usedBy"],"description":"Creating the package's variables under `create-stub` or `create-with-value` would exceed the instance variable quota (`quota:maxVariables`). Reported once for the whole import; nothing is created."},{"type":"object","properties":{"type":{"type":"string","enum":["missing-node-type"]},"nodeType":{"type":"string","description":"Full node type name as used by the package's workflows."},"typeVersion":{"type":"number","description":"Node type version the package's workflows use."},"usedBy":{"type":"array","items":{"$ref":"#/components/schemas/packageRequirementConsumer.generated"},"description":"Package consumers that use this node type and version."}},"required":["type","nodeType","typeVersion","usedBy"],"description":"A node type — or a version of a node type — used by a package workflow that this instance does not have, under `missingNodeTypeMode=fail`. One issue is reported per missing `(nodeType, typeVersion)` pair."},{"type":"object","properties":{"type":{"type":"string","enum":["policy-violation"]},"sourceWorkflowId":{"type":"string","description":"Workflow id as it appears in the package."},"name":{"type":"string"},"violations":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string"},"checkId":{"type":"string"},"message":{"type":"string"},"subject":{"type":"string"},"subjectType":{"type":"string"},"scope":{"type":"string"},"matchedRuleId":{"type":"string"}},"required":["kind","checkId","message"]}}},"required":["type","sourceWorkflowId","name","violations"],"description":"A workflow the content-import policy refused. Takes down the whole package rather than skipping the workflow: the import rewrites cross-workflow references to the ids each workflow would get, so dropping one leaves the workflows that call it pointing at a row nothing ever wrote."},{"type":"object","properties":{"type":{"type":"string","enum":["credential-policy-violation"]},"sourceId":{"type":"string","description":"Credential id as it appears in the package."},"name":{"type":"string"},"credentialType":{"type":"string"},"usedBy":{"type":"array","items":{"$ref":"#/components/schemas/packageRequirementConsumer.generated"},"description":"Package consumers that use this credential."},"violations":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string"},"checkId":{"type":"string"},"message":{"type":"string"},"subject":{"type":"string"},"subjectType":{"type":"string"},"scope":{"type":"string"},"matchedRuleId":{"type":"string"}},"required":["kind","checkId","message"]}}},"required":["type","sourceId","credentialType","usedBy","violations"],"description":"A credential the import would write that the credential-save policy refused, for example a stub of a credential type this instance does not allow. The import stops before any writes."}],"type":"object"},"packageRequirementConsumer.generated":{"type":"object","properties":{"kind":{"type":"string","enum":["workflow","agent"]},"id":{"type":"string","minLength":1}},"required":["kind","id"]}},"responses":{"badRequest":{"description":"The request is invalid or provides malformed data."},"unauthorized":{"description":"Unauthorized"},"forbidden":{"description":"Forbidden"},"notFound":{"description":"The specified resource was not found."},"contentTooLarge":{"description":"Content too large."},"unsupportedMediaType":{"description":"Unsupported media type."},"internalServerError":{"description":"Internal server error."}}},"paths":{"/n8n-packages/import-selection":{"post":{"operationId":"importPackageSelection","tags":["N8nPackage"],"summary":"Beta: Import a selected subset of workflows from an n8n package","description":"**Beta** — breaking changes may still occur without major version bump.\n\nImports a chosen subset of workflows from one source project of a gzip-compressed tar package (`.n8np`), instead of the whole package. Send the archive as the multipart field `package`. The import is **additive** (cherry-pick): it never removes a workflow the selection omits. It creates or updates only the workflows named in `selectedWorkflowIds`, and deletes only the destination workflows named in `deletedWorkflowIds`.\n\n`selectedProjectId` names the single source project the selection is scoped to (its id as it appears in the package). The selected workflows are written into the instance project whose id matches that source project, which is created if it does not yet exist; there is no separate target-project field. `selectedWorkflowIds` are source ids within that project; ids that belong to another project are dropped. `deletedWorkflowIds` are destination ids in the same project; an absent id is a tolerated no-op, and a delete needs the `workflow:delete` scope. A delete id must not match the destination id of a selected workflow, including when `workflowConflictPolicy=skip`. This overlap returns a 409 before any writes.\n\nThe package must be a project package (a workflow package is rejected with a 400). The cherry-pick conflict policies (folder, tag, and project) are fixed and are not accepted here; only `workflowConflictPolicy`, `workflowIdPolicy`, and `overwriteDeletionPolicy` are configurable. Maximum upload size is `N8N_ENDPOINTS_PAYLOAD_SIZE_MAX` MB (default 16). The caller is authorised through the `workflow:import` scope.","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"package":{"type":"string","description":"Gzip-compressed tar package (`.n8np`).","format":"binary"},"selectedProjectId":{"type":"string","minLength":1,"description":"Id of the single source project the selection is scoped to, as it appears in the package."},"selectedWorkflowIds":{"type":"string","description":"JSON-encoded array of source workflow ids to import from `selectedProjectId`, e.g. `[\"wf-1\",\"wf-2\"]`. An empty array (`[]`) is allowed — useful for a delete-only request. Ids outside the scoped project are dropped."},"deletedWorkflowIds":{"type":"string","description":"Optional JSON-encoded array of destination workflow ids to remove from the scoped project, e.g. `[\"wf-3\"]`. Removal happens even under the additive profile, and the manner of removal follows `overwriteDeletionPolicy` (archive by default). An absent id is a no-op unless it is also a selected destination. Must not contain a selected workflow's destination id. Needs the `workflow:delete` scope."},"workflowConflictPolicy":{"type":"string","enum":["new-version","fail","skip"],"default":"new-version","description":"What happens when a selected workflow matches an existing workflow by source id in the target project. `new-version` (default) updates it and creates a new version; `fail` rejects the import when any matching workflow exists; `skip` leaves matching workflows unchanged. An archive state change also needs the `workflow:delete` scope."},"workflowIdPolicy":{"type":"string","enum":["new","source"],"default":"source","description":"Controls the id each newly created workflow receives. `source` (default) reuses the package's own workflow id on the target instance; `new` mints a fresh id and records the package id as `sourceWorkflowId`. Workflows matched to an existing workflow keep that workflow's current id, regardless of policy."},"overwriteDeletionPolicy":{"type":"string","enum":["archive","hard-delete"],"default":"archive","description":"How the ids in `deletedWorkflowIds` are removed. `archive` (default) archives each one, so it stays recoverable along with its execution history. `hard-delete` archives it — the step that unpublishes it, which a delete will not do on its own — and then deletes the workflow and its executions permanently. Each entry in `removedWorkflows` reports what actually happened in its `deletion` field: a `hard-delete` whose row cannot be dropped yet, because unpublishing defers trigger teardown, is left `archived` rather than failing an import whose content is already written."}},"required":["package","selectedProjectId","selectedWorkflowIds"],"additionalProperties":false}}}},"responses":{"200":{"description":"Operation successful.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/importResultDto.generated"}}}},"400":{"$ref":"#/components/responses/badRequest"},"401":{"$ref":"#/components/responses/unauthorized"},"403":{"$ref":"#/components/responses/forbidden"},"404":{"$ref":"#/components/responses/notFound"},"409":{"description":"Import blocked by at least one conflict among the issues — for example a workflow source-id conflict under `workflowConflictPolicy=fail`, or a selected destination also named for deletion (`workflow-removal-conflict`).","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"issues":{"type":"array","items":{"$ref":"#/components/schemas/importBlockingIssue.generated"}}},"required":["message","issues"]}}}},"413":{"$ref":"#/components/responses/contentTooLarge"},"415":{"$ref":"#/components/responses/unsupportedMediaType"},"422":{"description":"Import blocked by non-conflict issues only — for example a delete the caller may not perform (`workflow-removal-forbidden`), unresolved credentials, or node types this instance does not have.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"issues":{"type":"array","items":{"$ref":"#/components/schemas/importBlockingIssue.generated"}}},"required":["message","issues"]}}}},"500":{"$ref":"#/components/responses/internalServerError"}}}}}}
```
