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

# Create a Flux 3 video

> Create a Flux 3 video from text, reference images, or first and last frames with a 720p or 1080p size preset.

Create a Flux 3 video from text, reference images, or first and last frames. Store the returned `id` to poll the task and download the completed video.

`POST /v1/videos` uses `multipart/form-data`. Send controls as form fields. For image inputs, use reference image URLs or opening and closing frames.

Keep `input_reference` separate from `first_frame` and `last_frame`.

## Choose an input mode

| Goal                       | Required fields                                           | Optional fields   |
| -------------------------- | --------------------------------------------------------- | ----------------- |
| Text-to-video              | `model=flux-3`, `prompt`                                  | `seconds`, `size` |
| HTTPS image-to-video       | `model=flux-3`, `prompt`, one `input_reference` URL       | `seconds`, `size` |
| Ordered keyframes          | `model=flux-3`, `prompt`, repeated `input_reference` URLs | `seconds`, `size` |
| Uploaded opening frame     | `model=flux-3`, `prompt`, one `first_frame` file          | `seconds`, `size` |
| First-and-last-frame video | `model=flux-3`, `prompt`, `first_frame`, `last_frame`     | `seconds`, `size` |

## Use reference images

The `input_reference` field accepts publicly accessible HTTPS image URLs only. Send it once for a single image, or repeat it in keyframe order for multiple images. Use one URL per field, up to 10 URLs in total.

Describe the motion, camera behavior, and visual details that the generated video should preserve from the reference image.

The request samples at the top of this page show single-image and multiple-image inputs. The following request uses two images in their submitted order:

```bash theme={null}
curl \
  https://api.cometapi.com/v1/videos \
  -H "Authorization: Bearer $COMETAPI_KEY" \
  --form-string 'model=flux-3' \
  --form-string 'prompt=Move smoothly through the supplied reference images in their given order. Preserve recognizable subjects and visual details as the scene changes. Keep the camera movement gentle.' \
  --form-string 'seconds=5' \
  --form-string 'size=1280x720' \
  --form-string 'input_reference=https://apidoc.cometapi.com/images/image/gemini/6100640_569429.png' \
  --form-string 'input_reference=https://apidoc.cometapi.com/images/image/gemini/6100640_569420.png'
```

## Set the first and last frames

Send `first_frame` to set the opening image. To also set the closing image, include `last_frame` and describe the motion between the two frames in `prompt`.

For an opening frame alone, omit `last_frame`. A closing frame requires both `first_frame` and `last_frame`.

Each field accepts one publicly accessible HTTPS URL or one PNG or JPEG file. Send each field once, using either a URL or a file. Keep each file at or below 20 MiB (20 × 1024 × 1024 bytes).

The frame examples at the top of this page show URL inputs and file uploads, with `seconds` and `size` set explicitly.

## Set duration and size

Set `seconds` explicitly to an integer from `5` through `20`.

Set `size` to one of these exact `WxH` preset values:

| Resolution tier | Size        |
| --------------- | ----------- |
| `720p`          | `1280x720`  |
| `1080p`         | `1920x1080` |

The size value selects the output resolution tier. For text-to-video, encoded dimensions can be adjusted for codec alignment. For image-to-video, the reference image can also determine the final framing and aspect ratio.

## Task flow

<Steps>
  <Step title="Create the task">
    Send the multipart form request and store the returned `id`.
  </Step>

  <Step title="Poll the task">
    Call [Retrieve a Flux 3 video](./retrieve) until `status` is `completed` or `failed`.
  </Step>

  <Step title="Download the result">
    When the task is `completed`, call [Download Flux 3 video content](./retrieve-content) to save the MP4 file.
  </Step>
</Steps>


## OpenAPI

````yaml api/openapi/video/flux-3/post-create.openapi.json POST /v1/videos
openapi: 3.1.0
info:
  title: Flux 3 Video Create API
  version: 1.0.0
  description: >-
    Create a Flux 3 video from text, a reference image, or opening and closing
    frames with multipart form data.
servers:
  - url: https://api.cometapi.com
security:
  - bearerAuth: []
paths:
  /v1/videos:
    post:
      summary: Create a Flux 3 video task
      description: >-
        Create a Flux 3 video from text, one reference image URL, or opening and
        closing frames.
      operationId: flux_3_create_video
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/Flux3CreateRequest'
            encoding:
              input_reference:
                contentType: text/plain
                style: form
                explode: true
              first_frame:
                contentType: image/png, image/jpeg, text/plain
              last_frame:
                contentType: image/png, image/jpeg, text/plain
            examples:
              text_to_video:
                summary: Text-to-video
                value:
                  model: flux-3
                  prompt: >-
                    A paper boat glides across a still pond while the camera
                    moves forward.
                  seconds: 5
                  size: 1280x720
              https_image_to_video:
                summary: Image-to-video with an HTTPS image
                value:
                  model: flux-3
                  prompt: >-
                    Animate the reference scene with a slow camera move and
                    natural motion.
                  seconds: 5
                  size: 1280x720
                  input_reference: >-
                    https://apidoc.cometapi.com/images/image/gemini/6100640_569429.png
              first_last_frame_urls:
                summary: First and last frames from URLs
                value:
                  model: flux-3
                  prompt: Move smoothly from the opening to the closing scene.
                  seconds: 5
                  size: 1280x720
                  first_frame: https://your-image-host/first-frame.png
                  last_frame: https://your-image-host/last-frame.png
              first_last_frame_files:
                summary: First and last frames from files
                value:
                  model: flux-3
                  prompt: Move smoothly from the opening to the closing scene.
                  seconds: 5
                  size: 1280x720
                  first_frame: '@/path/to/first-frame.png'
                  last_frame: '@/path/to/last-frame.png'
              opening_frame_file:
                summary: Opening frame from a file
                value:
                  model: flux-3
                  prompt: >-
                    Animate the opening frame with a slow camera move and
                    natural motion.
                  seconds: 5
                  size: 1280x720
                  first_frame: '@/path/to/reference.png'
              input_reference_url_pair:
                summary: Ordered keyframes from image URLs
                value:
                  model: flux-3
                  prompt: >-
                    Move smoothly through the supplied reference images in their
                    given order. Preserve recognizable subjects and visual
                    details as the scene changes. Keep the camera movement
                    gentle.
                  seconds: 5
                  size: 1280x720
                  input_reference:
                    - >-
                      https://apidoc.cometapi.com/images/image/gemini/6100640_569429.png
                    - >-
                      https://apidoc.cometapi.com/images/image/gemini/6100640_569420.png
      responses:
        '200':
          description: >-
            Task created. Store the returned id and poll GET
            /v1/videos/{task_id}.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Flux3VideoTask'
              example:
                id: <task_id>
                task_id: <task_id>
                object: video
                model: flux-3
                status: queued
                progress: 0
                created_at: 1779938152
        '400':
          description: >-
            The request is missing a required field or contains an unsupported
            value.
        '401':
          description: The API key is missing or invalid.
      security:
        - bearerAuth: []
      x-codeSamples:
        - lang: Shell
          label: Text-to-video
          source: |-
            curl \
              https://api.cometapi.com/v1/videos \
              -H "Authorization: Bearer $COMETAPI_KEY" \
              --form-string 'model=flux-3' \
              --form-string 'prompt=A paper boat glides across a still pond while the camera moves forward.' \
              --form-string 'seconds=5' \
              --form-string 'size=1280x720'
        - lang: Python
          label: Text-to-video
          source: |
            import os

            import requests

            fields = [
                ("model", (None, "flux-3")),
                (
                    "prompt",
                    (
                        None,
                        "A paper boat glides across a still pond while the "
                        "camera moves forward.",
                    ),
                ),
                ("seconds", (None, "5")),
                ("size", (None, "1280x720")),
            ]

            response = requests.post(
                "https://api.cometapi.com/v1/videos",
                headers={
                    "Authorization": "Bearer " + os.environ["COMETAPI_KEY"]
                },
                files=fields,
                timeout=120,
            )
            response.raise_for_status()
            print(response.json())
        - lang: JavaScript
          label: Text-to-video
          source: |
            const form = new FormData();
            form.append("model", "flux-3");
            form.append(
              "prompt",
              "A paper boat glides across a still pond while the camera moves forward.",
            );
            form.append("seconds", "5");
            form.append("size", "1280x720");

            const response = await fetch("https://api.cometapi.com/v1/videos", {
              method: "POST",
              headers: { Authorization: `Bearer ${process.env.COMETAPI_KEY}` },
              body: form,
            });

            if (!response.ok) {
              throw new Error(await response.text());
            }

            console.log(await response.json());
        - lang: Shell
          label: HTTPS image-to-video
          source: |-
            curl \
              https://api.cometapi.com/v1/videos \
              -H "Authorization: Bearer $COMETAPI_KEY" \
              --form-string 'model=flux-3' \
              --form-string 'prompt=Animate the reference scene with a slow camera move and natural motion.' \
              --form-string 'seconds=5' \
              --form-string 'size=1280x720' \
              --form-string 'input_reference=https://apidoc.cometapi.com/images/image/gemini/6100640_569429.png'
        - lang: Python
          label: HTTPS image-to-video
          source: |
            import os

            import requests

            fields = [
                ("model", (None, "flux-3")),
                (
                    "prompt",
                    (
                        None,
                        "Animate the reference scene with a slow camera move and "
                        "natural motion.",
                    ),
                ),
                ("seconds", (None, "5")),
                ("size", (None, "1280x720")),
                (
                    "input_reference",
                    (None, "https://apidoc.cometapi.com/images/image/gemini/6100640_569429.png"),
                ),
            ]

            response = requests.post(
                "https://api.cometapi.com/v1/videos",
                headers={
                    "Authorization": "Bearer " + os.environ["COMETAPI_KEY"]
                },
                files=fields,
                timeout=120,
            )
            response.raise_for_status()
            print(response.json())
        - lang: JavaScript
          label: HTTPS image-to-video
          source: >
            const form = new FormData();

            form.append("model", "flux-3");

            form.append(
              "prompt",
              "Animate the reference scene with a slow camera move and natural motion.",
            );

            form.append("seconds", "5");

            form.append("size", "1280x720");

            form.append("input_reference",
            "https://apidoc.cometapi.com/images/image/gemini/6100640_569429.png");


            const response = await fetch("https://api.cometapi.com/v1/videos", {
              method: "POST",
              headers: { Authorization: `Bearer ${process.env.COMETAPI_KEY}` },
              body: form,
            });


            if (!response.ok) {
              throw new Error(await response.text());
            }


            console.log(await response.json());
        - lang: Shell
          label: First and last frames from URLs
          source: |-
            image1=https://your-image-host/first-frame.png
            image2=https://your-image-host/last-frame.png

            curl \
              https://api.cometapi.com/v1/videos \
              -H "Authorization: Bearer $COMETAPI_KEY" \
              --form-string model=flux-3 \
              --form-string 'prompt=Move smoothly from the opening to the closing scene.' \
              --form-string seconds=5 \
              --form-string size=1280x720 \
              --form-string "first_frame=$image1" \
              --form-string "last_frame=$image2"
        - lang: Python
          label: First and last frames from URLs
          source: |
            import os

            import requests

            url1 = "https://your-image-host/first-frame.png"
            url2 = "https://your-image-host/last-frame.png"

            prompt = "Move smoothly from the opening to the closing scene."

            fields = [
                ("model", (None, "flux-3")),
                ("prompt", (None, prompt)),
                ("seconds", (None, "5")),
                ("size", (None, "1280x720")),
                (
                    "first_frame",
                    (None, url1),
                ),
                (
                    "last_frame",
                    (None, url2),
                ),
            ]

            response = requests.post(
                "https://api.cometapi.com/v1/videos",
                headers={"Authorization": "Bearer " + os.environ["COMETAPI_KEY"]},
                files=fields,
                timeout=120,
            )

            response.raise_for_status()
            print(response.json())
        - lang: JavaScript
          label: First and last frames from URLs
          source: >
            const form = new FormData();

            form.append("model", "flux-3");

            form.append("prompt", "Move smoothly from the opening to the closing
            scene.");

            form.append("seconds", "5");

            form.append("size", "1280x720");

            form.append(
              "first_frame",
              "https://your-image-host/first-frame.png",
            );

            form.append(
              "last_frame",
              "https://your-image-host/last-frame.png",
            );


            const response = await fetch("https://api.cometapi.com/v1/videos", {
              method: "POST",
              headers: { Authorization: "Bearer " + process.env.COMETAPI_KEY },
              body: form,
            });


            if (!response.ok) {
              throw new Error(await response.text());
            }


            console.log(await response.json());
        - lang: Shell
          label: First and last frames from files
          source: |-
            curl \
              https://api.cometapi.com/v1/videos \
              -H "Authorization: Bearer $COMETAPI_KEY" \
              --form-string model=flux-3 \
              --form-string 'prompt=Move smoothly from the opening to the closing scene.' \
              --form-string seconds=5 \
              --form-string size=1280x720 \
              --form 'first_frame=@/path/to/first-frame.png;type=image/png' \
              --form 'last_frame=@/path/to/last-frame.png;type=image/png'
        - lang: Python
          label: First and last frames from files
          source: |
            import os
            from contextlib import ExitStack

            import requests

            prompt = (
                "Move smoothly from the opening to the closing scene."
            )

            with ExitStack() as stack:
                image_1 = stack.enter_context(open("/path/to/first-frame.png", "rb"))
                image_2 = stack.enter_context(open("/path/to/last-frame.png", "rb"))
                fields = [
                    ("model", (None, "flux-3")),
                    ("prompt", (None, prompt)),
                    ("seconds", (None, "5")),
                    ("size", (None, "1280x720")),
                    ("first_frame", ("first-frame.png", image_1, "image/png")),
                    ("last_frame", ("last-frame.png", image_2, "image/png")),
                ]

                response = requests.post(
                    "https://api.cometapi.com/v1/videos",
                    headers={"Authorization": "Bearer " + os.environ["COMETAPI_KEY"]},
                    files=fields,
                    timeout=120,
                )

            response.raise_for_status()
            print(response.json())
        - lang: JavaScript
          label: First and last frames from files
          source: >
            import { readFile } from "node:fs/promises";


            const image_1 = await readFile("/path/to/first-frame.png");

            const image_2 = await readFile("/path/to/last-frame.png");


            const form = new FormData();

            form.append("model", "flux-3");

            form.append("prompt", "Move smoothly from the opening to the closing
            scene.");

            form.append("seconds", "5");

            form.append("size", "1280x720");

            form.append(
              "first_frame",
              new Blob([image_1], { type: "image/png" }),
              "first-frame.png",
            );

            form.append(
              "last_frame",
              new Blob([image_2], { type: "image/png" }),
              "last-frame.png",
            );


            const response = await fetch("https://api.cometapi.com/v1/videos", {
              method: "POST",
              headers: { Authorization: "Bearer " + process.env.COMETAPI_KEY },
              body: form,
            });


            if (!response.ok) {
              throw new Error(await response.text());
            }


            console.log(await response.json());
        - lang: Shell
          label: Opening frame from a file
          source: |-
            curl \
              https://api.cometapi.com/v1/videos \
              -H "Authorization: Bearer $COMETAPI_KEY" \
              --form-string 'model=flux-3' \
              --form-string 'prompt=Animate the opening frame with a slow camera move and natural motion.' \
              --form-string 'seconds=5' \
              --form-string 'size=1280x720' \
              --form 'first_frame=@/path/to/reference.png;type=image/png'
        - lang: Python
          label: Opening frame from a file
          source: |
            import os

            import requests

            prompt = (
                "Animate the opening frame with a slow camera move and "
                "natural motion."
            )

            with open("/path/to/reference.png", "rb") as reference:
                response = requests.post(
                    "https://api.cometapi.com/v1/videos",
                    headers={
                        "Authorization": "Bearer "
                        + os.environ["COMETAPI_KEY"]
                    },
                    data={
                        "model": "flux-3",
                        "prompt": prompt,
                        "seconds": "5",
                        "size": "1280x720",
                    },
                    files={
                        "first_frame": (
                            "reference.png",
                            reference,
                            "image/png",
                        )
                    },
                    timeout=120,
                )

            response.raise_for_status()
            print(response.json())
        - lang: JavaScript
          label: Opening frame from a file
          source: |
            import { readFile } from "node:fs/promises";

            const reference = await readFile("/path/to/reference.png");
            const form = new FormData();
            form.append("model", "flux-3");
            form.append(
              "prompt",
              "Animate the opening frame with a slow camera move and natural motion.",
            );
            form.append("seconds", "5");
            form.append("size", "1280x720");
            form.append(
              "first_frame",
              new Blob([reference], { type: "image/png" }),
              "reference.png",
            );

            const response = await fetch("https://api.cometapi.com/v1/videos", {
              method: "POST",
              headers: { Authorization: `Bearer ${process.env.COMETAPI_KEY}` },
              body: form,
            });

            if (!response.ok) {
              throw new Error(await response.text());
            }

            console.log(await response.json());
        - lang: Shell
          label: Ordered keyframes from image URLs
          source: |-
            curl \
              https://api.cometapi.com/v1/videos \
              -H "Authorization: Bearer $COMETAPI_KEY" \
              --form-string 'model=flux-3' \
              --form-string 'prompt=Move smoothly through the supplied reference images in their given order. Preserve recognizable subjects and visual details as the scene changes. Keep the camera movement gentle.' \
              --form-string 'seconds=5' \
              --form-string 'size=1280x720' \
              --form-string 'input_reference=https://apidoc.cometapi.com/images/image/gemini/6100640_569429.png' \
              --form-string 'input_reference=https://apidoc.cometapi.com/images/image/gemini/6100640_569420.png'
        - lang: Python
          label: Ordered keyframes from image URLs
          source: |
            import os

            import requests

            fields = [
                ("model", (None, "flux-3")),
                ("prompt", (None, "Move smoothly through the supplied reference images in their given order. Preserve recognizable subjects and visual details as the scene changes. Keep the camera movement gentle.")),
                ("seconds", (None, "5")),
                ("size", (None, "1280x720")),
                ("input_reference", (None, "https://apidoc.cometapi.com/images/image/gemini/6100640_569429.png")),
                ("input_reference", (None, "https://apidoc.cometapi.com/images/image/gemini/6100640_569420.png")),
            ]

            response = requests.post(
                "https://api.cometapi.com/v1/videos",
                headers={"Authorization": "Bearer " + os.environ["COMETAPI_KEY"]},
                files=fields,
                timeout=120,
            )
            response.raise_for_status()
            print(response.json())
        - lang: JavaScript
          label: Ordered keyframes from image URLs
          source: >
            const form = new FormData();

            form.append("model", "flux-3");

            form.append("prompt", "Move smoothly through the supplied reference
            images in their given order. Preserve recognizable subjects and
            visual details as the scene changes. Keep the camera movement
            gentle.");

            form.append("seconds", "5");

            form.append("size", "1280x720");

            form.append("input_reference",
            "https://apidoc.cometapi.com/images/image/gemini/6100640_569429.png");

            form.append("input_reference",
            "https://apidoc.cometapi.com/images/image/gemini/6100640_569420.png");


            const response = await fetch("https://api.cometapi.com/v1/videos", {
              method: "POST",
              headers: { Authorization: `Bearer ${process.env.COMETAPI_KEY}` },
              body: form,
            });


            if (!response.ok) {
              throw new Error(await response.text());
            }


            console.log(await response.json());
components:
  schemas:
    Flux3CreateRequest:
      type: object
      description: >-
        Flux 3 multipart request. Choose text, input_reference URLs, or
        first_frame and last_frame inputs. Keep reference-image and frame inputs
        separate.
      required:
        - model
        - prompt
      not:
        anyOf:
          - required:
              - input_reference
              - first_frame
          - required:
              - input_reference
              - last_frame
      properties:
        model:
          type: string
          const: flux-3
          default: flux-3
          description: Model ID for this route. Use flux-3.
        prompt:
          type: string
          minLength: 1
          description: >-
            Text that describes the scene, motion, camera behavior, and visual
            details that the video should preserve.
          default: >-
            A paper boat glides across a still pond while the camera moves
            forward.
        seconds:
          type: integer
          minimum: 5
          maximum: 20
          description: >-
            Requested clip duration in whole seconds. Set seconds explicitly to
            an integer from 5 through 20.
        size:
          type: string
          enum:
            - 1280x720
            - 1920x1080
          default: 1280x720
          description: >-
            Resolution preset in exact WxH form. Use 1280x720 for the 720p tier
            or 1920x1080 for the 1080p tier. Encoded dimensions can be
            codec-aligned; image-to-video framing can follow the reference
            image.
        input_reference:
          description: >-
            Reference image URLs. Send one publicly accessible HTTPS image URL
            per input_reference field. For multiple images, repeat the field in
            keyframe order, up to 10 URLs. This field accepts URLs only. Keep it
            separate from first_frame and last_frame.
          anyOf:
            - type: string
              format: uri
              pattern: ^https://
            - type: array
              minItems: 1
              maxItems: 10
              items:
                type: string
                format: uri
                pattern: ^https://
        first_frame:
          description: >-
            Opening-frame image as one publicly accessible HTTPS URL or one PNG
            or JPEG file. Keep each file at or below 20 MiB (20 × 1024 × 1024
            bytes). Send the field once, using either a URL or a file. Pair with
            last_frame to set both boundaries. Keep frame inputs separate from
            input_reference.
          anyOf:
            - type: string
              format: uri
              pattern: ^https://
            - type: string
              format: binary
        last_frame:
          description: >-
            Closing-frame image as one publicly accessible HTTPS URL or one PNG
            or JPEG file. Keep each file at or below 20 MiB (20 × 1024 × 1024
            bytes). Send the field once, using either a URL or a file. To
            specify the closing image through this endpoint, send last_frame
            together with first_frame. Keep frame inputs separate from
            input_reference.
          anyOf:
            - type: string
              format: uri
              pattern: ^https://
            - type: string
              format: binary
      additionalProperties: false
      dependentRequired:
        last_frame:
          - first_frame
    Flux3VideoTask:
      type: object
      required:
        - id
        - object
        - model
        - status
        - progress
        - created_at
      properties:
        id:
          type: string
          description: Task ID. Use this value as task_id in retrieve and content requests.
          example: <task_id>
        task_id:
          type: string
          description: >-
            Compatibility alias for id. This field can be omitted from retrieve
            responses.
          example: <task_id>
        object:
          type: string
          const: video
          description: Object type for the asynchronous video task.
        model:
          type: string
          const: flux-3
          description: Model ID that the task uses.
        status:
          type: string
          enum:
            - queued
            - in_progress
            - completed
            - failed
          description: Task lifecycle status. Poll until the value is completed or failed.
        progress:
          type: integer
          minimum: 0
          maximum: 100
          description: Task progress as a coarse percentage.
        created_at:
          type: integer
          format: int64
          description: Task creation time as a Unix timestamp in seconds.
        completed_at:
          type: integer
          format: int64
          description: >-
            Task completion time as a Unix timestamp in seconds when the task
            provides one.
        expires_at:
          type: integer
          format: int64
          description: >-
            Result expiration time as a Unix timestamp in seconds when the task
            provides one.
        video_url:
          type: string
          format: uri
          description: Video delivery URL. This field appears on completed tasks.
          example: https://media.example.com/flux-3-result.mp4
        error:
          type: object
          description: Failure details. This field appears when the task fails.
          properties:
            message:
              type: string
              description: Human-readable failure description.
            code:
              type: string
              description: Failure code when the task provides one.
          additionalProperties: true
      additionalProperties: true
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: Bearer authentication. Use your CometAPI API key.

````