Run 웹훅

이 문서는 영문 원고를 AI로 번역한 내용이라 표현이 어색할 수 있습니다.

모든 실행 표면은 communication.webhook_url을 받습니다. 실행이 완료되거나 실패하면 Sume가 그 URL로 서명된 POST를 한 번 보내며, 폴링 엔드포인트가 반환하는 것과 같은 영수증을 담습니다. 전달은 fal 웹훅 형태와 같습니다. 봉투 status는 그 결과에 대해 OK 또는 ERROR이며, 취소에는 웹훅이 없습니다.

폴링 루프의 대안입니다. status_urlresult_url은 그대로 받고 폴링도 계속 지원합니다. 웹훅은 실행마다 루프를 돌리는 수고를 덜어 줄 뿐입니다.

제공 여부

환경전달
개발 — api.dev.sume.com동작합니다. 엔드포인트가 호출됩니다.
프로덕션 — api.sume.com동작합니다. 엔드포인트가 호출됩니다.

communication.webhook_url을 주면 두 환경 모두에서 전달이 무장됩니다. status_url / result_url 폴링은 백업으로 계속 지원됩니다. 이미 webhook_url을 제공한 실행(활성화 이후 종료에 도달한 예전 실행 포함)은 POST를 받을 수 있으므로, 지금도 트래픽을 받고 싶은 엔드포인트만 등록하세요.

이 페이지는 run 웹훅을 다룹니다. 생성 Job 웹훅(POST /v1/models/...에서 오는 job.completed 등)은 별도 이벤트 집합을 가진 별개 표면입니다. 웹훅에서 살펴보세요. 서명 스킴은 같으므로 검증기 하나로 둘 다 처리할 수 있습니다.

웹훅 요청하기

실행을 시작할 때 communication.webhook_url을 보내세요. 세 표면 모두 같은 방식으로 동작합니다.

Create a Format run

POST /v1/formats/{handle}/{slug}/runs

Required

필드설명
communication.webhook_url공개 HTTPS URL이며 최대 2048자입니다. localhost, 사설 네트워크, HTTPS가 아닌 URL은 400 invalid_request로 거부됩니다.
communication.callback_urlwebhook_url의 별칭입니다. 동작은 같습니다. 둘 중 하나만 보내세요.
communication.modeasync(기본) 또는 webhook입니다. 실제로 전달을 켜는 것은 URL이고, mode는 설명용입니다.
최상위 webhook_url / callback_url / modefal 형태의 별칭입니다. communication.*로 정규화됩니다. 양쪽이 같으면 허용되고, 값이 다르면 400 invalid_request입니다.

URL은 제출할 때만이 아니라 전달 시점에도 공개 HTTPS URL인지 다시 검증합니다. 리다이렉트는 따라가지 않으므로 3xx는 전달이 아닙니다.

이벤트

실행 계열마다 종료 이벤트가 하나씩 있습니다. 결과는 이벤트 이름이 아니라 statuspayload.status에 담깁니다.

표면이벤트영수증 object
Action 실행action.run.terminalaction.run
Format 실행format.run.terminalformat.run
Agent Completionsagent.run.terminalagent.run

Format만 임베드한 파트너라면 본문을 들여다보지 않고 event === "format.run.terminal"로 분기할 수 있습니다.

페이로드

필드설명
event위 표를 참고하세요.
request_idrun_id와 같습니다. 재시도에도 값이 유지되니 중복 제거에 사용하세요.
run_id이 전달이 다루는 실행입니다.
object영수증 자체의 object입니다.
status실행이 완료됐으면 OK, 실패했으면 ERROR입니다.
payload실행 영수증입니다. 크기 초과일 때만 null입니다. 아래를 참고하세요.
errorstatusOKnull이고, 그 외에는 { code, message }입니다.

usage.billable_amount_usd_micros는 실행에 귀속된 생성 지출을 담고, 이를 읽지 못하면 usagenull입니다. 실행과 결과에서 살펴보세요. 권위 있는 과금 기록은 여전히 GET /v1/usage입니다.

가 곧 영수증입니다

payload는 같은 실행에 대한 GET /v1/{family}-runs/{run_id}data 객체와 바이트 단위로 동일합니다. 폴링 응답은 이를 { "data": ... }로 감싸지만 웹훅은 감싸지 않습니다.

폴링 엔드포인트가 호출하는 것과 같은 코드 경로로 만들어지므로 어긋날 수 없습니다.

실패, 취소, 건너뜀

실패한 실행은 status: "ERROR"와 값이 채워진 error로 도착합니다. payload는 여전히 전체 영수증입니다. 실패한 실행의 영수증에도 artifactsoutput_error가 담겨 있고, 보통 그것들이 필요합니다.

영수증에 오류가 있으면 error.codepayload.error.code를 그대로 반영합니다. 보통은 output_schema_unsatisfied 같은 구체 사유이고, 없으면 계열별 일반 코드인 action_run_failed / format_run_failed / agent_run_failed입니다.

canceled 실행은 웹훅을 보내지 않습니다. 취소는 별도 API 경로입니다(fal 큐 취소와 같은 개념 — 취소용 웹훅 상태가 없습니다). POST …/cancel 뒤에는 취소 응답을 신뢰하고 status_url을 폴링해 payload.statuscanceled가 될 때까지 기다리세요. POST를 기다리지 마세요.

skipped 실행은 웹훅을 보내지 않습니다. on_active_run: "skip"은 작업을 시작하지도 않고 곧바로 종료 실행을 기록하므로 알릴 완료 자체가 없습니다. 생성 응답이 이미 알려줬습니다. 오지 않을 POST를 기다리지 말고 받은 응답의 status를 읽으세요.

너무 큰 영수증

1 MiB를 넘는 영수증은 본문에 담아 전달할 수 없습니다. Sume는 payload: null과 함께 어디서 가져오면 되는지 알려주는 오류를 담아 봉투를 보냅니다.

status는 여전히 실행의 실제 결과를 보고합니다. 성공했지만 크기가 커서 보내지 못한 실행이 실패한 것은 아닙니다.

서명

Sume는 원본 JSON 본문에 <timestamp>.<raw_body>에 대한 HMAC-SHA256 서명을 붙입니다.

JSON을 파싱하거나 다시 직렬화하기 전에 원본 요청 본문으로 검증하세요. 재전송 허용 시간을 벗어난 타임스탬프는 거부하세요. 5분이 무난한 기본값입니다.

서명 시크릿은 대시보드의 웹훅 탭(/dashboard/webhooks)에서 직접 확인하거나, account:read 범위를 가진 API 키로 GET /v1/webhooks/signing-secret을 호출해 받을 수 있습니다. 워크스페이스별로 파생된 값이므로, 다른 사람의 시크릿으로는 여러분에게 서명된 전송을 검증할 수 없습니다. 전달 워커가 서명할 때 쓰는 것과 같은 이름인 SUME_COM_WEBHOOK_SIGNING_SECRET으로 저장하세요.

모든 전송에는 x-sume-webhook-secret-fingerprint 헤더가 실리고, Run 영수증의 webhook_delivery.signing_secret_fingerprint에도 같은 값이 담깁니다. 대시보드에서 시크릿 옆에 표시된 지문과 비교하면 시크릿을 어디에도 보내지 않고 양쪽이 같은 값을 쓰고 있는지 확인할 수 있습니다.

TypeScript에서는 @sume-com/sdk가 이 검증을 제공합니다. 웹훅 검증에서 살펴보세요.

다른 언어나 앱 앞단 게이트웨이처럼 SDK를 쓸 수 없는 수신기를 위해 스킴 전체를 싣습니다.

생성 Job 웹훅을 검증하는 것과 같은 검증기입니다. 한 번만 작성하세요.

전달 동작

속성
시점실행당 한 번, 완료되거나 실패할 때입니다.
성공모든 2xx입니다.
재시도최대 10회이며, 그다음 webhook_delivery.statusexhausted입니다.
백오프min(max(지터를 더한 30s × 2^(attempt−1), Retry-After), 1h)입니다. 429/503의 Retry-After를 존중합니다.
타임아웃시도당 10초입니다.
리다이렉트따라가지 않습니다. 3xx는 실패한 시도입니다.

이벤트를 내구성 있게 기록한 뒤 2xx를 빠르게 반환하고, 처리는 그다음에 하세요. 느린 엔드포인트는 10초 예산을 소진하고 재시도를 부릅니다.

request_id로 중복을 제거하세요. 같은 실행의 재시도에서는 값이 같습니다.

전달 결과는 실행 자체를 바꾸지 않습니다. 열 번의 시도를 모두 거부한 엔드포인트가 남기는 것은 실패한 전달이고, 실행은 여전히 completed입니다. result_url에서 가져오세요.

다음