Webhook URL with user:pass@ gets a 400: verify the signature instead
Sume refuses a run webhook_url that carries credentials, plain HTTP or a private host. Authenticate your receiver with the signed headers, not the URL.

No, you cannot put a username and password in a Sume communication.webhook_url. Credentials in the URL, plain HTTP, localhost and private ranges all return 400 invalid_request when you create the run, and nothing starts. The way to protect your receiver is to verify the signature that Sume puts on every delivery.
What the create call refuses
The webhook URL rules are the same for a single run and for each item of a bulk queue, because a bulk item is the same body as a single create. A bad URL on item 37 fails the whole bulk create before any queue exists, so check your URLs before you send 100 items.
Sume also checks the URL again at delivery time, not only at create. It does not follow redirects, so a 3xx counts as a failed attempt.
| URL | Result |
|---|---|
| https://hooks.example.com/sume | Accepted (public HTTPS, up to 2048 characters) |
| https://user:pass@hooks.example.com/sume | 400 invalid_request at create |
| http://hooks.example.com/sume | 400 invalid_request at create |
| https://localhost:3000/sume or a private range | 400 invalid_request at create |
| A URL that later answers 301 or 302 | Failed attempt; Sume does not follow it |
What to use instead of a password
Each delivery carries x-sume-webhook-timestamp, x-sume-webhook-signature (sume-v1=<hex>) and x-sume-webhook-secret-fingerprint. The signature is HMAC-SHA256 over <timestamp>.<raw_body> with your workspace signing secret, which you read on the dashboard Webhooks tab or from GET /v1/webhooks/signing-secret with a key that has account:read.
Verify against the raw bytes before you parse JSON, and reject timestamps outside a five-minute window. Compare the fingerprint header with the one next to the secret in the dashboard to confirm both sides hold the same secret. A receiver that refuses to start with an empty secret is safer than one that accepts everything.
- Verify first, then record the event durably, then answer 2xx within 10 seconds, then do the work.
- Dedupe on
request_id, which equals the run id and repeats on retries. - If you need a per-run routing hint, send it in
inputand look the run up by id on your side; the docs do not describe query-string behavior, so do not rely on it for secrets.
Tradeoffs
A signature proves that Sume sent the body, not that the body is new. A captured delivery replayed inside five minutes still verifies, so the dedupe on request_id matters as much as the signature. Anyone who finds your endpoint URL can still send it junk; the signature check is what makes that harmless.
Sources
Related posts
More in Developers
- Sume SDK 402 insufficient credits: it is returned, not thrown
Generated Sume SDK calls resolve with data, error and response. Turn a 402 into SumeInsufficientCreditsError with toSumeApiError and stop retrying.
- Sume SDK idempotencyKey: null sends no key, so POST retries stop
subscribeFormatRun mints a UUID Idempotency-Key by default. Pass null and the create call carries no key, so the SDK will not retry it on a 429 or 5xx.
- Sume SDK maxRetries: 0 when your job queue already retries the call
The SDK retries 408, 429 and 5xx twice by default. Under a queue with five attempts that is up to 15 tries. Set maxRetries to 0 and let one layer retry.
- Does the Sume SDK retry a failed video submit? Only with a key
createSumeClient retries GET and HEAD by default and retries a POST only when an Idempotency-Key header is set. See what is retried, what is not, and why.
Written by Sume