Sora API gone: 9:16 portrait video on Sume, model by model
Which Sume video models return 9:16 after the Sora API ended on 2026-09-24, how to ask for it, and a script that reads the catalog instead of trusting a table.

To get 9:16 portrait video from Sume after the OpenAI Sora API ended, send aspect_ratio: "9:16" and a resolution on POST /v1/videos, and pick a model whose supported_aspect_ratios includes 9:16. Gemini Omni Flash 1.1 (gemini-omni-flash-1.1) takes only 16:9 and 9:16, so a vertical-first workload fits it directly. Seedance 2.0 (seedance-2) lists 9:16 among six ratios. For every other model, read the field instead of assuming.
A tracker of video releases reports that the OpenAI Sora API ended on 2026-09-24 and that Sora was discontinued (Magic Hour tracker, read 2026-10-06). If your code sent a portrait pixel size to Sora, the Sume wire works differently, and this page covers that change.
Ratio plus resolution, not a pixel size
Sume's /v1/videos follows the OpenRouter video wire. It takes resolution (480p, 720p, 768p, 1080p, 1K, 2K, 4K) and aspect_ratio (16:9, 9:16, 1:1, 4:3, 3:4, 3:2, 2:3, 21:9, 9:21). It does not take size: every v1 model reports supported_sizes: null, so a size field returns 400 unsupported_parameter (Sume video docs, read 2026-10-06).
So a ported call that said "portrait, 720 wide" becomes resolution: "720p" with aspect_ratio: "9:16". The model decides the exact pixel grid. Do not hard-code a pixel size in your own post-processing; read the file with the inspect tool if a downstream spec needs exact dimensions.
What the docs say about 9:16 per model
The catalog is per model, and the docs state a few of them outright. Treat the last column as the rule for everything else.
| Model id | Duration | Resolutions | 9:16 in the docs | How to confirm |
|---|---|---|---|---|
| gemini-omni-flash-1.1 | 3-10 s | 360p, 720p, 1080p, 4K | Yes, with 16:9 as the only other ratio | supported_aspect_ratios |
| seedance-2 | 4-15 s | 480p, 720p, 1080p | Yes, in a list of six ratios | supported_aspect_ratios |
| seedance-2.5 | 4-30 s | 480p, 720p, 1080p | Not stated on the page | supported_aspect_ratios |
| wan-3.0 | 2-30 s | 480p, 720p, 1080p | Not stated on the page | supported_aspect_ratios |
| minimax-h3-max | 5-15 s | 480p, 768p, 1080p | Not stated on the page | supported_aspect_ratios |
Submit a vertical job
This is the whole request. It returns a job id and a polling URL at once, with status pending.
curl -X POST "https://api.sume.com/v1/videos" \
-H "Authorization: Bearer $SUME_API_KEY" \
-H "Idempotency-Key: portrait-demo-001" \
-H "Content-Type: application/json" \
-d '{
"model": "gemini-omni-flash-1.1",
"prompt": "A barista pours oat milk into a flat white, handheld, morning light",
"aspect_ratio": "9:16",
"resolution": "720p",
"duration": 5
}'Read the catalog before you submit
A static table goes stale the first time a model changes. GET /v1/videos/models returns each model's ratios, resolutions and durations, so the script below lists every model that accepts 9:16 right now, with its duration range. Run it in CI next to your tests, and fail the build when the model you pinned stops listing 9:16.
import os
import requests
r = requests.get(
"https://api.sume.com/v1/videos/models",
headers={"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"},
timeout=30,
)
r.raise_for_status()
for m in r.json()["data"]:
if "9:16" in (m.get("supported_aspect_ratios") or []):
d = m.get("supported_durations") or []
span = f"{min(d)}-{max(d)} s" if d else "see docs"
print(m["id"], span, m.get("supported_resolutions"))Two traps when porting
First, 9:16 and 9:21 are different ratios. 9:21 is ultra-tall and rare; most social specs mean 9:16. Second, do not switch to a 16:9 render and crop it yourself unless you need a model that has no vertical mode. A crop throws away roughly two thirds of the pixels and often cuts the subject; ask for the ratio at submit time instead.
If you submit through the legacy Video Router, the same model ids work with a flat body, and the migration is a path-and-body change with no id remapping. New integrations are pointed at /v1/videos by the docs. The first-pass model guide and the 4K vertical comparison cover the choice of model and the resolution tier.
A portrait checklist for the migration
Before you flip the model id in config, run a short checklist against one real request. It takes a few minutes and avoids the two failures that look like bugs: a 400 on the submit, and a clip that renders in the wrong orientation because the ratio was left at its default.
The default matters. A request without aspect_ratio does not promise portrait, so a vertical product always sends the field, even when the model only has two ratios. Sending it costs nothing and documents the intent in your logs.
- Send
aspect_ratioandresolutionon every call; never rely on a default for a vertical product. - Remove any
sizefield from the ported body; it returns400 unsupported_parameter. - Remove
seed; it is not accepted on any v1 model and also returns 400. - Run the catalog script above in CI and pin the model id in config, so a catalog change fails a test before it fails a user.
- Probe the finished file for its real width and height, and store both next to the job id.
Sources
Related posts
More in Developers
- Parse a Sume video poll response with a dataclass, no network
A stdlib Python dataclass for the /v1/videos poll response (status, unsigned_urls, usage.cost, error), tested on sample JSON so a ported client fails early.
- Export old video prompts to JSONL, then re-render on Sume resumably
A prompt manifest for a Sora back catalog: one JSON line per clip with a stable idempotency key and status, and a runnable script that skips what is done.
- Photo to video on Sume: frame_images or input_references?
Which Sume video field starts from your photo and which only guides style. If you send both, frame_images wins. Two request bodies and a check you can run.
- Score a Sora replacement: five numbers to log for every clip
Before you cut over from Sora to a Sume video model, log five numbers per clip: status, wall time, usage.cost, duration asked and failures. Script included.
Written by Sume