Shopify collection.products trigger: one Sume job per product added

Shopify Events' collection.products trigger fires when a product joins or leaves a collection. Key one Sume image job on collection and product ids.

4 min readSume
All posts

Subscribe to collection.products in Shopify Events and Shopify's example delivery names the collection and the product that joined it. Start a Sume job only for an addition, and set the Idempotency-Key to the collection id plus the product id, so a redelivery returns the original job instead of billing a second time.

Shopify details are from its Next Gen Events announcement, read 2026-10-01; Sume retry rules from Jobs and results and Webhooks.

What does the collection.products trigger send?

Shopify says Events are generally available with the 2026-10 API version. You configure a subscription in shopify.app.toml with triggers, a GraphQL query and an optional query_filter. Its example subscribes to collection.products and, when product 456 is added to collection 123, the payload carries the collection id and the product id as query variables.

Events pieces used here, Shopify developer blog, read 2026-10-01.
PieceFrom Shopify's page
Triggercollection.products
Ids in the payloadcollectionId and productsId
Action on an addupdate
What changedfields_changed.added

How do I stop a retry from billing twice?

Sume's video submit route accepts Idempotency-Key: a replay returns the original job. The jobs docs say that on a retry you reuse the same key and do not submit a new paid job for the same intent. Build the key from the ids in the delivery, for example bfcm:123:456, so the same product added to the same collection always maps to the same job. The Image API also lists an optional Idempotency-Key header.

async function onProductAdded(collectionId, productsId) {
  const res = await fetch("https://api.sume.com/v1/images", {
    method: "POST",
    headers: {
      Authorization: "Bearer " + process.env.SUME_API_KEY,
      "Content-Type": "application/json",
      "Idempotency-Key": "bfcm:" + collectionId + ":" + productsId,
    },
    body: JSON.stringify({
      model: "openai/gpt-image-2.5",
      prompt: "Black Friday banner for a new product, bold clean layout",
      image_size: "1536x640",
    }),
  });
  if (!res.ok) throw new Error("Sume returned " + res.status);
  return res.json();
}

What about a product that is removed?

Shopify's collection example shows an add only, so check fields_changed on every delivery: Shopify's changelog says it is now an object with added, updated and removed arrays. Only added should call Sume. Removals are a cleanup in your own store, not a paid job. The same split is covered in the variants wildcard post.

How do I dedupe on my side?

Sume's webhook docs tell receivers to treat job_id as the idempotency key for Sume's own callbacks. For Shopify's side, the changelog says the shopify-event-id header is removed from Events deliveries, so use your own key from the ids instead; see the removed header post.

Sources

Related posts

More in Integrations

All Integrations posts

Written by Sume