n8n 의 워크플로 정의를 디스크의 JSON 파일로 관리하고 있다. 워크플로를 수정하면 import 하고, public API 의
/activate 엔드포인트로 켜는 흐름을 자동화해두려 했다. 그런데 그 마지막 한 줄에서 막혔다.
$ curl -X POST \
-H "X-N8N-API-KEY: $N8N_API_KEY" \
https://n8n.speech.pe.kr/api/v1/workflows/lFBTaoP6uuGUYCaA/activate
{"message":"Bad request - please check your parameters"}
이게 끝이다. 어떤 파라미터가 어떻게 잘못됐는지 한 글자도 안 알려준다. 30분 헛삽질의 시작이었다.
1. 엔드포인트 자체는 살아있다 — 다른 워크플로로 확인
가장 먼저 의심한 건 인증·URL 오타였다. trigger 노드 없이 빈 워크플로를 만들어 같은 호출을 보내봤다.
{"message":"Workflow cannot be activated because it has no trigger
node"}
응답이 다르게 나온다. 즉 엔드포인트 자체는 정상 동작하고, 인증도 통과한다. 문제의 워크플로에만 특정 거부 조건이 걸려 있다는 뜻.
2. 진짜 원인 추정 — activeVersionId 가 비어있다
GET 으로 워크플로 정보를 조회해봤다.
$ curl -H "X-N8N-API-KEY: $N8N_API_KEY" \
https://n8n.speech.pe.kr/api/v1/workflows/lFBTaoP6uuGUYCaA \
| jq '{active, activeVersionId, triggerCount}'
{
"active": false,
"activeVersionId": null,
"triggerCount": 0
}
activeVersionId 가 null. n8n 은 워크플로를 “publish” 한 다음에야 활성화할 수 있는
구조인데, 디스크 JSON 으로 막 import 한 워크플로는 published version 이 없다. triggerCount: 0 도 같이
0 으로 표시되는데, 이건 publish 가 안 돼서 트리거가 인식되지 않은 부수 효과로 보인다.
문제는 public API 가 이 상황을 “Bad request” 라는 한 줄로 뭉뚱그려 응답한다는 점. 진단을 어렵게 한다.
3. 시도 1 — CLI n8n publish:workflow
n8n CLI 에 publish 명령이 있다. 다만 컨테이너 안에서 돌리면 이런 메시지가 나온다.
> n8n publish:workflow --id=lFBTaoP6uuGUYCaA
Changes will not take effect if n8n is running.
말 그대로 실행 중 인스턴스의 in-memory 상태가 갱신되지 않는다. 적용하려면 컨테이너를 재시작해야 하는데, 그러면 다른 활성 워크플로의 실행 중인 잡들이 끊긴다. 비효율이다.
4. 시도 2 — Internal REST 의 /rest/workflows/{id} PUT
n8n 의 UI 가 내부적으로 쓰는 REST 가 따로 있다. 거기엔 active: true 를 PUT 으로 보낼 수 있는
엔드포인트가 있다. 그러나 owner 의 세션 쿠키가 필요하다. 자동화 스크립트에서 매번 로그인 쿠키를
받아오는 건 깨지기 쉽고, public API 가 있는데 굳이 갈 길도 아니다.
5. 답 — UI 토글이 publish + activate + setWebhook 을 한 번에 한다
워크플로 편집 화면 헤더 우측의 Inactive → Active 토글을 클릭. UI 는 이걸 처리하면서 다음을 모두 수행한다.
activeVersionId 를 세팅active: true)API 한 줄로 끝내려던 일이 결국 마우스 클릭 한 번. 자존심은 좀 상하지만 30분 헛삽질의 결론이다.
정리
n8n public API 의 /activate 는 새로 import 한 워크플로에 대해서는 사실상 못
쓴다(2.18.5 기준). 진단 메시지가 무성의해서 더 답답하다.
| 시나리오 | API 활성화 가능? |
|---|---|
| API 로 새 워크플로 POST 후 즉시 activate | 불가 (400 Bad request) |
| UI 에서 한 번 publish 된 워크플로 | 가능 |
| deactivate API | 정상 동작 (시나리오 무관) |
자동화 흐름을 짜고 있다면 워크플로 첫 활성화는 UI 토글, 그 이후의 정의 수정은 PUT
/api/v1/workflows/{id} 로 갱신하는 패턴이 가장 안정적이다. 활성 상태는 PUT 으로 토글되지 않으므로
(active 필드를 보내도 무시) 다음번 비활성화는 /deactivate API 로
가능하다.
이 글은 Telegram 봇으로 YouTube URL 요약 워크플로를 활성화하다가 만난 함정의 기록이고, 그 봇은 이 글의 형제 글 Nginx + Let’s Encrypt TLS 위에서 동작한다.