crontab에서 curl로 매일 API 호출하기: % 이스케이프

crontab 줄은 curl을 /bin/sh로 실행하고, 이스케이프하지 않은 %는 줄바꿈이 됩니다. %는 \%로 이스케이프하고, 전체 경로를 쓰고, 출력을 로그로 남기고, 요청 키는 날짜로 만드세요.

읽는 시간 5분Sume
전체 글

crontab에서 curl로 API를 호출하려면 명령 전체를 crontab 한 줄에 넣고, 터미널이 아니라 cron에 맞게 작성하세요. cron은 그 줄을 /bin/sh로 실행하고 이스케이프하지 않은 %를 모두 줄바꿈으로 바꾸므로, date +%F는 date +\%F로 써야 합니다. /usr/bin/curl 같은 전체 경로를 쓰고, 출력은 로그 파일에 덧붙이고, API 키는 curl이 -H @file로 읽는 파일에 두세요.

cron 관련 내용은 man7.org에 게시된 cronie의 crontab(5)와 cron(8) 매뉴얼 페이지에서 가져왔으며, 다른 cron 구현은 다를 수 있습니다. curl 관련 내용은 curl 매뉴얼 페이지에서, Sume 관련 내용은 Format 호출하기 (영문), 실행과 결과 (영문), 오류와 비용 (영문)에서 가져왔습니다. 모두 2026-09-28에 확인했습니다. Sume에는 crontab 전용 연동이 없으며, 작업은 HTTPS를 한 번 직접 호출합니다.

제대로 동작하는 crontab curl 줄은 어떻게 생겼나요?

아래 항목은 매일 오전 6:00에 Sume Format 실행을 하나 시작합니다. \%는 날짜를 온전히 지켜 주고, cron은 /etc/passwd에서 $HOME을 설정하며, --fail-with-body(curl 7.76.0 이상)는 4xx나 5xx에서 curl이 오류로 종료되게 하면서도 Sume의 JSON 오류를 로그에 기록합니다. 헤더 파일에는 Authorization: Bearer 뒤에 키가 오는 한 줄이 들어 있습니다.

# m h dom mon dow  command  (crontab -e; one entry per line)
0 6 * * * /usr/bin/curl -sS --fail-with-body --max-time 30 --retry 3 -H @$HOME/.config/sume/auth-header -H 'Content-Type: application/json' -H "Idempotency-Key: daily-recap-$(date -u +\%F)" -d '{"input":{"feed_url":"https://example.com/daily.json"}}' https://api.sume.com/v1/formats/acme/daily-recap/runs >> $HOME/sume-cron.log 2>&1

curl이 터미널에서는 되는데 crontab에서는 왜 안 되나요?

cron의 환경이 여러분 셸의 환경과 다르기 때문입니다. 대부분의 실패는 아래 행 중 하나에 해당합니다.

crontab(5), cron(8), curl 매뉴얼 페이지, Sume의 오류와 비용 (영문) 기준, 2026-09-28 확인.
증상원인해결 방법
명령이 date +에서 끊김cron이 이스케이프하지 않은 %를 줄바꿈으로 바꾸고, 나머지를 명령의 표준 입력으로 보냄모든 %를 \%로 쓰기
터미널에서는 실행되는 도구를 찾지 못함cronie는 -P로 시작하지 않으면 자체 PATH를 설정함/usr/bin/curl 같은 전체 경로 사용
Sume가 401 unauthorized로 응답셸에서 export한 키가 설정되어 있지 않음. cron 자체는 SHELL, LOGNAME, HOME을 설정함-H @file로 파일에서 키 읽기
Sume가 415 unsupported_media_type으로 응답-d는 application/x-www-form-urlencoded로 보냄-H 'Content-Type: application/json' 추가
작업은 0으로 종료했지만 아무것도 시작되지 않음curl은 기본적으로 HTTP 오류 코드를 실패로 취급하지 않음--fail-with-body를 추가하고 로그 확인
출력이 어디에도 없음cron은 명령 출력을 crontab 소유자에게 메일로 보냄>> file 2>&1 덧붙이기
마지막 항목이 제대로 동작하지 않음모든 항목은 줄바꿈으로 끝나야 하며, 그렇지 않으면 cron은 crontab이 적어도 일부 손상되었다고 봄파일을 줄바꿈으로 끝내기

API 키를 crontab에 넣지 않으려면 어떻게 하나요?

헤더를 여러분의 사용자만 읽을 수 있는 파일에 넣으세요. -H @file을 쓰면 curl이 파일의 각 줄마다 헤더를 하나씩 추가하므로, 키가 crontab에도, 명령줄에도 나타나지 않습니다. curl 매뉴얼은 비밀번호에 관해 설명하면서 그런 데이터는 파일에서 읽어야 하며 명령줄에 평문으로 절대 쓰지 말라고 말합니다. 헤더 자체는 curl Bearer 토큰: Authorization 헤더 보내는 법에서 다룹니다. Sume 문서는 API 키를 신뢰할 수 있는 서버에 두라고 하며, 로그나 채팅 기록에 노출된 키는 교체하라고 안내합니다.

중복 실행으로 두 번 과금되는 것은 어떻게 막나요?

위 줄처럼 Idempotency-Key를 날짜로 만들고, 본문은 하루 종일 같게 유지하세요. 그러면 같은 날짜에 작업이 한 번 더 돌거나 curl이 재시도해도 원래 실행과 idempotency_hit: true가 담긴 200을 받습니다. 두 번째 실행도, 두 번째 청구도 없습니다. 그 밖의 재전송 사례는 Kubernetes CronJob 동시성 정책: 유료 API 작업용에 정리되어 있습니다.

  • --retry 3은 타임아웃이나 HTTP 408, 429, 500, 502, 503, 504, 522, 524 뒤에 다시 보냅니다. 처음에는 1초를 기다린 뒤 대기 시간을 두 배씩 늘리고, Retry-After를 따릅니다. 날짜 키가 있어서 이런 재전송이 안전합니다.
  • 같은 키로 본문을 바꾸면 409 idempotency_conflict가 되고 아무것도 실행되지 않습니다. 같은 날 일부러 두 번째 영상을 만들려면 새 키가 필요합니다.

cron 작업이 영상을 기다려야 하나요?

아니요, 기다릴 필요가 없습니다. 생성 요청은 즉시 영수증으로 응답하고, 실행 자체는 몇 분이 걸립니다. 본문에 communication.webhook_url을 넣으면 실행이 완료되거나 실패할 때 Sume가 서명된 format.run.terminal 영수증 하나를 POST합니다. 그렇지 않다면 별도 작업에서 status_url을 폴링하되, 간격을 두 배씩 늘려 최대 일 분까지 늘리세요. 시계 말고는 작업을 촉발하는 것이 없다면 Sume 자체의 Scheduled가 IANA 타임존 기준의 다섯 필드 cron으로 저장된 자동화를 실행합니다. AI 영상 에이전트 스케줄 실행을 참고하세요.

출처

관련 글

연동 카테고리의 다른 글

연동 글 전체 보기

작성자 Sume