A video provider interface after the Sora shutdown, Sume behind it
OpenAI lists the Sora API shutdown as 2026-09-24 with no replacement. Put video generation behind one interface so the next vendor exit is a config change.

OpenAI's deprecations page lists the Sora video API shutdown date as September 24, 2026 and names no recommended replacement (read 2026-10-03). Code that called it directly now needs a new backend; code that called it through one interface needs a new adapter. The interface below is small on purpose, shaped by what an async job API actually returns.
Shape the interface around jobs
Every hosted video API is asynchronous, so do not model generation as a function that returns a video. Model it as submit, then a handle you can persist, then a poll that yields a terminal state with output URLs. That maps directly to a Sume job: the submit returns a job id, GET /v1/jobs/:id/status reports terminal, and the result carries artifacts on media.sume.com.
export type VideoRequest = {
prompt: string;
imageUrl?: string;
durationSeconds?: number;
resolution?: "720p" | "1080p";
idempotencyKey: string;
};
export type VideoStatus =
| { state: "pending"; pollAfterSeconds?: number }
| { state: "done"; urls: string[] }
| { state: "failed"; code: string; retryable: boolean };
export interface VideoProvider {
submit(req: VideoRequest): Promise<{ handle: string }>;
status(handle: string): Promise<VideoStatus>;
cancel(handle: string): Promise<void>;
}What the Sume adapter maps
On Video 1.0, prompt, image_url, duration and resolution are documented request fields, and Idempotency-Key is the header for safe retries. Video 1.0 is documented as a retiring compatibility alias; for new code the docs point to POST /v1/videos with a catalog model id, so check the live OpenAPI before you hard-code a path.
| Interface | Sume Video 1.0 field | Notes |
|---|---|---|
| prompt | prompt | Required |
| imageUrl | image_url | First frame, public HTTPS |
| durationSeconds | duration | Integer seconds, validated per model |
| resolution | resolution | 720p default, 1080p allowed |
| idempotencyKey | Idempotency-Key header | Same key only for the same payload |
Keep vendor quirks inside the adapter
Polling cadence, download URL lifetimes and size rules differ by vendor, so they belong in each adapter, not in callers. Run the same five prompts through every adapter in CI and record what differs; that is the exit drill, written as a test.
Sources
Related posts
More in Developers
- Video API 400 unsupported_parameter: size, seed and provider.options
Sume's /v1/videos returns 400 unsupported_parameter for size, seed and a non-empty provider.options. Use resolution and aspect_ratio, and strip the rest.
- Video Router aliases first_frame_url, last_frame_url, duration_seconds
Three Video Router fields are aliases: first_frame_url for image_url, last_frame_url for end_image_url, duration_seconds for duration. Use the canonical names.
- Video Router sync waits 30 seconds; your Seedance 2.5 clip keeps going
mode sync and subscribe are the same bounded wait of at most 30 seconds. A long Seedance 2.5 job returns 2xx with the current state; poll, do not resubmit.
- video_trim_output_requires_exact: keyframe cuts can't resize
FFmpeg stream copy cannot filter, and Sume's keyframe trim cannot take an output size or fps. Why it is refused, and the one-line fix.
Written by Sume