Standard Webhooks headers vs Sume sume-v1: a header map
Sume does not send webhook-id, webhook-timestamp or webhook-signature. It sends x-sume-webhook-* headers with a sume-v1 hex signature. Use verifyWebhook.

A stock Standard Webhooks verifier will not accept a Sume delivery as-is. Sume sends x-sume-webhook-timestamp and x-sume-webhook-signature: sume-v1=<hex_signature>, not the webhook-id, webhook-timestamp and webhook-signature trio. Verify with verifyWebhook from @sume-com/sdk.
Spec facts are from the Standard Webhooks page; Sume facts from Webhooks and Run webhooks, read 2026-09-30.
How do the headers map?
The spec prefixes every header with webhook- and uses a space-delimited signature list. Sume uses its own names and a comma-separated list.
| Role | Standard Webhooks | Sume |
|---|---|---|
| Message id | webhook-id | None; dedupe on job_id (jobs) or request_id (runs) |
| Timestamp | webhook-timestamp (unix seconds) | x-sume-webhook-timestamp: 1780000000 |
| Signature | webhook-signature, e.g. v1,<base64> | x-sume-webhook-signature: sume-v1=<hex_signature> |
| Multiple signatures | Space-delimited list | Comma-separated sume-v1= entries during rotation |
| Signed content | message id, timestamp and payload joined by dots | <timestamp>.<raw_body> |
What do I dedupe on without a webhook-id?
For job webhooks, use job_id as the idempotency key on your side. For run webhooks, request_id equals the run id and is the same on every retry: "Stable across retries — use it to dedupe." Use created_at to order deliveries, since request_id cannot. See request_id stable across retries.
Why does a Standard Webhooks library fail on it?
It looks for the webhook-* headers and the spec's signed content, neither of which Sume sends. The spec encodes its example signature as v1,<base64>; Sume encodes hex after sume-v1=. A mismatch on any of these makes verification fail even with the right secret.
Both sides agree on one rule: sign and verify the exact bytes. The spec warns that parsing the body as JSON and re-serializing it is a common cause of failed verification, and Sume's docs say the same about the raw body.
What should I use instead?
verifyWebhook is the check, so you do not write it. It takes the raw body, the headers and SUME_COM_WEBHOOK_SIGNING_SECRET, is async, and returns false instead of throwing. One verifier covers job and run webhooks because they share one secret. If you must adapt an existing pipeline, put a thin verification step in front that calls it and forwards only verified bodies. More hardening notes are in webhook security best practices.
Sources
Related posts
More in Developers
- Stripe idempotency key length (255) and Sume's key rules
Stripe allows keys up to 255 characters. Sume generation keys are 1-255 printable ASCII and optional; crawl keys are required and capped at 200.
- Submitting 20 avatar videos at once: what each Sume plan accepts
Sume accepts as many paid jobs as concurrency plus queue allows: 6 on Free, 24 on Pro, 48 on Startup, 120 on Scale. Past that a submit returns 429 queue_full.
- Which model does Sume Agent Completions run? Only sume-agent
The model field on POST /v1/agent/completions accepts only sume-agent. Omit it for the same agent; any other value returns 400 invalid_request.
- sume --agent --json: what it redacts before you paste output
Sume CLI --agent mode redacts or summarizes URL-like and account fields where supported. What to still strip before pasting output into a ticket or chat.
Written by Sume