The official TypeScript library for the OpenAI API
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Generate, manage, and remix videos using OpenAI's Sora video generation models. The Videos API enables text-to-video generation with support for different durations, resolutions, and the ability to use image references for guided generation.
Create videos from text prompts using Sora models.
/**
* Create a video from a text prompt
* @param params - Video generation parameters
* @returns Video job object with generation status
*/
function create(params: VideoCreateParams): Promise<Video>;
interface VideoCreateParams {
/** Text prompt that describes the video to generate */
prompt: string;
/** Optional image reference that guides generation */
input_reference?: Uploadable;
/** The video generation model to use. Defaults to 'sora-2' */
model?: VideoModel;
/** Clip duration in seconds. Defaults to 4 seconds */
seconds?: VideoSeconds;
/** Output resolution formatted as width x height. Defaults to 720x1280 */
size?: VideoSize;
}Usage Example:
import OpenAI from "openai";
const client = new OpenAI();
// Generate a 8-second video
const video = await client.videos.create({
prompt: "A serene mountain landscape at sunset with clouds rolling over peaks",
model: "sora-2",
seconds: "8",
size: "1280x720",
});
console.log(`Video job created: ${video.id}`);
console.log(`Status: ${video.status}`);
console.log(`Progress: ${video.progress}%`);Retrieve information about a video generation job.
/**
* Retrieve a video job by ID
* @param videoID - Unique identifier for the video job
* @returns Video job object with current status
*/
function retrieve(videoID: string): Promise<Video>;Usage Example:
// Check video generation progress
const video = await client.videos.retrieve("video_abc123");
if (video.status === "completed") {
console.log("Video generation complete!");
console.log(`Downloadable until: ${new Date(video.expires_at! * 1000)}`);
} else if (video.status === "failed") {
console.error("Generation failed:", video.error?.message);
}List all video generation jobs with pagination support.
/**
* List video generation jobs
* @param params - List parameters for pagination and sorting
* @returns Paginated list of video jobs
*/
function list(params?: VideoListParams): Promise<VideosPage>;
interface VideoListParams {
/** Sort order of results by timestamp */
order?: "asc" | "desc";
/** Maximum number of items to return */
limit?: number;
/** Cursor for fetching the next page of results */
after?: string;
}Usage Example:
// List recent video jobs
for await (const video of client.videos.list({ order: "desc", limit: 20 })) {
console.log(`${video.id}: ${video.status} - ${video.prompt?.substring(0, 50)}`);
}Delete a video job and its associated assets.
/**
* Delete a video job
* @param videoID - Unique identifier for the video job
* @returns Deletion confirmation response
*/
function delete(videoID: string): Promise<VideoDeleteResponse>;
interface VideoDeleteResponse {
/** Identifier of the deleted video */
id: string;
/** Indicates that the video resource was deleted */
deleted: boolean;
/** The object type that signals the deletion response */
object: "video.deleted";
}Usage Example:
const result = await client.videos.delete("video_abc123");
console.log(`Video ${result.id} deleted: ${result.deleted}`);Download the generated video content or associated assets.
/**
* Download video content or related assets
* @param videoID - Unique identifier for the video job
* @param params - Download parameters specifying which variant to retrieve
* @returns Response object containing the binary content
*/
function downloadContent(
videoID: string,
params?: VideoDownloadContentParams
): Promise<Response>;
interface VideoDownloadContentParams {
/** Which downloadable asset to return. Defaults to the MP4 video */
variant?: "video" | "thumbnail" | "spritesheet";
}Usage Example:
// Download the generated video
const response = await client.videos.downloadContent("video_abc123", {
variant: "video",
});
// Save to file (Node.js)
const fs = require("fs");
const buffer = Buffer.from(await response.arrayBuffer());
fs.writeFileSync("output.mp4", buffer);
// Download thumbnail
const thumbnail = await client.videos.downloadContent("video_abc123", {
variant: "thumbnail",
});Create a new video based on an existing video with a modified prompt.
/**
* Create a remix of an existing video with a new prompt
* @param videoID - Unique identifier for the source video
* @param params - Remix parameters with updated prompt
* @returns New video job object for the remix
*/
function remix(videoID: string, params: VideoRemixParams): Promise<Video>;
interface VideoRemixParams {
/** Updated text prompt that directs the remix generation */
prompt: string;
}Usage Example:
// Create a remix with modified conditions
const remixedVideo = await client.videos.remix("video_abc123", {
prompt:
"The same mountain landscape at sunset, but now with dramatic lightning in the sky",
});
console.log(`Remix job created: ${remixedVideo.id}`);
console.log(`Remixed from: ${remixedVideo.remixed_from_video_id}`);interface Video {
/** Unique identifier for the video job */
id: string;
/** Unix timestamp (seconds) for when the job was created */
created_at: number;
/** Unix timestamp (seconds) for when the job completed, if finished */
completed_at: number | null;
/** Unix timestamp (seconds) for when the downloadable assets expire, if set */
expires_at: number | null;
/** Current lifecycle status of the video job */
status: "queued" | "in_progress" | "completed" | "failed";
/** Approximate completion percentage for the generation task */
progress: number;
/** The prompt that was used to generate the video */
prompt: string | null;
/** The video generation model that produced the job */
model: VideoModel;
/** Duration of the generated clip in seconds */
seconds: VideoSeconds;
/** The resolution of the generated video */
size: VideoSize;
/** Identifier of the source video if this video is a remix */
remixed_from_video_id: string | null;
/** Error payload that explains why generation failed, if applicable */
error: VideoCreateError | null;
/** The object type, which is always 'video' */
object: "video";
}
interface VideoCreateError {
code: string;
message: string;
}/** Available video generation models */
type VideoModel = "sora-2" | "sora-2-pro";sora-2 - Standard Sora model for video generationsora-2-pro - Pro version with enhanced capabilities/** Available video durations in seconds */
type VideoSeconds = "4" | "8" | "12";Supported durations: 4, 8, or 12 seconds.
/** Available video resolutions formatted as width x height */
type VideoSize = "720x1280" | "1280x720" | "1024x1792" | "1792x1024";720x1280 - Vertical/portrait (9:16 aspect ratio)1280x720 - Horizontal/landscape (16:9 aspect ratio)1024x1792 - Vertical/portrait (wider format)1792x1024 - Horizontal/landscape (wider format)import OpenAI from "openai";
const client = new OpenAI();
async function generateAndDownloadVideo() {
// 1. Create video generation job
const video = await client.videos.create({
prompt: "A bustling Tokyo street at night with neon lights",
model: "sora-2-pro",
seconds: "12",
size: "1792x1024",
});
console.log(`Video generation started: ${video.id}`);
// 2. Poll for completion
let currentVideo = video;
while (
currentVideo.status === "queued" ||
currentVideo.status === "in_progress"
) {
await new Promise((resolve) => setTimeout(resolve, 5000)); // Wait 5 seconds
currentVideo = await client.videos.retrieve(video.id);
console.log(`Progress: ${currentVideo.progress}%`);
}
// 3. Check for success
if (currentVideo.status === "completed") {
console.log("Video generation completed!");
// 4. Download the video
const response = await client.videos.downloadContent(video.id);
const buffer = Buffer.from(await response.arrayBuffer());
// Save to file
const fs = require("fs");
fs.writeFileSync(`${video.id}.mp4`, buffer);
console.log(`Video saved to ${video.id}.mp4`);
// 5. Optionally create a remix
const remix = await client.videos.remix(video.id, {
prompt: "The same Tokyo street at night, but with rain falling",
});
console.log(`Remix job created: ${remix.id}`);
} else if (currentVideo.status === "failed") {
console.error("Video generation failed:", currentVideo.error?.message);
}
}
generateAndDownloadVideo();expires_at field)progress field provides approximate completion percentageerror fieldinput_reference can guide the generation processInstall with Tessl CLI
npx tessl i tessl/npm-openai