Sume Format 실행 수명주기: 상태, 웹훅, 폴링
Sume Format 실행은 queued에서 processing을 거쳐 종료 상태로 갑니다. 결과는 서명된 format.run.terminal 웹훅 한 번이나 폴링, 또는 둘 다로 확인합니다.

Sume Format 실행은 비동기입니다. 생성 호출은 즉시 영수증으로 응답하고, 실행은 queued에서 processing을 거쳐 종료 상태로 이동하며, 결과는 서명된 format.run.terminal 웹훅 한 번이나 폴링으로 알 수 있습니다. 둘 다 똑같은 영수증을 담고 있으며, 프로덕션 연동은 둘 다 씁니다. 웹훅은 빠른 경로로, result_url 읽기는 백업으로 씁니다.
아래 내용은 모두 2026-09-25에 확인한 Sume 문서 실행과 결과 (영문)와 Run 웹훅 (영문) 페이지에서 가져왔습니다.
Format 실행은 어떤 상태를 거치나요?
모든 영수증에는 status와, 다음에 할 일을 알려 주는 next_action이 있습니다. Format 실행이 내보내는 next_action 값은 poll_status, retry_later, none 세 가지뿐입니다.
| 상태 | 의미 | 다음 동작 |
|---|---|---|
queued | 수락됨, 아직 시작 전 | poll_status |
processing | 실행이 작업 중 | poll_status |
completed | 끝남. output, artifacts[], primary_output_url이 채워짐 | none |
failed | 오류와 함께 끝남. artifacts[]에는 만들어진 것이 그대로 담김 | none |
canceled | POST …/cancel로 멈춤 | none |
skipped | 실행되지 않음. on_active_run: "skip"을 보냈는데 다른 실행이 진행 중이었음 | retry_later |
Format 실행은 어떻게 폴링하나요?
경로를 직접 만들지 말고 영수증에 있는 URL을 따르세요. 대부분의 연동은 status가 종료 상태가 될 때까지 GET /v1/format-runs/{run_id}에서 전체 영수증을 읽습니다. status_url은 output과 artifacts가 빠진 더 작은 페이로드입니다. result_url은 종료 후에는 전체 영수증을, 그 전에는 409 run_not_completed를 반환합니다. events_url은 로그 스트림이 아니라 phase 타임라인 (영문)(preparing, running, finalizing)입니다.
- 백오프하세요. 긴 영상은 15~30분짜리 작업이므로 간격을 두 배씩 늘리되 최대 1분까지만 늘리세요.
- 루프 중에 받은
429나503은 일시적인 것으로 처리하세요. 실행은 여전히 진행 중이고 계속 비용을 씁니다. expires_at을 상한선으로 삼으세요. 실행은created_at부터 90분이 지나면failed로 강제 종료되며, 25분을 넘긴 실행이 10분 동안 아무 활동이 없으면 그보다 일찍 강제 종료됩니다.queued가 오래 이어지면queue.state를 읽으세요. 일반적인 픽업 시간 안이면waiting, 그 시간을 넘기면runtime_unavailable이며, 이때retry_after_seconds가 백오프할 시간을 알려 줍니다.- TypeScript에서는
subscribeFormatRun이 실행을 만들고 이 루프를 돌립니다. 이미 가진 실행 ID에는waitForRun이 같은 일을 합니다.
SLEEP=5
while :; do
RUN=$(curl -sS "https://api.sume.com/v1/format-runs/$RUN_ID" \
-H "Authorization: Bearer $SUME_API_KEY")
STATUS=$(echo "$RUN" | jq -r '.data.status')
case "$STATUS" in
queued|processing) sleep "$SLEEP"; SLEEP=$(( SLEEP < 60 ? SLEEP * 2 : 60 )) ;;
*) break ;;
esac
done
echo "$RUN" | jq '{status: .data.status, primary: .data.primary_output_url, error: .data.error}'Format 실행 웹훅은 어떻게 동작하나요?
실행을 만들 때 공개 HTTPS URL인 communication.webhook_url을 보내세요. 실행이 완료되거나 실패하면 Sume가 폴링 엔드포인트가 돌려주는 것과 같은 영수증을 담아 서명된 POST를 한 번 보냅니다. 실행이 클립을 몇 개 만들었든 웹훅은 실행당 한 번만 발송됩니다. 전체 계약은 Run 웹훅 (영문)에 있습니다.
| 필드 | 활용 방법 |
|---|---|
event | Format 실행에서는 항상 format.run.terminal. 본문을 보지 않고 이 값으로 라우팅 |
request_id, run_id | 서로 같고 재시도에도 유지됨. 이 값으로 중복 제거 |
status | 실행이 완료되면 OK, 실패하면 ERROR |
outcome | ok, degraded, error 중 하나. degraded는 실제 미디어로 완료되어 과금됐지만 output이 null이라는 뜻. 구조화 출력 참고 |
created_at | 이 전달 본문이 만들어진 시각. 전달 순서는 이 값으로 정렬 |
payload | 실행 영수증. GET /v1/format-runs/{run_id}의 data와 바이트 단위로 동일. 영수증이 1 MiB를 넘을 때만 null이며, 그때는 error.result_url에서 가져오기 |
Sume 웹훅 서명은 어떻게 검증하나요?
각 전달에는 x-sume-webhook-timestamp, x-sume-webhook-signature(sume-v1=<hex hmac-sha256>), x-sume-webhook-secret-fingerprint가 담깁니다. 서명은 워크스페이스의 서명 시크릿으로 <timestamp>.<raw_body>에 대해 계산한 HMAC-SHA256입니다. 시크릿은 대시보드의 웹훅 탭에서 확인하거나, account:read 스코프가 있는 키로 GET /v1/webhooks/signing-secret을 호출해 받을 수 있습니다. 같은 검증기로 생성 Job 웹훅도 처리할 수 있습니다. 영상 실행을 위한 서명된 웹훅을 참고하세요.
- JSON을 파싱하기 전에 원본 바이트로 검증하세요.
- 오 분 범위를 벗어난 타임스탬프는 거부하세요.
- 지문 헤더를 시크릿 옆에 표시된 지문과 비교하세요.
- 10초 안에
2xx중 아무 상태로나 응답하세요. 이벤트를 내구성 있게 기록하고, 응답한 다음, 작업하세요.
import { verifyWebhook } from "@sume-com/sdk";
const ok = await verifyWebhook({
body: rawBody,
headers: request.headers,
secret: process.env.SUME_COM_WEBHOOK_SIGNING_SECRET!,
});웹훅 엔드포인트가 다운되면 어떻게 되나요?
실행에는 영향이 없습니다. 전달 결과는 실행을 절대 바꾸지 않습니다. Sume는 최대 10회까지 재시도하며, 지수 백오프(지터를 더한 30 s × 2^(attempt−1))와 여러분이 429나 503에 담아 보낸 Retry-After 중 더 긴 쪽만큼 기다리되 최대 한 시간으로 제한합니다. 리다이렉트는 따라가지 않으므로 3xx는 실패한 시도로 셉니다.
영수증의 webhook_delivery.status가 전달 상태를 보여 줍니다. 값은 not_armed, pending, retrying, delivered, failed, exhausted 중 하나입니다. 수신기를 고친 뒤 POST /v1/format-runs/{run_id}/webhook/redeliver(스코프 formats:write, 빈 본문)를 호출하면 현재 영수증을 새 타임스탬프와 서명으로 다시 보내며, 자동 시도 열 번 중 하나를 쓰지 않습니다.
실행이 웹훅을 보내지 않는 때는 언제인가요?
- 취소됐을 때입니다. 취소 요청이 직접 응답하며,
cancel_effect가 그 호출이 실행을 멈췄는지(canceled), 아니면 실행이 이미 끝나 있었는지(no_op) 알려 줍니다. 취소 전에 완료된 생성은 과금됩니다. - 건너뛰었을 때입니다. 건너뛴 실행은 생성 응답에서 이미 종료 상태입니다.
- 이어 간 뒤에는 다시 보내지 않습니다.
previous_run_id로 이어 가면 웹훅을 한 번 따로 보내는 새 실행이 시작되며, 원래 실행의 웹훅은 이미 발송되었으므로 다시 발송되지 않습니다.
출처
관련 글
작성자 Sume