Cloudflare Worker for a social video pipeline: SDK verifyWebhook
@sume-com/sdk 0.2.0 needs only fetch and WebCrypto, so verifyWebhook runs in a Cloudflare Worker. Verify the raw body, then answer 2xx before you post.

@sume-com/sdk 0.2.0 has no runtime dependencies and needs only fetch and WebCrypto, so it runs on Node 18+, Bun, Deno and Cloudflare Workers. Its verifyWebhook is async, takes the raw body, headers and secret, and returns false instead of throwing, which fits a small Worker that receives a Sume webhook and starts a social post.
Read the secret from the dashboard Webhooks tab or GET /v1/webhooks/signing-secret with an account:read key, and store it as SUME_COM_WEBHOOK_SIGNING_SECRET.
What does the helper need?
From Sume's SDK docs.
| Field | Notes |
|---|---|
body | The raw body: string, ArrayBuffer or typed array |
headers | A Headers, Map or plain object; case-insensitive |
secret | Your Sume webhook signing secret |
toleranceSeconds | Replay window; default 300; 0 skips the timestamp check |
What does the Worker look like?
Read the body as text before any JSON parse, refuse a missing secret, and return a fast 2xx.
import { verifyWebhook } from "@sume-com/sdk";
export default {
async fetch(request: Request, env: { SUME_COM_WEBHOOK_SIGNING_SECRET?: string }) {
const secret = env.SUME_COM_WEBHOOK_SIGNING_SECRET;
if (!secret) return new Response("not configured", { status: 500 });
const body = await request.text();
const ok = await verifyWebhook({ body, headers: request.headers, secret });
if (!ok) return new Response("bad signature", { status: 401 });
const event = JSON.parse(body);
if (event.event === "job.completed") {
// enqueue the platform posts here, keyed by event.job_id
}
return new Response(null, { status: 204 });
},
};What should happen after the 2xx?
Do the platform posts from a queue, not inside the request: Sume allows 10 seconds for each attempt, and a slow endpoint spends that budget and is retried. Dedupe on job_id, since a delivery can arrive more than once.
Sources
Related posts
More in Developers
- compose_duration_clamped_to_source: the banner clip came out shorter
Compose clamps video.duration to the source file and warns compose_duration_clamped_to_source. The job still succeeds; read the result length first.
- Conversational video edits on Omni: a three-turn chain on Sume
Edit a clip in turns on Sume: each Omni video_to_video call takes the last result as video_url. Three turns on a 10 s clip cost $3.75 at 720p. curl chain.
- createSumeClient custom fetch: log ratelimit-remaining as you go
Pass your own fetch to createSumeClient to warn when ratelimit-remaining runs low, without wrapping every SDK call. Works on Node 18+, Bun, Deno, Workers.
- C# HttpClient and Sume images: keep the key off the download call
Reuse one HttpClient, but set the bearer header per request, not as a default header, or it also rides along when you download the Sume image URL.
Written by Sume