> ## 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.

# FLUX 3 Video

> Text, keyframe and video-continuation generation

<CardGroup cols={1}>
  <Card title="Try FLUX 3 Video in the Workbench" icon="flask" href="https://www.oxen.ai/ai/workbench?model=flux-3-video">
    Run this model interactively, tune parameters, and compare outputs.
  </Card>
</CardGroup>

**Model ID:** `flux-3-video`

FLUX 3 Video generates video from a text prompt, from keyframes, or by continuing an existing clip, served directly by Black Forest Labs. Clips run 5 to 20 seconds at 720p or 1080p, with synchronized audio generated by default.

Supply keyframes to animate stills, or a source clip to continue it; with neither, it generates from the prompt alone. Draft mode trades quality for a lower per-second rate and is useful for iterating before a full generation.

## Example request

<Tip>
  Use the [Workbench](https://www.oxen.ai/ai/workbench?model=flux-3-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": "flux-3-video",
            "prompt": "<prompt>"
          }'
          ```

          ```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": "flux-3-video",
                  "prompt": "<prompt>"
              },
          )
          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": "flux-3-video",
            "prompt": "<prompt>",
            "input_images": [
              "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png"
            ],
            "input_video": "https://hub.oxen.ai/api/repos/ox/Oxen-AI-Assets/file/main/images/winter_summer_ox.mp4"
          }'
          ```

          ```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": "flux-3-video",
                  "prompt": "<prompt>",
                  "input_images": [
                      "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png"
                  ],
                  "input_video": "https://hub.oxen.ai/api/repos/ox/Oxen-AI-Assets/file/main/images/winter_summer_ox.mp4"
              },
          )
          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": "flux-3-video",
            "prompt": "<prompt>",
            "input_images": [
              "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png"
            ],
            "input_video": "https://hub.oxen.ai/api/repos/ox/Oxen-AI-Assets/file/main/images/winter_summer_ox.mp4",
            "resolution": "720p",
            "aspect_ratio": "auto",
            "duration": 5,
            "generate_audio": true,
            "draft": false,
            "safety_tolerance": 2
          }'
          ```

          ```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": "flux-3-video",
                  "prompt": "<prompt>",
                  "input_images": [
                      "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png"
                  ],
                  "input_video": "https://hub.oxen.ai/api/repos/ox/Oxen-AI-Assets/file/main/images/winter_summer_ox.mp4",
                  "resolution": "720p",
                  "aspect_ratio": "auto",
                  "duration": 5,
                  "generate_audio": true,
                  "draft": false,
                  "safety_tolerance": 2
              },
          )
          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": "flux-3-video",
            "prompt": "<prompt>"
          }' | 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": "flux-3-video",
                  "prompt": "<prompt>"
              },
          )
          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": "flux-3-video",
            "prompt": "<prompt>",
            "input_images": [
              "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png"
            ],
            "input_video": "https://hub.oxen.ai/api/repos/ox/Oxen-AI-Assets/file/main/images/winter_summer_ox.mp4"
          }' | 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": "flux-3-video",
                  "prompt": "<prompt>",
                  "input_images": [
                      "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png"
                  ],
                  "input_video": "https://hub.oxen.ai/api/repos/ox/Oxen-AI-Assets/file/main/images/winter_summer_ox.mp4"
              },
          )
          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": "flux-3-video",
            "prompt": "<prompt>",
            "input_images": [
              "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png"
            ],
            "input_video": "https://hub.oxen.ai/api/repos/ox/Oxen-AI-Assets/file/main/images/winter_summer_ox.mp4",
            "resolution": "720p",
            "aspect_ratio": "auto",
            "duration": 5,
            "generate_audio": true,
            "draft": false,
            "safety_tolerance": 2
          }' | 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": "flux-3-video",
                  "prompt": "<prompt>",
                  "input_images": [
                      "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png"
                  ],
                  "input_video": "https://hub.oxen.ai/api/repos/ox/Oxen-AI-Assets/file/main/images/winter_summer_ox.mp4",
                  "resolution": "720p",
                  "aspect_ratio": "auto",
                  "duration": 5,
                  "generate_audio": true,
                  "draft": false,
                  "safety_tolerance": 2
              },
          )
          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": "flux-3-video",
            "prompt": "<prompt>"
          }' | 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": "flux-3-video",
                  "prompt": "<prompt>"
              },
          )
          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": "flux-3-video",
            "prompt": "<prompt>",
            "input_images": [
              "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png"
            ],
            "input_video": "https://hub.oxen.ai/api/repos/ox/Oxen-AI-Assets/file/main/images/winter_summer_ox.mp4"
          }' | 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": "flux-3-video",
                  "prompt": "<prompt>",
                  "input_images": [
                      "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png"
                  ],
                  "input_video": "https://hub.oxen.ai/api/repos/ox/Oxen-AI-Assets/file/main/images/winter_summer_ox.mp4"
              },
          )
          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": "flux-3-video",
            "prompt": "<prompt>",
            "input_images": [
              "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png"
            ],
            "input_video": "https://hub.oxen.ai/api/repos/ox/Oxen-AI-Assets/file/main/images/winter_summer_ox.mp4",
            "resolution": "720p",
            "aspect_ratio": "auto",
            "duration": 5,
            "generate_audio": true,
            "draft": false,
            "safety_tolerance": 2
          }' | 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": "flux-3-video",
                  "prompt": "<prompt>",
                  "input_images": [
                      "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png"
                  ],
                  "input_video": "https://hub.oxen.ai/api/repos/ox/Oxen-AI-Assets/file/main/images/winter_summer_ox.mp4",
                  "resolution": "720p",
                  "aspect_ratio": "auto",
                  "duration": 5,
                  "generate_audio": true,
                  "draft": false,
                  "safety_tolerance": 2
              },
          )
          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/flux-3-video
```

## Request parameters

### Required parameters

| Field    | Type     | Default | Description                            |
| -------- | -------- | ------- | -------------------------------------- |
| `prompt` | `string` | —       | Free-form prompt describing the video. |

### Optional parameters

| Field              | Type            | Default  | Description                                                                                                                                                                                                                                                                                                                                                                    |
| ------------------ | --------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `input_images`     | `array<string>` | —        | Images that become frames of the generated video, 1 to 10 in order: one image starts the video, two start and end it, and beyond that the first starts it, the last ends it, and the rest fall evenly in between. They are frames, not references, so the prompt cannot cite them. Leave empty to generate from the prompt alone. Cannot be combined with Continue From Video. |
| `input_video`      | `string`        | —        | Clip to extend; the generated video carries on from its final frames. MP4. Cannot be combined with Keyframes. Billed at a higher per-second rate than generating from a prompt or keyframes. Format: uri.                                                                                                                                                                      |
| `resolution`       | `string`        | `"720p"` | Output resolution. 1080p costs more per second. One of: 720p, 1080p.                                                                                                                                                                                                                                                                                                           |
| `aspect_ratio`     | `string`        | `"auto"` | Aspect ratio of the generated video. Auto lets the model choose. One of: auto, 21:9, 2:1, 16:9, 4:3, 1:1, 3:4, 9:16.                                                                                                                                                                                                                                                           |
| `duration`         | `integer`       | `5`      | Duration in seconds. One of: 5, 6, 7, 8, 9, 10, 12, 15, 18, 20.                                                                                                                                                                                                                                                                                                                |
| `generate_audio`   | `boolean`       | `true`   | Generate synchronized audio for the video.                                                                                                                                                                                                                                                                                                                                     |
| `draft`            | `boolean`       | `false`  | Draft mode: rapid, cost-effective exploration at a lower per-second rate. HD only.                                                                                                                                                                                                                                                                                             |
| `safety_tolerance` | `integer`       | `2`      | Safety filter strictness, 0 is strictest. One of: 0, 1, 2, 3, 4.                                                                                                                                                                                                                                                                                                               |
