Webflow CMS item webhook to Sume: ack first, three retries, one image
Webflow retries a failed webhook 3 times, 10 minutes apart, then deactivates it. Ack with 200, key the Sume job by item id, and check the signature timestamp.

When a CMS item is created in Webflow, the collection_item_created webhook can start a Sume image job. Answer 200 quickly, key the Sume request by the item id, and skip draft items. Webflow retries a failed delivery 3 times at 10-minute intervals and deactivates a webhook that keeps failing, so a handler that blocks on generation can end up switching itself off.
This post gives the Sume side. Webflow's page describes signed requests, but write your verifier from that page and test it against a real delivery; the code below starts after verification.
What Webflow says about delivery
The webhook guide describes two headers, x-webflow-timestamp and x-webflow-signature, with the signed string built from the timestamp, a colon and the JSON body, and tells you to reject timestamps older than 5 minutes. It expects a 200 response, retries up to 3 times 10 minutes apart, and deactivates a webhook after repeated failures. A site can register up to 75 webhooks per trigger type.
The collection_item_created payload includes the item id, cmsLocaleId, fieldData with at least name and slug, and isDraft. That is all the Sume prompt needs: the name for the subject, and isDraft to avoid paying for images on items nobody will publish. When the editor later publishes the item, you can submit then, using the same key, and an earlier submit would simply be adopted.
| Webflow rule | Value | Handler decision |
|---|---|---|
| Expected response | 200 | Return it before slow work |
| Retries | 3, 10 minutes apart | Stable key from the item id |
| After repeated failure | Webhook deactivated | Do not return 5xx for permanent errors |
| Replay window | Reject timestamps older than 5 minutes | Check the timestamp header |
| Draft items | isDraft true in payload | Skip, or wait for publish |
Submitting from the payload
Pass the payload object from the verified webhook body. A 202 or a replay both count as success.
import os, requests
def submit_item_image(payload: dict) -> int:
if payload.get("isDraft"):
return 200
name = (payload.get("fieldData") or {}).get("name", "")
if not name:
return 200
try:
r = requests.post(
"https://api.sume.com/v1/images",
headers={"Authorization": f"Bearer {os.environ['SUME_API_KEY']}",
"Idempotency-Key": f"webflow-item-{payload['id']}"},
json={"model": "sume/auto", "mode": "async",
"prompt": f"Header illustration for a post titled: {name}"},
timeout=15,
)
except requests.RequestException:
return 503
return 503 if r.status_code == 429 or r.status_code >= 500 else 200Why the slow path is separate
Webflow's 10-minute spacing gives you a long gap between attempts, which is good for a transient Sume outage and bad for a handler that hangs. Return 200 from the web request as soon as the job is submitted, and collect the finished image through the Sume job webhook. Writing it back to the CMS item is then an independent step with its own retries.
Sources
Related posts
More in Integrations
- Wix Stores product video: 50 MB limit and an AI clip
Wix Stores takes AVI, MP4, MOV or MPEG product video up to 50 MB. Measure a Sume clip, then shorten it, drop audio or conform its size with video trim.
- AgentCore SynchronizeGatewayTargets 202: refresh Sume's tool list
AgentCore Gateway caches an MCP target's tools in DEFAULT mode and refreshes on SynchronizeGatewayTargets. Why Sume's listChanged false means you must sync.
- Where to set the AI label: Ads Editor, DV360, CM360, SA360, more
Google's AI label setting exists in Ads, Ads Editor, Search Ads 360, DV360, CM360 and Merchant Center. How a Sume-made clip moves through them.
- Amazon Seller Assistant plugin for Claude: add listing media
Amazon's Seller Assistant plugin (beta with Claude) reads your listings and sales. Pair it with Sume's hosted MCP server to make the missing images and clips.
Written by Sume