Format run 400 on an empty body: what a create request must include
A Format run create must name instruction, input, previous_run_id or attachments. An empty object or an empty input object is a 400 invalid_request.

A Sume Format run create request has to say what to run: at least one of instruction, input, previous_run_id or attachments. A body of {} and a body of {"input":{}} both come back as 400 invalid_request, and nothing is queued or charged.
This is a fix-the-request error, so a retry loop will never clear it. Validate the body before the call.
What counts as content
The rules come from the Create a run page (read 2026-10-03).
| Body | Outcome |
|---|---|
| {} | 400 invalid_request |
| {"input":{}} | 400 invalid_request |
| {"instruction":"Make a 15 second teaser"} | Accepted |
| {"input":{"sku":"A-12"}} | Accepted |
| {"previous_run_id":"..."} on a resumable run | Accepted |
| {"webook_url":"https://..."} | 400 unknown_parameter, with a suggestion for webhook_url |
Limits that sit next to it
Once the body has content, the size rules apply. The whole request body is capped at 4 MiB (413 above that). input must be a JSON object with at most 64 top-level keys and 2 MiB. instruction accepts 8000 characters, though about 4000 are carried into the run, so keep the real request in the first part. Attachments go up to 30 files, with a lower cap for video and audio than for images.
Sending both output_schema and response_format is also a 400, as is a field the API does not know.
import json, os, urllib.request
body = {"instruction": "Cut a 15 second teaser"}
if not any(body.get(k) for k in ("instruction", "input", "previous_run_id", "attachments")):
raise SystemExit("empty Format body")
req = urllib.request.Request(
"https://api.sume.com/v1/formats/acme/teaser/runs",
data=json.dumps(body).encode(),
headers={"Authorization": "Bearer " + os.environ["SUME_API_KEY"],
"Content-Type": "application/json"},
)
print(json.load(urllib.request.urlopen(req))["data"]["id"])Where it usually comes from
Templating bugs produce most empty bodies: a form with no fields filled yields {"input":{}}. Reject it in your own code with a clear message, and read the typo suggestion when the 400 names an unknown field instead.
Sources
Related posts
More in Formats
- Four places a Format run fails, and a message for each
Format runs fail at submit, during the run, as a non-failure terminal state, or at webhook delivery. Each needs its own retry rule and its own UI message.
- Format run Idempotency-Key: header or body, and four replay outcomes
Send Idempotency-Key as a header or idempotency_key in the body; the header wins. Same key and body gives 200 idempotency_hit true; a new body is a 409.
- Format run media budget: 30 files, 10 videos, 10 audio for a lookbook
A Sume Format run shares one attachment budget: 30 files, 30 images, 10 videos, 10 audio. Plan a lookbook run so it stays under invalid_attachment.
- Format run media URLs are public: copy on webhook or proxy
Sume Format run media lives at durable public media.sume.com URLs. If customer A must not see customer B's video, copy it at receipt time or proxy it.
Written by Sume