Shopify 제품 영상 AI API: products/create 웹훅

Shopify products/create 웹훅에 오 초 안에 응답하고, 큐에서 Sume Format을 실행한 뒤 staged upload로 MP4를 Shopify에 올리세요.

읽는 시간 6분Sume
전체 글

새 Shopify 제품마다 AI 영상을 만들려면 products/create 웹훅을 구독하고, Shopify가 허용하는 오 초 안에 웹훅을 검증해 200으로 응답한 뒤, 큐에서 제품 사진을 attachments로 넣어 Sume Format 실행을 시작하세요. Sume의 서명된 웹훅이 primary_output_url을 돌려주면 stagedUploadsCreate와 fileCreate로 그 MP4를 Shopify에 업로드하고, 파일이 READY가 되면 제품에 연결하세요.

Sume에는 Shopify 앱이 없습니다. 여러분의 앱 서버가 HTTPS로 Shopify Admin API와 Sume를 직접 호출하는 방식입니다. Sume 관련 내용은 Format 호출하기 (영문)와 실행과 결과 (영문)에서, Shopify 관련 내용은 shopify.dev에서 가져왔으며 모두 2026-09-27에 확인했습니다. 제품 영상에 맞는 카탈로그 Format은 바로 쓰는 제품 영상 Format에서 다룹니다.

Shopify 웹훅에는 얼마나 빨리 응답해야 하나요?

Shopify가 허용하는 시간은 연결에 일 초, 요청 전체에 오 초이며, 3XX를 포함해 200번대를 벗어난 응답은 모두 오류입니다. 8회 연속으로 실패하면 Shopify는 Admin API로 설정한 구독을 삭제합니다. 오 초 안에 응답하기 위해 Shopify가 직접 권하는 방법은 큐이므로, 수신기는 다음 세 가지 짧은 일만 합니다.

  • X-Shopify-Hmac-SHA256을 검증하세요. 앱의 클라이언트 시크릿을 키로 원본 본문에 대해 계산한 base64 HMAC-SHA256입니다.
  • Shopify는 같은 웹훅을 두 번 이상 전달할 수 있으므로, 이미 저장한 X-Shopify-Webhook-Id는 건너뛰세요.
  • 제품을 큐에 넣고 200으로 응답하세요. Sume는 큐에서 호출하세요. Format 실행 생성 요청은 응답하기 전에 모든 첨부 파일을 가져와 복사합니다.

새 제품의 Sume 실행은 어떻게 시작하나요?

워커는 formats:write 스코프가 있는 키로 sume/{slug}의 카탈로그 Format을 호출합니다. 제목 같은 제품 텍스트는 instruction이 아니라 input에 넣으세요. Sume 문서는 제품 문구를 넣을 곳으로 input을 지목합니다. 보낸 값은 실행이 되풀이해 주지 않는 한 output으로 돌아오지 않으므로, data.id를 제품 ID 옆에 저장하세요.

  • attachments는 JPEG, PNG, WebP, GIF, AVIF 이미지를 최대 30장, 장당 30 MB, 실행당 500 MB까지 받습니다. Sume는 생성 시점에 이미지를 가져오므로 각 URL은 인증 없이 접근할 수 있어야 합니다. 접근할 수 없는 URL이 있으면 생성 요청이 502 attachment_fetch_failed와 details.index로 실패합니다.
  • Idempotency-Key는 제품 ID와, 의도적으로 다시 렌더링할 때 올리는 버전으로 만드세요. 같은 키와 본문을 보내면 두 번째 과금 없이 원래 영수증과 idempotency_hit: true가 200으로 돌아옵니다.
  • generation_spend_cap_usd로 제품 하나의 실행에 최대 $500까지 상한을 걸 수 있으며, 0은 거부됩니다.
  • Shopify의 products/create 샘플 페이로드에는 빈 images 배열이 들어 있습니다. 사진이 없는 제품에는 아직 첨부할 것이 없습니다.
// Queue worker. product = { id, title, imageUrls } from your queue.
async function startProductVideo(product) {
  const res = await fetch("https://api.sume.com/v1/formats/sume/sume-product-commercial/runs", {
    method: "POST",
    headers: {
      Authorization: "Bearer " + process.env.SUME_API_KEY,
      "Content-Type": "application/json",
      "Idempotency-Key": "shopify-product-" + product.id + "-v1",
    },
    body: JSON.stringify({
      instruction: "Make a product video from the attached photos.",
      input: { product_title: product.title },
      attachments: product.imageUrls.slice(0, 30).map((url) => ({ type: "input_image", image_url: url })),
      generation_spend_cap_usd: 20,
      communication: { webhook_url: "https://app.example.com/hooks/sume" },
    }),
  });
  const body = await res.json();
  if (!res.ok) throw new Error(body.error.code); // e.g. attachment_fetch_failed
  await saveRun(body.data.id, product.id);
}

Shopify 웹훅과 Sume 웹훅은 어떻게 다른가요?

앱은 서명된 웹훅 두 개를 받는데, 서명 방식도 두 가지이고 시크릿도 두 개이므로 각각에 별도의 라우트와 검증기를 두세요. 시크릿 교체 중에는 24시간 동안 Sume 헤더에 쉼표로 구분된 sume-v1= 항목 두 개가 실립니다. @sume-com/sdk의 verifyWebhook처럼 둘 중 어느 쪽이든 수락하세요.

Shopify의 "Verify webhook deliveries" 페이지와 Sume Run 웹훅 (영문) 페이지 기준, 2026-09-27 확인.
속성Shopify `products/create`Sume `format.run.terminal`
서명 헤더X-Shopify-Hmac-SHA256, base64x-sume-webhook-signature: sume-v1=<hex>
서명 대상 바이트원본 본문<timestamp>.<raw_body>
시크릿앱 클라이언트 시크릿워크스페이스 웹훅 서명 시크릿
응답 기한연결 1초, 전체 5초시도당 10초
재시도4시간에 걸쳐 8회최대 10회 시도
중복 제거 기준X-Shopify-Webhook-Idrequest_id
3xx 응답오류실패한 시도(리다이렉트를 따라가지 않음)

완성된 영상은 제품에 어떻게 연결하나요?

Sume는 실행이 완료되거나 실패하면 format.run.terminal 이벤트를 한 번 POST합니다. status: "OK"이면 payload.primary_output_url은 내구성 있는 media.sume.com URL이고, payload.artifacts[]는 파일마다 content_type, size_bytes, duration_ms를 나열합니다. 이 값들을 Shopify의 영상 한도와 비교해 확인하세요. Sume URL을 fileCreate에 바로 넘기지 마세요. Shopify의 `FileCreateInput`은 이미지, 일반 파일, 외부(YouTube 또는 Vimeo) 영상에만 외부 URL을 받으며, Shopify에 호스팅되는 영상에는 staged upload URL이 필요합니다. MP4를 내려받아 단계별로 업로드하세요.

  • stagedUploadsCreate(아래 뮤테이션)로 업로드 대상을 요청하세요. Shopify는 영상에 fileSize를 요구하므로 아티팩트의 size_bytes를 보내세요.
  • 반환된 url로 MP4를 멀티파트 폼 데이터로 POST하고, 반환된 parameters를 함께 보내세요.
  • resourceUrl을 originalSource로 넣고 contentType: VIDEO와 함께 `fileCreate`를 호출하세요.
  • 파일은 비동기로 처리됩니다. fileStatus가 READY(또는 FAILED)가 될 때까지 폴링한 뒤, productSet, productCreate, productUpdate 중 하나로 파일을 ID로 참조해 제품에 연결하세요.
  • 실패한 실행은 status: "ERROR"로 도착합니다. 영수증이 1 MiB를 넘었다면 payload는 null이고, error.result_url이 영수증을 가져올 위치를 알려 줍니다.
mutation {
  stagedUploadsCreate(input: [{
    filename: "product-video.mp4",
    mimeType: "video/mp4",
    resource: VIDEO,
    fileSize: "899765"
  }]) {
    stagedTargets { url resourceUrl parameters { name value } }
    userErrors { field message }
  }
}

어떤 한도가 있나요?

Shopify는 가져오는 파일에 한도를 두고, Sume의 규칙은 그 파일을 만드는 실행을 좌우합니다.

  • Shopify 영상은 MP4, MOV, WEBM 형식에 최대 1 GB, 10분, 3840x2160까지입니다. 앱은 스토어당 주당 최대 1,000개의 영상을 만들 수 있습니다.
  • API로 시작한 Format 실행은 사람의 개입 없이 진행됩니다. 레시피가 사람에게 요청할 승인은 미리 부여되어 있고, 끝낼 수 없는 실행은 failed로 돌아옵니다.
  • Shopify 미디어 가이드는 read_products, write_products, write_files 액세스 스코프가 있다고 가정합니다.
  • Format 실행의 미디어 URL은 URL을 가진 누구에게나 공개됩니다. 고객별 접근 제어가 필요하다면 프록시하거나 복사하세요.

출처

관련 글

연동 카테고리의 다른 글

연동 글 전체 보기

작성자 Sume