Sume webhook_url 400: localhost, http, credentials, alias clash
Why a Sume create call rejects webhook_url with 400 invalid_request: localhost, private IPs, http, credentials in the URL, or conflicting webhook_url aliases.

Sume rejects a webhook URL with 400 invalid_request when it is not a public HTTPS URL, or when two spellings of the field disagree. Localhost, private-network ranges, plain http:// and credentials embedded in the URL all fail at create, before any run or job exists. The check runs again at delivery time, so a URL that passed at submit can still fail later.
Details below come from Run webhooks, Webhooks and Errors and spend, read 2026-10-02.
Which URLs does Sume refuse?
A rejected create returns the standard envelope with error.code of invalid_request, and nothing is charged.
| Your URL | Outcome | Fix |
|---|---|---|
| http://hooks.example.com/sume | 400 invalid_request (plain HTTP) | Use https |
| https://localhost:3000/hook | 400 invalid_request (localhost) | Expose a public HTTPS tunnel or staging host |
| https://10.0.0.5/hook | 400 invalid_request (private range) | Use a publicly routable host |
| https://user:pass@example.com/hook | 400 invalid_request (credentials in URL) | Authenticate with the signature, not the URL |
| URL over the 2048-character maximum (run webhooks) | Rejected at create | Shorten the URL; carry state in your own database |
What is the alias conflict?
Run endpoints accept the URL under several names. Inside communication, webhook_url and callback_url are aliases with identical behavior, so send one or the other. There are also fal-shaped top-level webhook_url, callback_url and mode fields, which Sume normalizes into communication.*. Sending the same value on both layers is fine. Conflicting values return 400 invalid_request.
Generation-job submits use the same idea: webhook_url and its alias callback_url. If you send a URL without a mode, you get webhook mode.
# Fine: same value on both layers
curl -sS -X POST https://api.sume.com/v1/formats/acme/product-promo/runs \
-H "Authorization: Bearer $SUME_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: promo-8823-v1" \
-d '{"instruction":"Make the promo",
"webhook_url":"https://hooks.example.com/sume",
"communication":{"webhook_url":"https://hooks.example.com/sume"}}'
# 400 invalid_request: the two layers name different URLs
# "webhook_url":"https://a.example.com/x"
# "communication":{"webhook_url":"https://b.example.com/x"}What does mode do for a run?
For Format, Action and Agent Completion runs, communication.mode is async (the default) or webhook, and the docs call it descriptive: supplying the URL is what arms delivery. There is no subscribe value for runs. So a run with a valid webhook_url and mode: "async" still gets its single terminal POST, and a run with mode: "webhook" but no URL has nothing to deliver to.
Why can a valid URL still fail later?
The URL is re-validated as public HTTPS at delivery time, not only when you submit. If DNS now points the host at a private address, or the endpoint starts redirecting, the attempt fails. Redirects are never followed, and a 3xx counts as a failed attempt, so register the final URL rather than a vanity link that redirects.
The failure shows up on the receipt as webhook_delivery.status of failed or exhausted with last_error, while the run itself stays completed. Read the receipt from result_url, fix the endpoint, and replay with the redeliver route.
A quick checklist before you submit
Run through these before the first paid call, because a 400 at create costs nothing but a blocked launch does.
- Use an
https://URL on a public host with a certificate that validates. - Put no username or password in the URL; verify the
sume-v1signature instead. - Send one spelling of the field, or the same value on every layer.
- Answer the first POST with a
2xxinside 10 seconds, then do the work. - Keep status polling as a backup for any event that never arrives.
Sources
Related posts
More in Developers
- Which Sume audio endpoint to call: TTS, STT, music, detach, timeline
A decision map for Sume's audio API: seven endpoints, what each takes in and returns, limits and list prices, and the order they chain in.
- Sume video tools: public URL or media import first? Per tool
Video captions takes a public HTTPS URL; trim, filter, inspect, frames, compose and detach need a workspace media.sume.com clip. A tool-by-tool input guide.
- Which voice does my avatar speak with? Check voice.status is ready
Sume TTS speaks in an avatar's voice when voice.status is ready. List avatars, check voice.status, then send avatar_id or avatar_handle on the TTS request.
- YouTube API audit and quota extension forms: which one to file
YouTube lists four forms for API audits and quota: extension, appeal, periodic audit and change of control. When each applies, and the private-upload rule.
Written by Sume