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

# Kling O3 Pro - Reference to Video

> Pro reference-driven cinematic video

<CardGroup cols={1}>
  <Card title="Try Kling O3 Pro - Reference to Video in the Workbench" icon="flask" href="https://www.oxen.ai/ai/workbench?model=kling-video-o3-pro-reference-to-video">
    Run this model interactively, tune parameters, and compare outputs.
  </Card>
</CardGroup>

**Model ID:** `kling-video-o3-pro-reference-to-video`

Part of the Kling 3.0/o3 family exclusively available on fal.ai, this reference-to-video model transforms static reference images into dynamic video sequences. It excels at preserving image details like identity, layout, and text while adding realistic motion, camera movements, and scene progression based on cinematic prompts. Supports multi-shot generation, explicit motion instructions, flexible durations up to 15 seconds, and native audio when specified. Optimized for advertising, branded content, and realistic scene extensions with smooth transitions and narrative continuity.

## Example request

<Tip>
  Use the [Workbench](https://www.oxen.ai/ai/workbench?model=kling-video-o3-pro-reference-to-video) as a request builder: configure parameters for this model in the UI, then open the **API** tab to copy the exact cURL or Python call.
</Tip>

<Tabs>
  <Tab title="Sync">
    This blocks until the video is ready (typically 5-15 minutes). Prefer **Async** or **Async with SSE** for anything beyond quick experimentation.

    See the [video generation reference](/inference-api/reference/video_generation) for more details.

    <Tabs>
      <Tab title="Minimal">
        <CodeGroup>
          ```bash cURL theme={null}
          curl -X POST https://hub.oxen.ai/api/ai/videos/generate \
            -H "Content-Type: application/json" \
            -H "Authorization: Bearer $OXEN_API_KEY" \
            -d '{
            "model": "kling-video-o3-pro-reference-to-video"
          }'
          ```

          ```python Python theme={null}
          import os
          import requests

          response = requests.post(
              "https://hub.oxen.ai/api/ai/videos/generate",
              headers={
                  "Content-Type": "application/json",
                  "Authorization": f"Bearer {os.environ['OXEN_API_KEY']}",
              },
              json={
                  "model": "kling-video-o3-pro-reference-to-video"
              },
          )
          response.raise_for_status()
          print(response.json())
          ```
        </CodeGroup>
      </Tab>

      <Tab title="Basic parameters">
        <CodeGroup>
          ```bash cURL theme={null}
          curl -X POST https://hub.oxen.ai/api/ai/videos/generate \
            -H "Content-Type: application/json" \
            -H "Authorization: Bearer $OXEN_API_KEY" \
            -d '{
            "model": "kling-video-o3-pro-reference-to-video",
            "start_image_url": "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png",
            "tail_image_url": "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png",
            "input_image": [
              "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png"
            ]
          }'
          ```

          ```python Python theme={null}
          import os
          import requests

          response = requests.post(
              "https://hub.oxen.ai/api/ai/videos/generate",
              headers={
                  "Content-Type": "application/json",
                  "Authorization": f"Bearer {os.environ['OXEN_API_KEY']}",
              },
              json={
                  "model": "kling-video-o3-pro-reference-to-video",
                  "start_image_url": "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png",
                  "tail_image_url": "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png",
                  "input_image": [
                      "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png"
                  ]
              },
          )
          response.raise_for_status()
          print(response.json())
          ```
        </CodeGroup>
      </Tab>

      <Tab title="All parameters">
        <CodeGroup>
          ```bash cURL theme={null}
          curl -X POST https://hub.oxen.ai/api/ai/videos/generate \
            -H "Content-Type: application/json" \
            -H "Authorization: Bearer $OXEN_API_KEY" \
            -d '{
            "model": "kling-video-o3-pro-reference-to-video",
            "start_image_url": "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png",
            "tail_image_url": "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png",
            "input_image": [
              "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png"
            ],
            "aspect_ratio": "16:9",
            "generate_audio": false
          }'
          ```

          ```python Python theme={null}
          import os
          import requests

          response = requests.post(
              "https://hub.oxen.ai/api/ai/videos/generate",
              headers={
                  "Content-Type": "application/json",
                  "Authorization": f"Bearer {os.environ['OXEN_API_KEY']}",
              },
              json={
                  "model": "kling-video-o3-pro-reference-to-video",
                  "start_image_url": "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png",
                  "tail_image_url": "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png",
                  "input_image": [
                      "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png"
                  ],
                  "aspect_ratio": "16:9",
                  "generate_audio": false
              },
          )
          response.raise_for_status()
          print(response.json())
          ```
        </CodeGroup>
      </Tab>
    </Tabs>
  </Tab>

  <Tab title="Async">
    See the [async queue reference](/inference-api/reference/async_queue) for more details.

    <Tabs>
      <Tab title="Minimal">
        <CodeGroup>
          ```bash cURL theme={null}
          # Enqueue, capture the generation id.
          GEN_ID=$(curl -s -X POST https://hub.oxen.ai/api/ai/queue \
            -H "Content-Type: application/json" \
            -H "Authorization: Bearer $OXEN_API_KEY" \
            -d '{
            "model": "kling-video-o3-pro-reference-to-video"
          }' | jq -r '.generations[0].generation_id')

          # Poll until the generation reaches a terminal status.
          while true; do
            STATUS=$(curl -s -H "Authorization: Bearer $OXEN_API_KEY" \
              "https://hub.oxen.ai/api/ai/queue/$GEN_ID" | jq -r '.status')
            echo "Status: $STATUS"
            case $STATUS in succeeded|failed|cancelled) break;; esac
            sleep 5
          done

          # Print the result.
          curl -s -H "Authorization: Bearer $OXEN_API_KEY" \
            "https://hub.oxen.ai/api/ai/queue/$GEN_ID" | jq .
          ```

          ```python Python theme={null}
          import os
          import time
          import requests

          HEADERS = {
              "Content-Type": "application/json",
              "Authorization": f"Bearer {os.environ['OXEN_API_KEY']}",
          }

          enqueue = requests.post(
              "https://hub.oxen.ai/api/ai/queue",
              headers=HEADERS,
              json={
                  "model": "kling-video-o3-pro-reference-to-video"
              },
          )
          enqueue.raise_for_status()
          generation_id = enqueue.json()["generations"][0]["generation_id"]

          while True:
              data = requests.get(
                  f"https://hub.oxen.ai/api/ai/queue/{generation_id}",
                  headers=HEADERS,
              ).json()
              if data["status"] in {"succeeded", "failed", "cancelled"}:
                  break
              time.sleep(5)

          if data["status"] == "succeeded":
              print(f"Result: {data['result_url']}")
          else:
              print(f"Generation {data['status']}: {data.get('error_message')}")
          ```
        </CodeGroup>
      </Tab>

      <Tab title="Basic parameters">
        <CodeGroup>
          ```bash cURL theme={null}
          # Enqueue, capture the generation id.
          GEN_ID=$(curl -s -X POST https://hub.oxen.ai/api/ai/queue \
            -H "Content-Type: application/json" \
            -H "Authorization: Bearer $OXEN_API_KEY" \
            -d '{
            "model": "kling-video-o3-pro-reference-to-video",
            "start_image_url": "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png",
            "tail_image_url": "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png",
            "input_image": [
              "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png"
            ]
          }' | jq -r '.generations[0].generation_id')

          # Poll until the generation reaches a terminal status.
          while true; do
            STATUS=$(curl -s -H "Authorization: Bearer $OXEN_API_KEY" \
              "https://hub.oxen.ai/api/ai/queue/$GEN_ID" | jq -r '.status')
            echo "Status: $STATUS"
            case $STATUS in succeeded|failed|cancelled) break;; esac
            sleep 5
          done

          # Print the result.
          curl -s -H "Authorization: Bearer $OXEN_API_KEY" \
            "https://hub.oxen.ai/api/ai/queue/$GEN_ID" | jq .
          ```

          ```python Python theme={null}
          import os
          import time
          import requests

          HEADERS = {
              "Content-Type": "application/json",
              "Authorization": f"Bearer {os.environ['OXEN_API_KEY']}",
          }

          enqueue = requests.post(
              "https://hub.oxen.ai/api/ai/queue",
              headers=HEADERS,
              json={
                  "model": "kling-video-o3-pro-reference-to-video",
                  "start_image_url": "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png",
                  "tail_image_url": "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png",
                  "input_image": [
                      "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png"
                  ]
              },
          )
          enqueue.raise_for_status()
          generation_id = enqueue.json()["generations"][0]["generation_id"]

          while True:
              data = requests.get(
                  f"https://hub.oxen.ai/api/ai/queue/{generation_id}",
                  headers=HEADERS,
              ).json()
              if data["status"] in {"succeeded", "failed", "cancelled"}:
                  break
              time.sleep(5)

          if data["status"] == "succeeded":
              print(f"Result: {data['result_url']}")
          else:
              print(f"Generation {data['status']}: {data.get('error_message')}")
          ```
        </CodeGroup>
      </Tab>

      <Tab title="All parameters">
        <CodeGroup>
          ```bash cURL theme={null}
          # Enqueue, capture the generation id.
          GEN_ID=$(curl -s -X POST https://hub.oxen.ai/api/ai/queue \
            -H "Content-Type: application/json" \
            -H "Authorization: Bearer $OXEN_API_KEY" \
            -d '{
            "model": "kling-video-o3-pro-reference-to-video",
            "start_image_url": "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png",
            "tail_image_url": "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png",
            "input_image": [
              "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png"
            ],
            "aspect_ratio": "16:9",
            "generate_audio": false
          }' | jq -r '.generations[0].generation_id')

          # Poll until the generation reaches a terminal status.
          while true; do
            STATUS=$(curl -s -H "Authorization: Bearer $OXEN_API_KEY" \
              "https://hub.oxen.ai/api/ai/queue/$GEN_ID" | jq -r '.status')
            echo "Status: $STATUS"
            case $STATUS in succeeded|failed|cancelled) break;; esac
            sleep 5
          done

          # Print the result.
          curl -s -H "Authorization: Bearer $OXEN_API_KEY" \
            "https://hub.oxen.ai/api/ai/queue/$GEN_ID" | jq .
          ```

          ```python Python theme={null}
          import os
          import time
          import requests

          HEADERS = {
              "Content-Type": "application/json",
              "Authorization": f"Bearer {os.environ['OXEN_API_KEY']}",
          }

          enqueue = requests.post(
              "https://hub.oxen.ai/api/ai/queue",
              headers=HEADERS,
              json={
                  "model": "kling-video-o3-pro-reference-to-video",
                  "start_image_url": "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png",
                  "tail_image_url": "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png",
                  "input_image": [
                      "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png"
                  ],
                  "aspect_ratio": "16:9",
                  "generate_audio": false
              },
          )
          enqueue.raise_for_status()
          generation_id = enqueue.json()["generations"][0]["generation_id"]

          while True:
              data = requests.get(
                  f"https://hub.oxen.ai/api/ai/queue/{generation_id}",
                  headers=HEADERS,
              ).json()
              if data["status"] in {"succeeded", "failed", "cancelled"}:
                  break
              time.sleep(5)

          if data["status"] == "succeeded":
              print(f"Result: {data['result_url']}")
          else:
              print(f"Generation {data['status']}: {data.get('error_message')}")
          ```
        </CodeGroup>
      </Tab>
    </Tabs>
  </Tab>

  <Tab title="Async with SSE">
    See the [async queue reference](/inference-api/reference/async_queue) for more details.

    <Tabs>
      <Tab title="Minimal">
        <CodeGroup>
          ```bash cURL theme={null}
          # Enqueue, capture the generation id.
          GEN_ID=$(curl -s -X POST https://hub.oxen.ai/api/ai/queue \
            -H "Content-Type: application/json" \
            -H "Authorization: Bearer $OXEN_API_KEY" \
            -d '{
            "model": "kling-video-o3-pro-reference-to-video"
          }' | jq -r '.generations[0].generation_id')

          # Stream the SSE channel, grab the data line that follows a
          # media_generation_completed event for our id, and pretty-print it.
          curl -sN -H "Authorization: Bearer $OXEN_API_KEY" https://hub.oxen.ai/api/events \
            | awk -v id="$GEN_ID" '
              /^event: media_generation_completed$/ { expect=1; next }
              /^data: / && expect {
                payload = substr($0, 7)
                if (index(payload, "\"generation_id\":\"" id "\"")) { print payload; exit }
                expect = 0
              }
            ' | jq .
          ```

          ```python Python theme={null}
          import json
          import os
          import requests

          API_KEY = os.environ["OXEN_API_KEY"]
          AUTH = {"Authorization": f"Bearer {API_KEY}"}

          enqueue = requests.post(
              "https://hub.oxen.ai/api/ai/queue",
              headers={**AUTH, "Content-Type": "application/json"},
              json={
                  "model": "kling-video-o3-pro-reference-to-video"
              },
          )
          enqueue.raise_for_status()
          generation_id = enqueue.json()["generations"][0]["generation_id"]

          with requests.get(
              "https://hub.oxen.ai/api/events",
              headers=AUTH,
              stream=True,
          ) as stream:
              event_name = None
              for line in stream.iter_lines(decode_unicode=True):
                  if line.startswith("event: "):
                      event_name = line.removeprefix("event: ")
                  elif line.startswith("data: ") and event_name == "media_generation_completed":
                      payload = json.loads(line.removeprefix("data: "))
                      if payload.get("generation_id") == generation_id:
                          print(payload)
                          break
          ```
        </CodeGroup>
      </Tab>

      <Tab title="Basic parameters">
        <CodeGroup>
          ```bash cURL theme={null}
          # Enqueue, capture the generation id.
          GEN_ID=$(curl -s -X POST https://hub.oxen.ai/api/ai/queue \
            -H "Content-Type: application/json" \
            -H "Authorization: Bearer $OXEN_API_KEY" \
            -d '{
            "model": "kling-video-o3-pro-reference-to-video",
            "start_image_url": "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png",
            "tail_image_url": "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png",
            "input_image": [
              "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png"
            ]
          }' | jq -r '.generations[0].generation_id')

          # Stream the SSE channel, grab the data line that follows a
          # media_generation_completed event for our id, and pretty-print it.
          curl -sN -H "Authorization: Bearer $OXEN_API_KEY" https://hub.oxen.ai/api/events \
            | awk -v id="$GEN_ID" '
              /^event: media_generation_completed$/ { expect=1; next }
              /^data: / && expect {
                payload = substr($0, 7)
                if (index(payload, "\"generation_id\":\"" id "\"")) { print payload; exit }
                expect = 0
              }
            ' | jq .
          ```

          ```python Python theme={null}
          import json
          import os
          import requests

          API_KEY = os.environ["OXEN_API_KEY"]
          AUTH = {"Authorization": f"Bearer {API_KEY}"}

          enqueue = requests.post(
              "https://hub.oxen.ai/api/ai/queue",
              headers={**AUTH, "Content-Type": "application/json"},
              json={
                  "model": "kling-video-o3-pro-reference-to-video",
                  "start_image_url": "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png",
                  "tail_image_url": "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png",
                  "input_image": [
                      "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png"
                  ]
              },
          )
          enqueue.raise_for_status()
          generation_id = enqueue.json()["generations"][0]["generation_id"]

          with requests.get(
              "https://hub.oxen.ai/api/events",
              headers=AUTH,
              stream=True,
          ) as stream:
              event_name = None
              for line in stream.iter_lines(decode_unicode=True):
                  if line.startswith("event: "):
                      event_name = line.removeprefix("event: ")
                  elif line.startswith("data: ") and event_name == "media_generation_completed":
                      payload = json.loads(line.removeprefix("data: "))
                      if payload.get("generation_id") == generation_id:
                          print(payload)
                          break
          ```
        </CodeGroup>
      </Tab>

      <Tab title="All parameters">
        <CodeGroup>
          ```bash cURL theme={null}
          # Enqueue, capture the generation id.
          GEN_ID=$(curl -s -X POST https://hub.oxen.ai/api/ai/queue \
            -H "Content-Type: application/json" \
            -H "Authorization: Bearer $OXEN_API_KEY" \
            -d '{
            "model": "kling-video-o3-pro-reference-to-video",
            "start_image_url": "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png",
            "tail_image_url": "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png",
            "input_image": [
              "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png"
            ],
            "aspect_ratio": "16:9",
            "generate_audio": false
          }' | jq -r '.generations[0].generation_id')

          # Stream the SSE channel, grab the data line that follows a
          # media_generation_completed event for our id, and pretty-print it.
          curl -sN -H "Authorization: Bearer $OXEN_API_KEY" https://hub.oxen.ai/api/events \
            | awk -v id="$GEN_ID" '
              /^event: media_generation_completed$/ { expect=1; next }
              /^data: / && expect {
                payload = substr($0, 7)
                if (index(payload, "\"generation_id\":\"" id "\"")) { print payload; exit }
                expect = 0
              }
            ' | jq .
          ```

          ```python Python theme={null}
          import json
          import os
          import requests

          API_KEY = os.environ["OXEN_API_KEY"]
          AUTH = {"Authorization": f"Bearer {API_KEY}"}

          enqueue = requests.post(
              "https://hub.oxen.ai/api/ai/queue",
              headers={**AUTH, "Content-Type": "application/json"},
              json={
                  "model": "kling-video-o3-pro-reference-to-video",
                  "start_image_url": "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png",
                  "tail_image_url": "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png",
                  "input_image": [
                      "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png"
                  ],
                  "aspect_ratio": "16:9",
                  "generate_audio": false
              },
          )
          enqueue.raise_for_status()
          generation_id = enqueue.json()["generations"][0]["generation_id"]

          with requests.get(
              "https://hub.oxen.ai/api/events",
              headers=AUTH,
              stream=True,
          ) as stream:
              event_name = None
              for line in stream.iter_lines(decode_unicode=True):
                  if line.startswith("event: "):
                      event_name = line.removeprefix("event: ")
                  elif line.startswith("data: ") and event_name == "media_generation_completed":
                      payload = json.loads(line.removeprefix("data: "))
                      if payload.get("generation_id") == generation_id:
                          print(payload)
                          break
          ```
        </CodeGroup>
      </Tab>
    </Tabs>
  </Tab>
</Tabs>

## Fetch model details

The [models endpoint](/inference-api/reference/models/overview) returns the full model object, including its `json_request_schema`.

```bash theme={null}
curl -H "Authorization: Bearer $OXEN_API_KEY" https://hub.oxen.ai/api/ai/models/kling-video-o3-pro-reference-to-video
```

## Request parameters

### Optional parameters

| Field             | Type            | Default  | Description                                                                                                                                                       |
| ----------------- | --------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `start_image_url` | `string`        | —        | The first frame of the video. The model will try to extend the contents of this frame. Format: uri.                                                               |
| `tail_image_url`  | `string`        | —        | The last frame of the video. Requires start frame to be configured. The model will try to fill in between the frames. Format: uri.                                |
| `input_image`     | `array<string>` | —        | Reference images for style/appearance. Use @Image1, @Image2, etc. in the prompt to refer to them. Maximum 4 total (elements + reference images) when using video. |
| `elements`        | `array<object>` | —        | Optional element references. Use @Element1, @Element2, etc. in the prompt to refer to them.                                                                       |
| `negative_prompt` | `string`        | —        | Text describing what to avoid in the generated video.                                                                                                             |
| `aspect_ratio`    | `string`        | `"16:9"` | Video aspect ratio One of: 9:16, 1:1, 16:9.                                                                                                                       |
| `generate_audio`  | `boolean`       | `false`  | Whether to generate native audio for the video. Supports Chinese and English voice output.                                                                        |
