mode webhook returns 400 without a webhook_url: what Sume checks
Submit with mode webhook and no URL and Sume returns 400 invalid_request. Omit mode and send a URL and Sume picks webhook for you. Both rules explained.

A generation submit with mode: "webhook" and no webhook_url (or callback_url) fails with 400 invalid_request and the message "mode webhook requires webhook_url or callback_url." The reverse also holds in the API code: if you send a URL and leave mode out, Sume sets the mode to webhook for you.
These rules live in the submit validation for generation jobs, and they sit next to a few siblings that produce the same 400. The Webhooks page covers delivery, this page covers the submit-time checks.
How does Sume pick the mode?
Submit endpoints accept mode, webhook_url, callback_url, and wait_timeout_seconds. In the API's communication-options code, the effective mode is the one you sent, otherwise webhook when a URL is present, otherwise async.
That gives a short decision table.
| You send | Result |
|---|---|
| No mode, no URL | async: 202 with polling URLs |
| No mode, webhook_url set | webhook |
| mode webhook, no URL | 400 invalid_request |
| webhook_url and callback_url that differ | 400 invalid_request |
| mode sync or subscribe | Bounded wait, wait_timeout_seconds clamped to 0..30 |
What are the other 400s on this path?
webhook_url and callback_url are aliases. If both are present and differ, the API answers 400 with "Send only one callback destination. webhook_url and callback_url must match when both are present." Send one.
The URL itself must be a public HTTPS address. The docs say localhost, private-network, and non-HTTPS URLs are rejected. A tunnel URL from your laptop works only if it is public HTTPS.
Does mode change cost or runtime?
No. The communication modes section says the mode decides how you learn the outcome and never changes whether a job is created, what it costs, or how long it takes.
So a 400 on mode is always safe to fix and resend: it is rejected before a job exists. Still send an Idempotency-Key on paid submits you might replay.
A submit that cannot hit the mode 400
Setting the URL and the mode from one variable keeps them consistent. Keep a polling fallback anyway: webhook delivery is an optimization and the docs tell you to keep status_url polling available.
curl -X POST https://api.sume.com/v1/image-1.0/generate \
-H "Authorization: Bearer $SUME_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: hero-shot-001" \
-d '{
"prompt": "Product hero shot of a matte black bottle on marble",
"mode": "webhook",
"webhook_url": "https://hooks.example.com/sume"
}'What Sume does not do
Job webhooks are terminal-only: job.completed, job.failed, and job.canceled. There are no progress callbacks, so a webhook-mode submit cannot replace reading GET /v1/jobs/:id/events if you need a timeline.
Quick checklist
The points above reduce to a short list you can paste into a runbook.
- Send webhook_url or callback_url, not both, unless the values match.
- Use a public HTTPS URL; localhost, private-network and non-HTTPS URLs are rejected.
- Remember mode never changes price or runtime, only how you learn the outcome.
- Keep status_url polling as a backup for deliveries that never arrive.
- Send an Idempotency-Key on every paid submit that might be retried.
Sources
Related posts
More in Developers
- Return 503 with Retry-After in a deploy: Sume run webhooks honour it
Sume run webhooks honour Retry-After on 429 and 503 up to 1 hour. Job webhooks use a fixed 30s spacing, so keep the drain short and the fallback poll on.
- GET /v1/webhooks/signing-secret returns 403: key needs account:read
Sume returns 403 insufficient_scope with required_scope account:read when a key cannot read the webhook secret. Scopes cannot be added, so mint a new key.
- 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.
Written by Sume