9:16, 1080p, 8 seconds: one Sume /v1/videos request, poll and download
A copy-paste flow for a vertical clip: POST /v1/videos with aspect_ratio 9:16, resolution 1080p and duration 8, poll the job, then fetch the MP4 content URL.

To get a vertical clip from Sume, POST to /v1/videos with aspect_ratio: "9:16", a resolution and an integer duration, poll the returned job until its status is completed, then fetch /v1/videos/{job_id}/content?index=0, which redirects to the file. The three fields are what a platform spec turns into: ratio, resolution and length.
Submit
sume/auto picks a model for you. The Videos doc says it validates against Gemini Omni Flash 1.1 limits: 3 to 10 seconds, 360p, 720p, 1080p or 4K, and 16:9 or 9:16. Eight seconds at 9:16 fits. Send an Idempotency-Key so a retry returns the original job instead of a second job.
curl -X POST https://api.sume.com/v1/videos \
-H "Authorization: Bearer $SUME_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: vertical-demo-001" \
-d '{"model":"sume/auto","prompt":"A vertical product clip of a ceramic mug on a desk, natural light","aspect_ratio":"9:16","resolution":"1080p","duration":8}'Poll and download
The submit returns 202 with an id, a polling_url and status: pending. Poll that URL. The job moves through pending and in_progress to completed or failed. When it completes, unsigned_urls[0] points at the content route.
curl -s -H "Authorization: Bearer $SUME_API_KEY" "$POLLING_URL"
curl -L -H "Authorization: Bearer $SUME_API_KEY" \
"https://api.sume.com/v1/videos/$JOB_ID/content?index=0" -o clip.mp4Map a platform spec to the request
| Spec | Source | Request field |
|---|---|---|
| Vertical | TikTok recommends 9:16; YouTube Shorts are vertical | aspect_ratio: 9:16 |
| 1080p ceiling | YouTube Shorts page | resolution: 1080p |
| Up to 3 minutes | YouTube Shorts page | Not one request: join clips in Timeline |
| Length per clip | Sume model catalog | duration (integer seconds) |
Polling in a script
In a script, poll on a timer and stop on a terminal status. The doc lists the statuses as pending, in progress, completed, failed and cancelled. Treat completed as success and the other two terminal states as errors. Do not poll in a tight loop; a few seconds between calls is enough for a job that takes tens of seconds or more.
You can also pass a callback_url (HTTPS only) and let Sume call you when the job completes, with its standard job webhook envelope and the x-sume-webhook-signature header. If you verify that signature, reject an empty secret rather than treating it as valid.
The same job is also readable at GET /v1/jobs/{id}/status and GET /v1/jobs/{id}/result, in the usual Sume envelope, and id and generation_id are the same value. Pick one style and stay with it, since the two shapes differ.
Gotchas
size returns 400 on every v1 model, and so does seed. Use resolution plus aspect_ratio. The response model field echoes sume/auto and never names the family that ran. The poll body is a bare object, not the usual Sume data envelope. Read the seed and size explainer if a request is rejected.
Sources
Related posts
More in Developers
- AI video audio you cannot switch off: Omni 1.1, H3 and H3 Max on Sume
Gemini Omni Flash 1.1 rejects generate_audio false; MiniMax H3 and H3 Max have no toggle. To publish a clip with your own sound, drop the audio with video trim.
- AI video generator for business: build a request form from the API
Use GET /v1/formats and the io.input_kind field to build an internal video request form, grouped by what each Sume Format needs.
- AI video generator for business: no approval step over the API
Format runs started through the Sume API are unattended: approval gates are pre-granted. What that means for review, and the unattended_blocked failure.
- arq worker that polls an AI video job with defer_by in Python
An arq task reads Sume's job status once and enqueues itself again with _defer_by from next_poll_after_seconds, giving asyncio polling without a sleep loop.
Written by Sume