> ## Documentation Index
> Fetch the complete documentation index at: https://docs.openp.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Video generation (Sora)

> POST /v1/videos — text-to-video

Generate video with Sora. It uses an **asynchronous task** flow: submit to get a task ID, poll until done, then download the video.

## Submit a task

```bash theme={null}
curl https://openp.ai/v1/videos \
  -H "Authorization: Bearer $OPENPAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "sora-2",
    "prompt": "A red panda surfing on a giant wave at sunset, cinematic, 4K",
    "seconds": 8,
    "size": "1280x720"
  }'
```

### Parameters

| Field             | Type    | Required | Description                               |
| ----------------- | ------- | :------: | ----------------------------------------- |
| `model`           | string  |     ✅    | `sora-2` / `sora-2-pro`, etc.             |
| `prompt`          | string  |     ✅    | Video description                         |
| `seconds`         | integer |          | Duration (seconds), typically 5-20        |
| `size`            | string  |          | Resolution, e.g. `1280x720` / `1920x1080` |
| `aspect_ratio`    | string  |          | `16:9` / `9:16` / `1:1`                   |
| `n`               | integer |          | Number to generate (partially supported)  |
| `input_reference` | object  |          | An input reference image or video         |

## Response (task created)

```json theme={null}
{
  "id": "video_01...",
  "object": "video.task",
  "status": "queued",
  "created_at": 1715750400,
  "model": "sora-2"
}
```

## Query task status

```bash theme={null}
curl https://openp.ai/v1/videos/video_01... \
  -H "Authorization: Bearer $OPENPAI_API_KEY"
```

```json theme={null}
{
  "id": "video_01...",
  "status": "completed",
  "video_url": "https://...mp4",
  "thumbnail_url": "https://...jpg",
  "duration": 8,
  "created_at": 1715750400,
  "completed_at": 1715750460
}
```

`status` possible values: `queued` / `processing` / `completed` / `failed`.

## Polling guidance

* Start polling after an initial delay of 5-10 seconds.
* Poll every 10-30 seconds.
* It usually completes in 1-5 minutes.
* On failure, the `failure_reason` field explains why.

## Billing

A fixed charge per **seconds generated + resolution**.
System-side failed tasks are not billed; tasks rejected by the upstream are billed by the compute already consumed.
