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

# OpenAI Video generation

***

## Request

<CodeGroup>
  ```bash cURL theme={null} theme={null}
  curl -X POST "https://api.znapai.com/v1/videos" \
    -H "Authorization: Bearer $ZnapAI_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "sora-2",
      "prompt": "A cinematic drone shot flying through a futuristic cyberpunk city at night, volumetric lighting, realistic reflections, neon signs, rain-soaked streets",
      "size": "1280x720",
      "seconds": "4",
      "metadata": {
        "user_id": "test-user",
        "project": "video-api-testing"
      }
    }'
  ```
</CodeGroup>

***

## Parameters

### Required Parameters

<ParamField path="model" type="string" required>
  The video generation model identifier. Supported value: `"sora-2"`.
</ParamField>

<ParamField path="prompt" type="string" required>
  A text description of the video you want to generate.
</ParamField>

### Optional / Strict Parameters

<Warning>
  OpenAI's Sora validation is incredibly strict. Passing incorrect data types
  (like an integer instead of a string) or unsupported resolutions will result
  in a `400 Bad Request`.
</Warning>

<ParamField path="seconds" type="string">
  The duration of the video clip in seconds. **Must be a string.** Supported
  values: `"4"`, `"8"`, `"12"`.
</ParamField>

<ParamField path="size" type="string">
  The output resolution formatted as `widthxheight`. Supported values for the
  standard `sora-2` model: `"720x1280"`, `"1280x720"` (720p only).
</ParamField>

<Note>
  `"1024x1792"` and `"1792x1024"` pass request validation but are rejected at
  generation time on the standard `sora-2` model (`"Resolution ... is not
      supported for model sora-2"`). These higher resolutions are exclusive to
  **Sora 2 Pro** — they are not usable on the standard model regardless of
  proxy configuration.
</Note>

<ParamField path="input_reference" type="string">
  An optional image reference (URL or base64 data) used to guide generation for
  Image-to-Video workflows.
</ParamField>

<ParamField path="metadata" type="object">
  Optional metadata attached to the request for tracking, analytics, user
  identification, or application-specific context. Any valid JSON object is
  supported.
</ParamField>

### Metadata Example

```json theme={null} theme={null}
{
  "metadata": {
    "project": "video-api-testing",
    "user_id": "test-user-id-123",
    "environment": "staging"
  }
}
```

***

## Get Video Status

The `POST /v1/videos` request returns a video job `id`. Use this `id` to poll the status of your generation job.

<CodeGroup>
  ```bash cURL theme={null} theme={null}
  curl https://api.znapai.com/v1/videos/$VIDEO_ID \
    -H "Authorization: Bearer $ZnapAI_API_KEY"
  ```
</CodeGroup>

### 200 Response Example

```json theme={null} theme={null}
{
  "id": "id",
  "completed_at": 0,
  "created_at": 0,
  "error": {
    "code": "code",
    "message": "message"
  },
  "expires_at": 0,
  "model": "string",
  "object": "video",
  "progress": 0,
  "prompt": "prompt",
  "remixed_from_video_id": "remixed_from_video_id",
  "seconds": "seconds",
  "size": "720x1280",
  "status": "queued"
}
```

<Note>
  The `status` field indicates the current state of the video job. Possible values include `"queued"`, `"in_progress"`, and `"completed"`. Poll this endpoint until `status` changes to `"completed"` before downloading the video.
</Note>

***

## Remix Video

Once a video job's status is `"completed"`, you can remix it — apply a targeted change to the existing video (e.g. altering one element of the scene) instead of generating a new video from scratch. The original video's structure, motion, and framing are preserved.

<CodeGroup>
  ```bash cURL theme={null} theme={null}
  curl -X POST "https://api.znapai.com/v1/videos/$VIDEO_ID/remix" \
    -H "Authorization: Bearer $ZnapAI_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "prompt": "Same scene, but shift the color palette to teal, sand, and rust with a warm backlight"
    }'
  ```
</CodeGroup>

### Path Parameters

<ParamField path="video_id" type="string" required>
  The unique identifier of a previously completed video job to remix.
</ParamField>

### Required Parameters

<ParamField path="prompt" type="string" required>
  A text description of the targeted change to apply to the existing video. For best results, limit this to one clearly articulated adjustment — narrow, precise edits retain more fidelity to the source video and reduce the chance of visual defects.
</ParamField>

### 200 Response Example

```json theme={null} theme={null}
{
  "id": "id",
  "completed_at": null,
  "created_at": 0,
  "error": null,
  "expires_at": null,
  "model": "sora-2",
  "object": "video",
  "progress": 0,
  "prompt": "prompt",
  "remixed_from_video_id": "remixed_from_video_id",
  "seconds": "4",
  "size": "720x1280",
  "status": "queued"
}
```

<Note>
  Remix returns a new video job `id` and sets `remixed_from_video_id` to the source video's `id`. Poll `GET /v1/videos/$VIDEO_ID` with the **new** `id` — the same way as [Get Video Status](#get-video-status) — until `status` changes to `"completed"` before downloading.
</Note>

***

## Download Video Content

Once the video job status is `"completed"`, download the generated video bytes or a derived preview asset using this endpoint.

Streams the rendered video content for the specified video job.

### Path Parameters

<ParamField path="video_id" type="string" required>
  The unique identifier of the completed video job.
</ParamField>

<CodeGroup>
  ```bash cURL theme={null} theme={null}
  curl https://api.znapai.com/v1/videos/$VIDEO_ID/content \
    -H "Authorization: Bearer $ZnapAI_API_KEY"
  ```
</CodeGroup>

***

## Common Errors to Avoid

<Note>
  Due to an exception mapping quirk, if you violate any of OpenAI's parameter
  validations (e.g., passing `"duration"` instead of `"seconds"`), the proxy may
  wrap the OpenAI `400 Bad Request` inside a confusing
  `ContentPolicyViolationError`.
</Note>

* **Passing `duration` instead of `seconds`:** OpenAI expects `"seconds"`. It does not recognize `"duration"`.
* **Passing `seconds` as an integer:** You must pass `"seconds": "4"`, not `"seconds": 4`.
* **Passing an unsupported `size`:** Using standard sizes like `"1920x1080"` will fail. You must use the specific crop ratios allowed by OpenAI (e.g., `"1280x720"`).
