패키지 가져오기
n8n v2.42요약
n8n 패키지는 프리뷰 단계입니다. 가져오기는 n8n 패키지인 .n8np 아카이브를 읽어 그 내용을 대상 인스턴스에 기록합니다. 또는 엔드포인트를 직접 호출할 수 있습니다. 전체 요청 및 응답 스키마는 엔드포인트 레퍼런스의 N8nPackage 섹션을 참조하세요.
프리뷰 상태
n8n 패키지는 프리뷰 단계입니다. 가져오기 옵션은 향후 릴리즈에서 변경될 수 있습니다.
가져오기는 n8n 패키지인 .n8np 아카이브를 읽어 그 내용을 대상 인스턴스에 기록합니다. n8n은 먼저 패키지 전체를 검사합니다. 가져오기를 막는 문제가 하나라도 있으면 아무것도 기록하지 않고 모든 문제를 한 번에 반환합니다. 자세한 내용은 가져오기 동작 방식을 참조하세요.
n8n CLI를 사용합니다.
n8n-cli package import --file=triage.n8np --project-id=<target-project-id>
또는 엔드포인트를 직접 호출할 수 있습니다. 아카이브는 package라는 이름의 multipart 필드에 담고, 각 옵션은 별도의 텍스트 필드로 보냅니다.
curl -X POST 'https://n8n.example.com/api/v1/n8n-packages/import' \
-H "X-N8N-API-KEY: <your-api-key>" \
-F 'package=@triage.n8np' \
-F 'workflowConflictPolicy=new-version' \
-F 'projectId=<target-project-id>'
전체 요청 및 응답 스키마는 엔드포인트 레퍼런스의 N8nPackage 섹션을 참조하세요.
CLI를 사용하지 않고 엔드포인트를 호출하는 경우 요청은 multipart/form-data여야 합니다. 다른 콘텐츠 유형은 415를 반환합니다. CLI는 workflowConflictPolicy를 대신 채워 주지만, 엔드포인트에서는 이 필드가 필수입니다.
설정하지 않으려는 옵션은 빈 값으로 보내지 말고 생략하세요. 정책 또는 모드 필드에 빈 값을 보내면 400으로 거부됩니다. projectId, folderId, bindings만 빈 값을 허용하며, n8n은 이를 생략한 것으로 처리합니다.
이 섹션의 상세 내용은 n8n 공식 문서를 참조하세요.
콘텐츠가 놓이는 위치#
워크플로 또는 폴더 패키지는 대상 위치를 직접 선택합니다.
| 플래그 | 설명 |
|---|---|
--file |
.n8np 파일 경로입니다. 필수입니다. -f가 --format이므로 짧은 별칭은 없습니다. |
--project-id, -p |
대상 프로젝트 ID입니다. 기본값은 개인 프로젝트입니다. 별칭: --project. |
--folder-id |
프로젝트 내 대상 폴더 ID입니다. 기본값은 프로젝트 루트입니다. 별칭: --folder. |
프로젝트 패키지에서는 --project-id와 --folder-id가 경고 없이 무시됩니다. 프로젝트 패키지는 자체 프로젝트를 포함하며, 각 프로젝트의 콘텐츠는 해당 프로젝트의 루트로 들어갑니다. 프로젝트가 이미 있을 때의 동작은 --project-conflict-policy로 제어합니다.
이 페이지에서는 플래그를 모두 kebab-case로 표기합니다. n8n-cli package import --help는 이에 대응하는 camelCase 이름(--projectId, --workflowConflictPolicy, --tagConflictPolicy)을 출력하며, 오류 메시지도 이 이름을 사용합니다. 두 표기 모두 동작합니다.
--conflict-policy, --force, --dry-run은 없습니다. 워크플로 충돌용 플래그는 --workflow-conflict-policy입니다.
워크플로 옵션#
| 플래그 | 값 | 설명 |
|---|---|---|
--workflow-conflict-policy |
new-version(기본값), fail, skip |
워크플로가 대상에 이미 있을 때의 동작입니다. new-version은 기존 워크플로의 새 버전을 저장하고, fail은 가져오기 전체를 거부하며, skip은 해당 워크플로를 그대로 두고 계속 진행합니다. |
--workflow-id-policy |
source(기본값), new |
가져온 워크플로가 패키지의 ID를 유지할지 새 ID를 받을지 정합니다. source는 인스턴스 간 프로모션에 적합합니다. new는 같은 패키지를 한 인스턴스에 반복해서 가져올 때 적합하며, 패키지 ID를 워크플로의 소스 ID로 기록합니다. |
--workflow-publishing-policy |
preserve-published-state(기본값), match-source, publish-all, unpublish-all |
가져온 워크플로를 게시 상태로 둘지 정합니다. 게시를 참조하세요. |
--missing-node-type-mode |
fail(기본값), import-anyway |
워크플로가 대상 인스턴스에 없는 노드 유형 또는 노드 버전을 사용할 때의 동작입니다. fail은 아무것도 기록하기 전에 가져오기를 거부하고, 누락된 유형 전체를 해당 유형을 사용하는 워크플로와 함께 나열합니다. import-anyway는 해당 워크플로를 가져오지만 게시하지는 않습니다. |
n8n은 대상에 기록된 소스 워크플로 ID를 기준으로 패키지 워크플로를 기존 워크플로와 매칭하고, 일치하는 항목이 없으면 ID가 패키지의 ID와 같은 대상 워크플로를 찾습니다. 덕분에 반복 프로모션이 같은 결과로 수렴합니다. 두 번째 가져오기는 중복 워크플로를 만들지 않고 기존 워크플로를 업데이트합니다.
게시#
n8n은 가져온 워크플로를 항상 게시되지 않은 상태로 기록한 다음, 모든 항목이 만들어진 가져오기 마지막 단계에서 게시 정책을 한 번에 적용합니다.
| 값 | 동작 |
|---|---|
preserve-published-state(기본값) |
새 워크플로는 초안으로 남습니다. 업데이트되는 워크플로는 이미 게시되어 있고 패키지의 워크플로도 게시 상태일 때만 다시 게시됩니다. |
match-source |
패키지에서 워크플로가 게시되어 있었는지를 따릅니다. |
publish-all |
가져온 모든 워크플로를 게시합니다. 대상 프로젝트에 대한 workflow:publish 권한이 필요합니다. |
unpublish-all |
새 워크플로는 초안으로 남고, 업데이트되는 워크플로는 게시가 취소됩니다. |
정책보다 우선하는 경우가 두 가지 있습니다. 플레이스홀더 자격 증명을 사용하는 워크플로와 인스턴스에 없는 노드 유형을 사용하는 워크플로는 게시되지 않습니다. n8n은 이런 워크플로를 사유와 함께 blocked로 보고합니다. 보관된 워크플로도 게시되지 않습니다.
가져오기는 성공했지만 게시만 실패할 수도 있으며, 가장 흔한 경우는 두 워크플로가 같은 웹훅 경로를 사용하려는 때입니다. 게시 결과를 참조하세요.
폴더 및 프로젝트 옵션#
| 플래그 | 값 | 설명 |
|---|---|---|
--folder-conflict-policy |
merge(기본값), fail |
패키지의 폴더가 대상 프로젝트에 이미 있을 때의 동작입니다. merge는 기존 폴더를 재사용하고 패키지의 콘텐츠를 그 안에 병합하며 폴더 이름은 그대로 둡니다. fail은 가져오기를 거부합니다. |
--project-conflict-policy |
merge(기본값), fail, overwrite |
프로젝트 패키지 전용입니다. 패키지의 프로젝트가 이미 있을 때의 동작입니다. merge는 프로젝트의 세부 정보는 그대로 두고 패키지의 콘텐츠를 추가합니다. overwrite는 이름, 설명, 아이콘까지 교체하며, 패키지에 없는 항목은 그대로 둡니다. fail은 가져오기를 거부합니다. |
--project-conflict-policy는 워크플로 및 폴더 패키지에서는 무시됩니다.
merge 정책에서도 가져오기를 거부하는 폴더 충돌이 두 가지 있습니다. 다른 프로젝트에 이미 있는 폴더 ID와, 가져오기가 배치하려는 위치와 다른 상위 폴더 아래에 있는 기존 폴더입니다. 둘 다 폴더를 옮겨야 해결되므로 정책으로 해결할 수 없습니다.
폴더가 포함된 패키지에는 폴더를 지원하는 라이선스가 필요합니다.
자격 증명 옵션#
| 플래그 | 값 | 설명 |
|---|---|---|
--credential-matching-mode |
id-only(기본값), name-and-type, type-only |
n8n이 패키지의 참조에 해당하는 대상 자격 증명을 찾는 방법입니다. |
--credential-missing-mode |
create-stub(기본값), must-preexist |
참조를 확인할 수 없을 때의 동작입니다. create-stub은 대상 프로젝트에 빈 플레이스홀더 자격 증명을 만들며, 워크플로는 가져와지지만 게시할 수 없습니다. must-preexist는 가져오기를 거부합니다. |
모든 모드에서 n8n은 사용자가 읽을 수 있고 대상 프로젝트가 사용할 수 있는 자격 증명과 글로벌 자격 증명만 후보로 고려합니다. 읽을 수 없는 자격 증명은 id-only에서도 후보가 되지 않으며, ID가 같은데도 매칭되지 않는 가장 흔한 이유입니다.
순위 규칙과 전체 확인 순서는 자격 증명을 참조하세요.
데이터 테이블 옵션#
| 플래그 | 값 | 설명 |
|---|---|---|
--data-table-matching-mode |
by-id(기본값이자 유일한 값) |
ID가 같은 대상 프로젝트의 테이블과 매칭합니다. 이름으로 매칭하는 대체 동작은 없습니다. |
--data-table-missing-mode |
create(기본값), must-preexist, do-nothing |
참조된 테이블이 대상 프로젝트에 없을 때의 동작입니다. create는 패키지 스키마로 테이블을 만들고 소스 ID를 유지하며 행은 포함하지 않습니다. must-preexist는 가져오기를 거부합니다. do-nothing은 생성을 건너뜁니다. |
--data-table-schema-conflict-policy |
keep-existing(기본값), fail, overwrite, overwrite-non-destructive |
매칭된 테이블의 스키마가 패키지와 다를 때의 동작입니다. keep-existing은 대상 테이블에만 있는 추가 칼럼을 허용합니다. fail은 그런 경우에도 거부합니다. overwrite는 대상 테이블을 패키지에 맞게 변경합니다. overwrite-non-destructive도 같지만 칼럼을 제거하거나 유형을 바꾸는 변경이 있으면 가져오기를 거부합니다. |
keep-existing과 fail에서는 패키지의 모든 칼럼이 매칭된 대상 테이블에 같은 이름과 유형으로 있어야 합니다. 칼럼이 없거나 유형이 다르면 가져오기가 거부되며, 소스에서 이름이 바뀐 칼럼은 없는 것으로 간주됩니다. 두 정책 모두 대상 테이블을 변경하지 않으므로 패키지의 칼럼이 대상 테이블에 추가되는 일은 없습니다.
overwrite는 칼럼을 추가, 제거, 이름 변경, 유형 변경, 순서 변경하고 테이블 이름을 바꿉니다. 행과 그 밖의 칼럼은 유지됩니다. 칼럼을 제거하거나 유형을 바꾸면 해당 칼럼의 값이 제거됩니다. 칼럼 이름을 바꾸면 값은 유지됩니다. 변경 사항은 해당 테이블을 사용하는 모든 워크플로에 적용됩니다.
overwrite-non-destructive는 같은 변경을 수행하지만 칼럼을 제거하거나 유형을 바꾸는 변경이 있으면 가져오기를 중단합니다. 아무것도 기록되지 않습니다. 대상 테이블에는 있고 패키지에는 없는 칼럼은 제거되는 것으로 간주됩니다.
각 정책의 자세한 내용은 데이터 테이블을 참조하세요.
매칭된 테이블은 --data-table-missing-mode=do-nothing에서도 스키마 검사를 받습니다. 이 옵션은 테이블의 부재만 다루며 비교는 다루지 않습니다.
변수 옵션#
| 플래그 | 값 | 설명 |
|---|---|---|
--variable-missing-mode |
create-with-value(기본값), create-stub, must-preexist, do-nothing |
참조된 변수가 대상 프로젝트와 글로벌 범위 어디에도 없을 때의 동작입니다. create-with-value는 패키지의 값으로 변수를 만들고, 패키지에 값이 없으면 빈 변수로 만듭니다. create-stub은 항상 빈 변수로 만듭니다. must-preexist는 가져오기를 거부합니다. do-nothing은 그대로 가져오고 확인되지 않은 이름을 보고하므로, 워크플로는 런타임에 실패합니다. |
--variable-conflict-policy |
keep-existing(기본값), overwrite, fail |
참조된 변수가 이미 확인되지만 패키지의 값이 다를 때의 동작입니다. keep-existing은 대상의 값을 그대로 둡니다. overwrite는 값을 교체합니다. fail은 가져오기를 거부합니다. |
--variable-parent-policy |
project(생략 시 동작), global |
새로 만든 변수가 놓일 위치입니다. 패키지 레이아웃이 이미 위치를 결정하는 프로젝트 패키지에서는 400으로 거부됩니다. |
n8n은 런타임에 $vars.<name>이 확인되는 방식인 대상 프로젝트, 글로벌 범위 순서를 따라 변수를 ID가 아닌 이름으로 매칭합니다.
--variable-conflict-policy=overwrite는 변수가 확인된 범위에 값을 기록합니다. 이름이 글로벌 변수로 확인되면 해당 변수를 읽는 다른 프로젝트에서도 새 값이 보입니다. 경고는 표시되지 않습니다.
변수를 만들거나 덮어쓰려면 변수를 지원하는 라이선스와 그에 맞는 API 키 범위가 필요하고, 인스턴스의 변수 한도에 여유가 있어야 합니다. 변수가 모두 이미 확인되는 가져오기는 아무것도 기록하지 않으므로 위 조건이 필요 없습니다.
태그 옵션#
| 플래그 | 값 | 설명 |
|---|---|---|
--tag-missing-mode |
create(기본값), do-nothing |
패키지가 참조하는 태그가 대상 인스턴스에 없을 때의 동작입니다. create는 소스 ID와 이름으로 글로벌 태그를 만듭니다. do-nothing은 해당 태그 없이 워크플로를 가져오고 건너뛴 태그로 나열합니다. |
--tag-conflict-policy |
skip(기본값), fail, rename |
태그가 충돌할 때의 동작입니다. skip은 태그를 버리고 건너뛴 태그로 나열합니다. fail은 가져오기를 거부합니다. rename은 이름이 달라진 대상 태그의 이름을 바꾸고, 이름 충돌은 기존 태그의 이름과 그 태그가 달린 모든 항목을 유지한 채 기존 태그를 패키지의 ID로 옮겨 해결합니다. |
태그는 이름이 아니라 소스 ID로 매칭됩니다. 이름 변경은 안정적인 ID와 비교해야만 감지할 수 있기 때문입니다.
충돌에는 두 종류가 있습니다. 이름 변경 드리프트는 대상 태그의 ID는 같지만 이름이 달라, 한 인스턴스에서 누군가 이름을 바꾼 경우입니다. 이름 충돌은 ID가 대상에 없는데 다른 태그가 이미 그 이름을 쓰고 있는 경우로, 태그를 각각 따로 만든 기존 인스턴스에서 흔히 발생합니다.
태그를 버리면 기존 워크플로의 태그가 제거될 수 있습니다. n8n이 워크플로를 업데이트할 때 패키지의 태그 목록이 대상 워크플로의 태그를 완전히 대체합니다. 버려진 태그는 먼저 그 목록에서 걸러지므로, 패키지 태그가 모두 버려지는 태그된 워크플로를 업데이트하면 현재 달려 있는 태그가 지워집니다.
기존 태그를 건드리지 않으려면 --include-tags=false로 내보내세요. 이 옵션은 빈 목록을 보내지 않고 태그 목록 자체를 생략합니다.
대상 인스턴스에 N8N_WORKFLOW_TAGS_DISABLED=true가 설정되어 있으면 모든 태그 처리가 조용히 건너뛰어지며 가져오기를 실패시키지 않습니다.
바인딩#
바인딩은 패키지의 엔티티를 인스턴스의 특정 엔티티에 직접 매핑하여 매칭 규칙을 건너뜁니다. 엔티티 유형을 키로 하는 JSON 객체를 전달합니다. credentials만 허용됩니다.
n8n-cli package import --file=triage.n8np \
--bindings='{"credentials":{"crLin44":"crProd8"}}'
이 명령은 패키지의 crLin44 자격 증명을 대상의 crProd8에 매핑하므로, crLin44를 사용하는 모든 워크플로가 대신 crProd8을 사용합니다. n8n은 --credential-matching-mode가 실행되기 전에 바인딩을 적용하고, 유형이 일치하는지도 확인합니다. 유형이 다른 자격 증명에 바인딩하면 가져오기가 거부됩니다.
n8n은 credentials 이외의 키를 무시하지 않고 400으로 거부합니다.
바인딩된 자격 증명을 확인할 수 없으면 기본값인 create-stub에서도 항상 가져오기가 거부됩니다. 바인딩하지 않은 참조에만 플레이스홀더가 만들어집니다.
n8n은 사용한 바인딩을 응답에 담아 반환합니다. credentials 맵을 저장해 두었다가 이후 가져오기에서 --bindings='{"credentials":{...}}'로 다시 전달하면 매핑을 안정적으로 유지할 수 있습니다. 응답에는 workflows 맵도 있지만 참고용이며, 이를 다시 보내면 400으로 거부됩니다.
가져오기 응답#
가져오기에 성공하면 키 9개가 담긴 200을 반환합니다.
{
"package": {
"sourceN8nVersion": "2.34.0",
"sourceId": "f9e1e962bba26edf357042c12f367dab17f4c63ec368e1f39cbf7ce43c8b9f8b",
"exportedAt": "2026-08-04T09:14:02.117Z"
},
"workflows": [
{ "sourceWorkflowId": "wf9Zx1", "localId": "wf9Zx1", "name": "Send email",
"projectId": "prProd4", "parentFolderId": null,
"activeVersionId": null, "publishing": { "state": "unchanged" }, "status": "created" },
{ "sourceWorkflowId": "wf7Kq2", "localId": "wf7Kq2", "name": "Triage inbound",
"projectId": "prProd4", "parentFolderId": null,
"activeVersionId": null, "publishing": { "state": "unchanged" }, "status": "created" }
],
"folders": [],
"projects": [],
"bindings": {
"workflows": { "wf7Kq2": "wf7Kq2", "wf9Zx1": "wf9Zx1" },
"credentials": { "crLin44": "crLin44" }
},
"credentials": { "matched": ["crLin44"], "stubbed": [] },
"dataTables": { "matched": 0, "created": 1, "updated": 0 },
"variables": { "matched": [], "missing": [], "created": ["slackChannelId"], "stubbed": [], "updated": [] },
"tags": { "matched": [], "created": ["prod"], "renamed": [], "reconciled": [], "skipped": [] }
}
| 키 | 담고 있는 내용 |
|---|---|
package |
매니페스트에서 복사한 소스 인스턴스의 n8n 버전, 인스턴스 ID, 내보내기 타임스탬프 |
workflows |
워크플로당 한 행이며, created, updated, skipped 중 하나인 status와 publishing 결과를 포함합니다 |
folders |
폴더당 한 행이며, created 또는 skipped인 status를 포함합니다 |
projects |
프로젝트당 한 행이며, created, updated, skipped 중 하나인 status를 포함합니다. 워크플로 및 폴더 패키지에서는 비어 있습니다 |
bindings |
워크플로와 자격 증명의 소스 ID에서 대상 ID로의 맵입니다. 이후 가져오기에 다시 전달할 수 있는 것은 credentials 맵뿐입니다 |
credentials |
소스 자격 증명 ID를 matched와 stubbed로 나눈 것 |
dataTables |
matched, created, updated된 데이터 테이블 수. updated는 overwrite 또는 overwrite-non-destructive에서 변경된 테이블을 셉니다 |
variables |
변수 이름을 matched, missing, created, stubbed, updated로 나눈 것. 값은 표시되지 않습니다 |
tags |
태그 이름을 matched, created, renamed, reconciled, skipped로 나눈 것 |
워크플로의 localId는 대상 인스턴스에서의 ID입니다. --workflow-id-policy=source에서는 패키지의 ID, new에서는 새 ID이며, 워크플로가 업데이트되었거나 건너뛰어진 경우에는 기존 워크플로의 ID입니다.
publishing.state는 published, unpublished, unchanged, blocked, failed 중 하나입니다. 각 값의 의미는 게시 결과를 참조하세요.
예시의 두 워크플로는 모두 새 워크플로이고 기본값인 preserve-published-state는 새 워크플로를 게시하지 않으므로 각각 unchanged로 보고됩니다. 새 워크플로를 게시된 상태로 받으려면 --workflow-publishing-policy=publish-all을 사용하거나, 패키지에서 published로 지정된 경우 match-source를 사용하세요.
오류#
거부된 가져오기는 첫 번째 문제만이 아니라 발견된 모든 문제를 반환합니다.
{
"message": "Import blocked: 2 issue(s) must be resolved before the package can be imported.",
"issues": [
{ "type": "missing-node-type", "nodeType": "@acme/cool-node", "typeVersion": 3,
"usedByWorkflows": ["wf7Kq2"] },
{ "type": "credential-unresolved", "kind": "not_found", "sourceId": "crLin44",
"usedByWorkflows": ["wf7Kq2"] }
]
}
아무것도 기록되지 않았습니다. CLI는 0이 아닌 상태로 종료하고 목록을 출력합니다.
| 상태 | 의미 |
|---|---|
400 |
요청 또는 패키지의 형식이 잘못되었습니다. 프로젝트 패키지에 --variable-parent-policy를 사용했거나 --bindings 값이 잘못된 경우도 해당합니다 |
403 |
API 키 범위가 없거나, 대상 프로젝트에 대한 접근 권한이 없거나, 폴더, 변수 또는 팀 프로젝트를 지원하지 않는 라이선스입니다 |
404 |
전달한 프로젝트 ID가 없거나 개인 프로젝트가 없습니다 |
409 |
충돌로 인해 가져오기가 거부되었습니다 |
413 |
업로드 크기가 인스턴스가 허용하는 한도보다 큽니다 |
415 |
요청이 multipart/form-data가 아니었습니다 |
422 |
확인되지 않은 자격 증명이나 누락된 노드 유형 등 다른 이유로 가져오기가 거부되었습니다 |
가져오기가 거부될 수 있는 모든 이유와 각 이유에 해당하는 상태는 가져오기가 거부되는 이유를 참조하세요.
이벤트#
모든 가져오기는 로그 스트리밍과 텔레메트리 경로 모두에 이벤트를 내보내므로, 인스턴스에 무엇이 들어왔는지 감사할 수 있습니다.
| 이벤트 | 내보내는 시점 |
|---|---|
n8n.audit.n8n-package.import.success |
가져오기에 성공했을 때 |
n8n.audit.n8n-package.import.failed |
가져오기에 실패했을 때 |
성공 이벤트에는 사용자, 콘텐츠가 놓인 프로젝트와 폴더, 기록된 워크플로, 가져오기에 사용된 모든 옵션, 패키지의 소스 인스턴스 ID와 형식 버전, 그리고 matched, created, updated로 나눈 자격 증명 ID가 담깁니다. 건너뛴 워크플로는 제외됩니다. 프로젝트가 여러 개 들어 있는 패키지도 이벤트는 하나만 내보냅니다.
실패 이벤트에는 사용자, access-denied, entity-not-found, blocked, validation 중 하나인 reason, 그리고 가져오기가 대상 프로젝트와 폴더를 확인할 수 있는 단계까지 진행되었다면 해당 프로젝트와 폴더가 담깁니다. 많은 실패가 n8n이 패키지를 읽기 전에 발생하므로 워크플로 ID는 담기지 않습니다.
거부된 가져오기는 성공 이벤트를 내보내지 않습니다. 로그 스트리밍 이벤트에는 ID는 있지만 개수가 없고, 텔레메트리 이벤트에는 개수는 있지만 ID가 없습니다.
다음 읽을거리#
- 가져오기 동작 방식에서 n8n이 항목을 기록하는 순서와 엔티티 유형별 확인 방식을 설명합니다.
- 패키지 내보내기에서 패키지 자체를 구성하는 옵션을 설명합니다.
- 제한 및 권한에서 업로드 한도와 전체 범위 매트릭스를 설명합니다.