0
# Videos
1
2
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.
3
4
## Capabilities
5
6
### Video Generation
7
8
Create videos from text prompts using Sora models.
9
10
```typescript { .api }
11
/**
12
* Create a video from a text prompt
13
* @param params - Video generation parameters
14
* @returns Video job object with generation status
15
*/
16
function create(params: VideoCreateParams): Promise<Video>;
17
18
interface VideoCreateParams {
19
/** Text prompt that describes the video to generate */
20
prompt: string;
21
/** Optional image reference that guides generation */
22
input_reference?: Uploadable;
23
/** The video generation model to use. Defaults to 'sora-2' */
24
model?: VideoModel;
25
/** Clip duration in seconds. Defaults to 4 seconds */
26
seconds?: VideoSeconds;
27
/** Output resolution formatted as width x height. Defaults to 720x1280 */
28
size?: VideoSize;
29
}
30
```
31
32
**Usage Example:**
33
34
```typescript
35
import OpenAI from "openai";
36
37
const client = new OpenAI();
38
39
// Generate a 8-second video
40
const video = await client.videos.create({
41
prompt: "A serene mountain landscape at sunset with clouds rolling over peaks",
42
model: "sora-2",
43
seconds: "8",
44
size: "1280x720",
45
});
46
47
console.log(`Video job created: ${video.id}`);
48
console.log(`Status: ${video.status}`);
49
console.log(`Progress: ${video.progress}%`);
50
```
51
52
### Video Retrieval
53
54
Retrieve information about a video generation job.
55
56
```typescript { .api }
57
/**
58
* Retrieve a video job by ID
59
* @param videoID - Unique identifier for the video job
60
* @returns Video job object with current status
61
*/
62
function retrieve(videoID: string): Promise<Video>;
63
```
64
65
**Usage Example:**
66
67
```typescript
68
// Check video generation progress
69
const video = await client.videos.retrieve("video_abc123");
70
71
if (video.status === "completed") {
72
console.log("Video generation complete!");
73
console.log(`Downloadable until: ${new Date(video.expires_at! * 1000)}`);
74
} else if (video.status === "failed") {
75
console.error("Generation failed:", video.error?.message);
76
}
77
```
78
79
### Video Listing
80
81
List all video generation jobs with pagination support.
82
83
```typescript { .api }
84
/**
85
* List video generation jobs
86
* @param params - List parameters for pagination and sorting
87
* @returns Paginated list of video jobs
88
*/
89
function list(params?: VideoListParams): Promise<VideosPage>;
90
91
interface VideoListParams {
92
/** Sort order of results by timestamp */
93
order?: "asc" | "desc";
94
/** Maximum number of items to return */
95
limit?: number;
96
/** Cursor for fetching the next page of results */
97
after?: string;
98
}
99
```
100
101
**Usage Example:**
102
103
```typescript
104
// List recent video jobs
105
for await (const video of client.videos.list({ order: "desc", limit: 20 })) {
106
console.log(`${video.id}: ${video.status} - ${video.prompt?.substring(0, 50)}`);
107
}
108
```
109
110
### Video Deletion
111
112
Delete a video job and its associated assets.
113
114
```typescript { .api }
115
/**
116
* Delete a video job
117
* @param videoID - Unique identifier for the video job
118
* @returns Deletion confirmation response
119
*/
120
function delete(videoID: string): Promise<VideoDeleteResponse>;
121
122
interface VideoDeleteResponse {
123
/** Identifier of the deleted video */
124
id: string;
125
/** Indicates that the video resource was deleted */
126
deleted: boolean;
127
/** The object type that signals the deletion response */
128
object: "video.deleted";
129
}
130
```
131
132
**Usage Example:**
133
134
```typescript
135
const result = await client.videos.delete("video_abc123");
136
console.log(`Video ${result.id} deleted: ${result.deleted}`);
137
```
138
139
### Video Download
140
141
Download the generated video content or associated assets.
142
143
```typescript { .api }
144
/**
145
* Download video content or related assets
146
* @param videoID - Unique identifier for the video job
147
* @param params - Download parameters specifying which variant to retrieve
148
* @returns Response object containing the binary content
149
*/
150
function downloadContent(
151
videoID: string,
152
params?: VideoDownloadContentParams
153
): Promise<Response>;
154
155
interface VideoDownloadContentParams {
156
/** Which downloadable asset to return. Defaults to the MP4 video */
157
variant?: "video" | "thumbnail" | "spritesheet";
158
}
159
```
160
161
**Usage Example:**
162
163
```typescript
164
// Download the generated video
165
const response = await client.videos.downloadContent("video_abc123", {
166
variant: "video",
167
});
168
169
// Save to file (Node.js)
170
const fs = require("fs");
171
const buffer = Buffer.from(await response.arrayBuffer());
172
fs.writeFileSync("output.mp4", buffer);
173
174
// Download thumbnail
175
const thumbnail = await client.videos.downloadContent("video_abc123", {
176
variant: "thumbnail",
177
});
178
```
179
180
### Video Remixing
181
182
Create a new video based on an existing video with a modified prompt.
183
184
```typescript { .api }
185
/**
186
* Create a remix of an existing video with a new prompt
187
* @param videoID - Unique identifier for the source video
188
* @param params - Remix parameters with updated prompt
189
* @returns New video job object for the remix
190
*/
191
function remix(videoID: string, params: VideoRemixParams): Promise<Video>;
192
193
interface VideoRemixParams {
194
/** Updated text prompt that directs the remix generation */
195
prompt: string;
196
}
197
```
198
199
**Usage Example:**
200
201
```typescript
202
// Create a remix with modified conditions
203
const remixedVideo = await client.videos.remix("video_abc123", {
204
prompt:
205
"The same mountain landscape at sunset, but now with dramatic lightning in the sky",
206
});
207
208
console.log(`Remix job created: ${remixedVideo.id}`);
209
console.log(`Remixed from: ${remixedVideo.remixed_from_video_id}`);
210
```
211
212
## Types
213
214
### Video
215
216
```typescript { .api }
217
interface Video {
218
/** Unique identifier for the video job */
219
id: string;
220
/** Unix timestamp (seconds) for when the job was created */
221
created_at: number;
222
/** Unix timestamp (seconds) for when the job completed, if finished */
223
completed_at: number | null;
224
/** Unix timestamp (seconds) for when the downloadable assets expire, if set */
225
expires_at: number | null;
226
/** Current lifecycle status of the video job */
227
status: "queued" | "in_progress" | "completed" | "failed";
228
/** Approximate completion percentage for the generation task */
229
progress: number;
230
/** The prompt that was used to generate the video */
231
prompt: string | null;
232
/** The video generation model that produced the job */
233
model: VideoModel;
234
/** Duration of the generated clip in seconds */
235
seconds: VideoSeconds;
236
/** The resolution of the generated video */
237
size: VideoSize;
238
/** Identifier of the source video if this video is a remix */
239
remixed_from_video_id: string | null;
240
/** Error payload that explains why generation failed, if applicable */
241
error: VideoCreateError | null;
242
/** The object type, which is always 'video' */
243
object: "video";
244
}
245
246
interface VideoCreateError {
247
code: string;
248
message: string;
249
}
250
```
251
252
### Video Models
253
254
```typescript { .api }
255
/** Available video generation models */
256
type VideoModel = "sora-2" | "sora-2-pro";
257
```
258
259
- `sora-2` - Standard Sora model for video generation
260
- `sora-2-pro` - Pro version with enhanced capabilities
261
262
### Video Duration
263
264
```typescript { .api }
265
/** Available video durations in seconds */
266
type VideoSeconds = "4" | "8" | "12";
267
```
268
269
Supported durations: 4, 8, or 12 seconds.
270
271
### Video Resolution
272
273
```typescript { .api }
274
/** Available video resolutions formatted as width x height */
275
type VideoSize = "720x1280" | "1280x720" | "1024x1792" | "1792x1024";
276
```
277
278
- `720x1280` - Vertical/portrait (9:16 aspect ratio)
279
- `1280x720` - Horizontal/landscape (16:9 aspect ratio)
280
- `1024x1792` - Vertical/portrait (wider format)
281
- `1792x1024` - Horizontal/landscape (wider format)
282
283
## Complete Workflow Example
284
285
```typescript
286
import OpenAI from "openai";
287
288
const client = new OpenAI();
289
290
async function generateAndDownloadVideo() {
291
// 1. Create video generation job
292
const video = await client.videos.create({
293
prompt: "A bustling Tokyo street at night with neon lights",
294
model: "sora-2-pro",
295
seconds: "12",
296
size: "1792x1024",
297
});
298
299
console.log(`Video generation started: ${video.id}`);
300
301
// 2. Poll for completion
302
let currentVideo = video;
303
while (
304
currentVideo.status === "queued" ||
305
currentVideo.status === "in_progress"
306
) {
307
await new Promise((resolve) => setTimeout(resolve, 5000)); // Wait 5 seconds
308
currentVideo = await client.videos.retrieve(video.id);
309
console.log(`Progress: ${currentVideo.progress}%`);
310
}
311
312
// 3. Check for success
313
if (currentVideo.status === "completed") {
314
console.log("Video generation completed!");
315
316
// 4. Download the video
317
const response = await client.videos.downloadContent(video.id);
318
const buffer = Buffer.from(await response.arrayBuffer());
319
320
// Save to file
321
const fs = require("fs");
322
fs.writeFileSync(`${video.id}.mp4`, buffer);
323
console.log(`Video saved to ${video.id}.mp4`);
324
325
// 5. Optionally create a remix
326
const remix = await client.videos.remix(video.id, {
327
prompt: "The same Tokyo street at night, but with rain falling",
328
});
329
console.log(`Remix job created: ${remix.id}`);
330
} else if (currentVideo.status === "failed") {
331
console.error("Video generation failed:", currentVideo.error?.message);
332
}
333
}
334
335
generateAndDownloadVideo();
336
```
337
338
## Notes
339
340
- Videos expire after a certain time period (check `expires_at` field)
341
- Generation can take several minutes depending on duration and complexity
342
- The `progress` field provides approximate completion percentage
343
- Failed jobs include error details in the `error` field
344
- Remixed videos inherit properties from the source video unless overridden
345
- Image references in `input_reference` can guide the generation process
346