Submit a Sume video job with curl, save it with sume jobs download
The CLI has no video generate command, but jobs watch and jobs download work on jobs created through the API. A shell script that submits, waits and saves.

Submit Video 1.0 with curl to POST /v1/video-1.0/generate, then use the CLI for the rest: sume jobs watch <job_id> to wait and sume jobs download <job_id> --output-dir ./out to save the files. The CLI has no sume video command, but its job helpers work for Image, Video and Music jobs you created through the API.
The script below does exactly that, and keeps the job id in a file so a restart recovers the job instead of paying for a second one.
Why split the work between curl and the CLI?
The generation workflows page is explicit: Avatar 1.0 and Avatar Video 1.0 are the only generation families with CLI submit commands, and Image, Video and Music are API-first. It also says not to invent sume image, sume video or sume music.
What the CLI does give you for those families is recovery. The jobs page says the job helpers work for Avatar CLI submits and for Image, Video and Music jobs created via the Developer API. Downloading artifacts into a folder is the part people otherwise write by hand.
What is the script?
Submit with an Idempotency-Key derived from the thing being made, and mode: async, which is the SDK-documented way to avoid the 30 second server-side wait. The accepted response carries the job id at data.request_id, the field the SDK's waitForJob is given in its own example. The script needs jq:
#!/usr/bin/env bash
set -euo pipefail
KEY="mug-hero-v1" # derive from what you are making
IDFILE=".sume-job-$KEY"
if [ ! -s "$IDFILE" ]; then
curl -fsS https://api.sume.com/v1/video-1.0/generate \
-H "x-api-key: $SUME_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $KEY" \
-d '{"prompt":"Slow push-in on a ceramic mug","mode":"async"}' \
| jq -r '.data.request_id' > "$IDFILE"
fi
JOB="$(cat "$IDFILE")"
sume jobs watch "$JOB"
sume jobs status "$JOB" --agent --json
sume jobs download "$JOB" --output-dir ./outWhat happens when the wait times out?
sume jobs watch polls until the job is terminal or its own timeout. A local timeout does not cancel anything. The troubleshooting page says to inspect the job before submitting another paid one, and the script is built for that: rerun it and it skips the submit because the id file exists, then watches the same job.
If the job failed or was canceled, jobs download has no completed media to write, and /v1/jobs/:id/result answers 409 job_not_completed for those states. Read sume jobs status first and branch on it. To stop a job that is still queued or processing, sume jobs cancel <job_id> --confirm-submit works only before generation starts; after that the API returns 409 job_generation_already_started.
What should I keep out of logs?
Result URLs on media.sume.com are public but still user data. The security page suggests summarizing media counts and types and using local filenames rather than full remote URLs. Use --agent --json when a tool or an AI agent reads the output, since it redacts URL-like and account fields where supported.
The script above deliberately prints status only. Store the downloaded files, not the URLs; Sume mirrors outputs to its own media host before exposing them, and you should keep your own copy of anything you deliver.
Can I do the same for Image and Music?
Yes. The same recovery commands work for any job, so only the submit line changes: POST /v1/image-1.0/generate for Image and POST /v1/music-router/generate for Music, with the body fields from the model guides. The API reference lists Music 1.0 as retiring and resolving through the Music Router, so prefer the router path for new code.
Because the script keys everything on the idempotency key and the id file, you can run one copy per asset in a loop. Mind the plan: write requests have a per-minute budget by plan (Free 120, Pro 300, Startup 600, Scale 1200), and a status poll counts against the separate, forty-times-larger read budget, so sume jobs watch cannot starve your submits. Generation concurrency is a different limit and is reported on generation_limits; valid submissions can still be accepted as queued while queue capacity remains.
When you move this into CI, store the id file as a cache or artifact keyed by the build, so a rerun of the same workflow recovers the job instead of paying again.
Sources
Related posts
More in Developers
- List Sume jobs: next_cursor, starting_after, and idempotency_key
Page through GET /v1/jobs with limit, next_cursor and starting_after, then recover a lost wave by joining your own key to each job's idempotency_key.
- Sume SumeMediaFile duration_ms: the 10 percent check and null
In a Sume structured output, a duration_ms must agree with the artifact's recorded length within 10 percent, or the projection fails. A null means not measured.
- Sume media tools: which answer 200 and which answer 202 by default
video-inspect defaults to sync, trim, filter, compose and detach to async, and video-frames always returns 202. Defaults, the 30 s wait, and how to poll each.
- next_poll_after_seconds vs recommended_poll_interval_seconds
Which delay a Sume poller should sleep: next_poll_after_seconds, recommended_poll_interval_seconds, or retry-after. Null rules, a fallback, and read budgets.
Written by Sume