개발자

Sume 웹훅이 도착하지 않나요? 전달·서명 디버깅 방법

Sume 웹훅이 도착하지 않으면 Job이나 실행의 webhook_delivery를 읽고, 테스트 전송으로 엔드포인트를 확인한 뒤, 실제 이벤트를 다시 보내세요.

읽는 시간 6분Sume
전체 글

Sume 웹훅이 도착하지 않으면 Job이나 실행 자체부터 확인하세요. 웹훅 URL과 함께 만든 Job이나 실행에는 webhook_delivery 객체가 있으며, 그 status, attempts, last_status_code, last_error를 보면 Sume가 전달을 시도했는지, 엔드포인트가 무엇을 응답했는지, Sume가 포기했는지 알 수 있습니다. 그런 다음 테스트 전송(POST /v1/webhooks/test-deliveries)으로 수신기를 검증하고, 다시 보내기(Redeliver)로 실제 이벤트를 재생하세요.

이 가이드는 Sume 문서 웹훅 (영문), Run 웹훅 (영문), 웹훅 검증을 따르며, 필드 정의는 Sume API 레퍼런스에서 가져왔습니다. 모두 2026-09-26에 확인했습니다. 서명과 재시도가 일반적으로 어떻게 동작하는지는 Sume 영상 실행용 서명된 웹훅에서 다룹니다.

Sume가 전달을 시도하기는 했나요?

먼저 URL이 접수되었는지, 그리고 그 결과가 웹훅을 보내는 경우인지 확인하세요. 웹훅 URL은 공개 HTTPS여야 합니다. localhost, 사설 네트워크, HTTPS가 아닌 URL은 제출 시 거부되며, 실행의 URL은 전달 시점에 다시 검사됩니다. 실행은 completed나 failed일 때만 전달하고 canceled나 skipped일 때는 절대 전달하지 않습니다. Job은 job.canceled도 보냅니다.

그다음 webhook_delivery.status를 읽으세요. Job은 pending, delivering, delivered, retrying, failed, exhausted를 쓰며, GET /v1/jobs/{id}/events의 Job 이벤트에는 webhook.delivery가 포함됩니다. 실행은 not_armed, pending, retrying, delivered, failed, exhausted를 씁니다.

실행과 결과 (영문)와 Sume API 레퍼런스 기준 실행 전달 상태, 2026-09-26 확인.
상태의미
not_armedURL은 저장됐지만 아직 예정된 전달이 없음. 실행이 아직 진행 중이거나, 취소 또는 건너뜀으로 끝남(이 경우 전달은 무장되지 않음)
pending, retrying무장됨. next_attempt_at은 다음 시도 예정 시각
delivered엔드포인트가 2xx로 응답함
failed, exhaustedSume가 포기함. 이유는 last_status_code와 last_error에 있음. 실행 자체는 바뀌지 않음

last_status_code와 last_error는 무엇을 알려 주나요?

실행에서 last_status_code는 마지막 시도에서 엔드포인트가 반환한 HTTP 상태이고, last_error는 타임아웃, 연결 실패, 2xx가 아닌 상태 같은 Sume 자체의 전송 오류이며, 엔드포인트의 응답 본문은 절대 담기지 않습니다. Job의 webhook_delivery에도 같은 두 필드가 있습니다. 확인할 원인은 다음과 같습니다.

  • 느린 핸들러: 시도마다 10초가 주어지고 어떤 2xx든 전달로 인정되므로, 이벤트를 내구성 있게 저장하고 응답한 뒤 작업하세요.
  • 리다이렉트: 실행 전달은 리다이렉트를 따라가지 않으므로 3xx는 실패한 시도입니다. 최종 URL을 등록하세요.
  • 핸들러가 모르는 이벤트 타입에 대한 500: 모르는 이벤트에는 204로 응답하세요. 그래야 새 이벤트 타입이 재시도 폭주로 번지지 않습니다.
  • 모든 시도 거부: 10회 시도 후에는 전달이 멈추지만, Job이나 실행은 이미 실제 종료 상태에 도달해 있습니다. result_url이나 status_url에서 읽으세요.

실제 Job 없이 엔드포인트를 어떻게 테스트하나요?

테스트 보내기(Send test)를 쓰세요. /dashboard/webhooks의 컨트롤을 쓰거나, account:write가 있는 키로 POST /v1/webhooks/test-deliveries를 호출하면 됩니다. 입력한 공개 HTTPS URL로 서명된 더미 webhook.test 이벤트를 POST하고, 결과를 status_code와 error로, 그리고 signing_secret_fingerprint와 함께 반환합니다. 실제 Job이나 실행을 재생하지 않으며, 본문에 job_id나 실행 ID가 없습니다.

curl -X POST https://api.sume.com/v1/webhooks/test-deliveries \
  -H "Authorization: Bearer $SUME_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "webhook_url": "https://example.com/hooks/sume" }'

놓친 이벤트는 어떻게 다시 받나요?

수신기를 고친 뒤 다시 보내기(Redeliver)로 실제 종료 이벤트를 다시 보내세요. jobs:write로 POST /v1/jobs/{job_id}/webhook/redeliver를 호출하거나, formats:write와 빈 본문으로 POST /v1/format-runs/{run_id}/webhook/redeliver를 호출하면 됩니다. Sume는 자동 시도 10회를 모두 소진한 뒤에도 새 타임스탬프와 서명으로 이벤트를 다시 POST합니다.

  • 방금 트리거한 POST의 결과는 redelivery(delivered, status_code, error)에서 읽으세요. 이미 전달된 호출을 다시 보냈다가 실패하면 webhook_delivery는 이전 2xx 상태로 남고, 그 시도는 manual_redeliveries에만 집계됩니다.
  • 409 webhook_not_configured는 웹훅 URL이 없었다는 뜻이고, 409 job_not_terminal이나 run_not_terminal은 아직 실행 중이라는 뜻입니다. 볼 수 없는 Job이나 실행은 404입니다.
  • 다시 보내기는 다른 URL로 절대 보내지 않습니다. Job의 경우 새 URL은 새 Job입니다.

엔드포인트가 왜 모든 서명을 거부하나요?

Sume는 모든 전달을 <timestamp>.<raw_body>에 대한 HMAC-SHA256으로 서명합니다. 모든 전달이 검증에 실패한다면 검증기를 다음 순서로 살펴보세요.

  • 원본 본문: 파싱했다가 다시 직렬화한 객체는 검증되지 않습니다. Express에서는 웹훅 라우트에만 express.raw({ type: "application/json" }) 미들웨어를 붙이고, Next.js App Router에서는 무엇보다 먼저 await request.text()를 호출하세요.
  • 시크릿: x-sume-webhook-secret-fingerprint 헤더를 대시보드에서 시크릿 옆에 표시된 지문과 비교하세요. 지문은 티켓에 붙여넣어도 안전하지만 시크릿은 그렇지 않습니다.
  • 시크릿 교체 또는 시계: 교체 후 24시간 동안 서명 헤더에는 sume-v1= 항목이 두 개 실리므로, 헤더 전체를 문자열 일치로 비교하는 검증기는 모든 전달에서 실패합니다. 어느 항목이든 일치하면 수락하세요. verifyWebhook은 재전송 허용 시간인 toleranceSeconds도 적용하며, 기본값은 300입니다. 교체는 Sume 영상 실행용 서명된 웹훅에서 다룹니다.

출처

관련 글

작성자 Sume