Make a vertical Short clip with curl and jq: submit, poll, download

A 20-line shell script that asks Sume for an 8-second 9:16 clip at 1080p, polls the job, and saves short.mp4, matched to YouTube's Shorts page.

4 min readSume
All posts

You can make a vertical Short clip with nothing but curl and jq: POST to https://api.sume.com/v1/videos with aspect_ratio: "9:16", read polling_url from the reply, loop until status is completed, then download unsigned_urls[0]. The script below does that in under 20 lines and asks for 1080p, which is the ceiling YouTube states for uploaded Shorts.

Two YouTube pages set the targets. Understand three-minute YouTube Shorts (read 2026-10-10) says a Short can be up to three minutes and must have a square or vertical aspect ratio. Get started creating YouTube Shorts (read 2026-10-10) says you can upload Short videos with a maximum resolution of 1080p. One clip from this script is 3 to 10 seconds, so it is a building block for a longer Short, not the whole thing.

The script

It uses Gemini Omni Flash 1.1 because the Sume docs list it at 3 to 10 seconds, 360p/720p/1080p/4K, in 16:9 or 9:16, with native synced audio. Set SUME_API_KEY in your environment first; the key is never written into the script.

set -euo pipefail
API=https://api.sume.com
AUTH="Authorization: Bearer $SUME_API_KEY"
job=$(curl -sS -X POST "$API/v1/videos" -H "$AUTH" \
  -H "Content-Type: application/json" -H "Idempotency-Key: short-001" \
  -d '{"model":"gemini-omni-flash-1.1","aspect_ratio":"9:16",
       "resolution":"1080p","duration":8,
       "prompt":"A barista pours latte art, close vertical shot, cafe sounds"}')
url=$(jq -r .polling_url <<<"$job")
while :; do
  r=$(curl -sS "$url" -H "$AUTH")
  s=$(jq -r .status <<<"$r")
  [ "$s" = completed ] && break
  case "$s" in failed|cancelled) jq -r '.error // .status' <<<"$r"; exit 1;; esac
  sleep 15
done
curl -sS "$(jq -r '.unsigned_urls[0]' <<<"$r")" -H "$AUTH" -o short.mp4
jq '{status, cost: .usage.cost}' <<<"$r"

Why each field is there

The Video Generation page says the surface follows the OpenRouter video API with a few Sume differences. Those differences decide what you can leave out of the request.

Fields in the script, from the Sume Video Generation docs (read 2026-10-10)
FieldValueReason
modelgemini-omni-flash-1.1Lists 9:16 and 3 to 10 seconds
aspect_ratio9:16Vertical, accepted for Shorts
resolution1080pMatches YouTube's 1080p upload ceiling
duration8Whole seconds, inside the model's range
Idempotency-Keyshort-001A retry returns the original job
size / seed / provider.optionsnot sentSume returns 400 for these on v1

What can go wrong

Check the loop's exit paths. A job can end as failed or cancelled, and the script prints the error field and stops rather than polling forever. The docs say a video usually takes from 30 seconds to several minutes, so a 15-second sleep is fine for one clip; for a batch, move to the callback_url webhook instead of many pollers.

If you change the model, change the numbers with it. The docs give seedance-2.5 4 to 30 seconds and wan-3.0 2 to 30 seconds, so an 8-second request fits all three, but a 2-second request fits only Wan. Read GET /v1/videos/models before you hard-code a duration.

Billing is visible in the last line. The poll response carries usage.cost, and the docs say Sume reserves the provider list price times 1.25 at submit; the cost field is the billable amount.

Check the file before you upload it

Do not trust the request alone; read the result. Sume's Video inspect page describes a probe that reads one media.sume.com clip your workspace already owns and returns probe facts plus sample stills, without re-encoding the source. Import the file first with POST /v1/media-imports, then send its URL as video_url with an Idempotency-Key.

Use the probe to confirm what you asked for: a vertical frame, a duration close to 8 seconds, and an audio stream. Use the stills to look at the first frame, because the opening seconds are what a Shorts viewer sees first. If the probe shows something other than what you requested, fix the request and resubmit under a new idempotency key; reusing the old key replays the original job.

From one clip to a Short

YouTube allows up to three minutes, and this script yields up to 10 seconds, so a full-length Short is a stitching job. Sume's Timeline 1.0 page describes joining ordered video slots with one audio spine into a single MP4. Keep the render at 1080 by 1920 or below for YouTube. Plan the join before you generate: eight 8-second clips make 64 seconds, and 22 make 176 seconds, just under the three-minute ceiling. The 1080p ceiling on the YouTube page is why the script does not ask for 4K, even though the model lists it.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume