{
  "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",
        "operationId": "flux_3_create_video",
        "description": "Create a Flux 3 video from text, one reference image URL, or opening and closing frames.",
        "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 \\\n  https://api.cometapi.com/v1/videos \\\n  -H \"Authorization: Bearer $COMETAPI_KEY\" \\\n  --form-string 'model=flux-3' \\\n  --form-string 'prompt=A paper boat glides across a still pond while the camera moves forward.' \\\n  --form-string 'seconds=5' \\\n  --form-string 'size=1280x720'"
          },
          {
            "lang": "Python",
            "label": "Text-to-video",
            "source": "import os\n\nimport requests\n\nfields = [\n    (\"model\", (None, \"flux-3\")),\n    (\n        \"prompt\",\n        (\n            None,\n            \"A paper boat glides across a still pond while the \"\n            \"camera moves forward.\",\n        ),\n    ),\n    (\"seconds\", (None, \"5\")),\n    (\"size\", (None, \"1280x720\")),\n]\n\nresponse = requests.post(\n    \"https://api.cometapi.com/v1/videos\",\n    headers={\n        \"Authorization\": \"Bearer \" + os.environ[\"COMETAPI_KEY\"]\n    },\n    files=fields,\n    timeout=120,\n)\nresponse.raise_for_status()\nprint(response.json())\n"
          },
          {
            "lang": "JavaScript",
            "label": "Text-to-video",
            "source": "const form = new FormData();\nform.append(\"model\", \"flux-3\");\nform.append(\n  \"prompt\",\n  \"A paper boat glides across a still pond while the camera moves forward.\",\n);\nform.append(\"seconds\", \"5\");\nform.append(\"size\", \"1280x720\");\n\nconst response = await fetch(\"https://api.cometapi.com/v1/videos\", {\n  method: \"POST\",\n  headers: { Authorization: `Bearer ${process.env.COMETAPI_KEY}` },\n  body: form,\n});\n\nif (!response.ok) {\n  throw new Error(await response.text());\n}\n\nconsole.log(await response.json());\n"
          },
          {
            "lang": "Shell",
            "label": "HTTPS image-to-video",
            "source": "curl \\\n  https://api.cometapi.com/v1/videos \\\n  -H \"Authorization: Bearer $COMETAPI_KEY\" \\\n  --form-string 'model=flux-3' \\\n  --form-string 'prompt=Animate the reference scene with a slow camera move and natural motion.' \\\n  --form-string 'seconds=5' \\\n  --form-string 'size=1280x720' \\\n  --form-string 'input_reference=https://apidoc.cometapi.com/images/image/gemini/6100640_569429.png'"
          },
          {
            "lang": "Python",
            "label": "HTTPS image-to-video",
            "source": "import os\n\nimport requests\n\nfields = [\n    (\"model\", (None, \"flux-3\")),\n    (\n        \"prompt\",\n        (\n            None,\n            \"Animate the reference scene with a slow camera move and \"\n            \"natural motion.\",\n        ),\n    ),\n    (\"seconds\", (None, \"5\")),\n    (\"size\", (None, \"1280x720\")),\n    (\n        \"input_reference\",\n        (None, \"https://apidoc.cometapi.com/images/image/gemini/6100640_569429.png\"),\n    ),\n]\n\nresponse = requests.post(\n    \"https://api.cometapi.com/v1/videos\",\n    headers={\n        \"Authorization\": \"Bearer \" + os.environ[\"COMETAPI_KEY\"]\n    },\n    files=fields,\n    timeout=120,\n)\nresponse.raise_for_status()\nprint(response.json())\n"
          },
          {
            "lang": "JavaScript",
            "label": "HTTPS image-to-video",
            "source": "const form = new FormData();\nform.append(\"model\", \"flux-3\");\nform.append(\n  \"prompt\",\n  \"Animate the reference scene with a slow camera move and natural motion.\",\n);\nform.append(\"seconds\", \"5\");\nform.append(\"size\", \"1280x720\");\nform.append(\"input_reference\", \"https://apidoc.cometapi.com/images/image/gemini/6100640_569429.png\");\n\nconst response = await fetch(\"https://api.cometapi.com/v1/videos\", {\n  method: \"POST\",\n  headers: { Authorization: `Bearer ${process.env.COMETAPI_KEY}` },\n  body: form,\n});\n\nif (!response.ok) {\n  throw new Error(await response.text());\n}\n\nconsole.log(await response.json());\n"
          },
          {
            "lang": "Shell",
            "label": "First and last frames from URLs",
            "source": "image1=https://your-image-host/first-frame.png\nimage2=https://your-image-host/last-frame.png\n\ncurl \\\n  https://api.cometapi.com/v1/videos \\\n  -H \"Authorization: Bearer $COMETAPI_KEY\" \\\n  --form-string model=flux-3 \\\n  --form-string 'prompt=Move smoothly from the opening to the closing scene.' \\\n  --form-string seconds=5 \\\n  --form-string size=1280x720 \\\n  --form-string \"first_frame=$image1\" \\\n  --form-string \"last_frame=$image2\""
          },
          {
            "lang": "Python",
            "label": "First and last frames from URLs",
            "source": "import os\n\nimport requests\n\nurl1 = \"https://your-image-host/first-frame.png\"\nurl2 = \"https://your-image-host/last-frame.png\"\n\nprompt = \"Move smoothly from the opening to the closing scene.\"\n\nfields = [\n    (\"model\", (None, \"flux-3\")),\n    (\"prompt\", (None, prompt)),\n    (\"seconds\", (None, \"5\")),\n    (\"size\", (None, \"1280x720\")),\n    (\n        \"first_frame\",\n        (None, url1),\n    ),\n    (\n        \"last_frame\",\n        (None, url2),\n    ),\n]\n\nresponse = requests.post(\n    \"https://api.cometapi.com/v1/videos\",\n    headers={\"Authorization\": \"Bearer \" + os.environ[\"COMETAPI_KEY\"]},\n    files=fields,\n    timeout=120,\n)\n\nresponse.raise_for_status()\nprint(response.json())\n"
          },
          {
            "lang": "JavaScript",
            "label": "First and last frames from URLs",
            "source": "const form = new FormData();\nform.append(\"model\", \"flux-3\");\nform.append(\"prompt\", \"Move smoothly from the opening to the closing scene.\");\nform.append(\"seconds\", \"5\");\nform.append(\"size\", \"1280x720\");\nform.append(\n  \"first_frame\",\n  \"https://your-image-host/first-frame.png\",\n);\nform.append(\n  \"last_frame\",\n  \"https://your-image-host/last-frame.png\",\n);\n\nconst response = await fetch(\"https://api.cometapi.com/v1/videos\", {\n  method: \"POST\",\n  headers: { Authorization: \"Bearer \" + process.env.COMETAPI_KEY },\n  body: form,\n});\n\nif (!response.ok) {\n  throw new Error(await response.text());\n}\n\nconsole.log(await response.json());\n"
          },
          {
            "lang": "Shell",
            "label": "First and last frames from files",
            "source": "curl \\\n  https://api.cometapi.com/v1/videos \\\n  -H \"Authorization: Bearer $COMETAPI_KEY\" \\\n  --form-string model=flux-3 \\\n  --form-string 'prompt=Move smoothly from the opening to the closing scene.' \\\n  --form-string seconds=5 \\\n  --form-string size=1280x720 \\\n  --form 'first_frame=@/path/to/first-frame.png;type=image/png' \\\n  --form 'last_frame=@/path/to/last-frame.png;type=image/png'"
          },
          {
            "lang": "Python",
            "label": "First and last frames from files",
            "source": "import os\nfrom contextlib import ExitStack\n\nimport requests\n\nprompt = (\n    \"Move smoothly from the opening to the closing scene.\"\n)\n\nwith ExitStack() as stack:\n    image_1 = stack.enter_context(open(\"/path/to/first-frame.png\", \"rb\"))\n    image_2 = stack.enter_context(open(\"/path/to/last-frame.png\", \"rb\"))\n    fields = [\n        (\"model\", (None, \"flux-3\")),\n        (\"prompt\", (None, prompt)),\n        (\"seconds\", (None, \"5\")),\n        (\"size\", (None, \"1280x720\")),\n        (\"first_frame\", (\"first-frame.png\", image_1, \"image/png\")),\n        (\"last_frame\", (\"last-frame.png\", image_2, \"image/png\")),\n    ]\n\n    response = requests.post(\n        \"https://api.cometapi.com/v1/videos\",\n        headers={\"Authorization\": \"Bearer \" + os.environ[\"COMETAPI_KEY\"]},\n        files=fields,\n        timeout=120,\n    )\n\nresponse.raise_for_status()\nprint(response.json())\n"
          },
          {
            "lang": "JavaScript",
            "label": "First and last frames from files",
            "source": "import { readFile } from \"node:fs/promises\";\n\nconst image_1 = await readFile(\"/path/to/first-frame.png\");\nconst image_2 = await readFile(\"/path/to/last-frame.png\");\n\nconst form = new FormData();\nform.append(\"model\", \"flux-3\");\nform.append(\"prompt\", \"Move smoothly from the opening to the closing scene.\");\nform.append(\"seconds\", \"5\");\nform.append(\"size\", \"1280x720\");\nform.append(\n  \"first_frame\",\n  new Blob([image_1], { type: \"image/png\" }),\n  \"first-frame.png\",\n);\nform.append(\n  \"last_frame\",\n  new Blob([image_2], { type: \"image/png\" }),\n  \"last-frame.png\",\n);\n\nconst response = await fetch(\"https://api.cometapi.com/v1/videos\", {\n  method: \"POST\",\n  headers: { Authorization: \"Bearer \" + process.env.COMETAPI_KEY },\n  body: form,\n});\n\nif (!response.ok) {\n  throw new Error(await response.text());\n}\n\nconsole.log(await response.json());\n"
          },
          {
            "lang": "Shell",
            "label": "Opening frame from a file",
            "source": "curl \\\n  https://api.cometapi.com/v1/videos \\\n  -H \"Authorization: Bearer $COMETAPI_KEY\" \\\n  --form-string 'model=flux-3' \\\n  --form-string 'prompt=Animate the opening frame with a slow camera move and natural motion.' \\\n  --form-string 'seconds=5' \\\n  --form-string 'size=1280x720' \\\n  --form 'first_frame=@/path/to/reference.png;type=image/png'"
          },
          {
            "lang": "Python",
            "label": "Opening frame from a file",
            "source": "import os\n\nimport requests\n\nprompt = (\n    \"Animate the opening frame with a slow camera move and \"\n    \"natural motion.\"\n)\n\nwith open(\"/path/to/reference.png\", \"rb\") as reference:\n    response = requests.post(\n        \"https://api.cometapi.com/v1/videos\",\n        headers={\n            \"Authorization\": \"Bearer \"\n            + os.environ[\"COMETAPI_KEY\"]\n        },\n        data={\n            \"model\": \"flux-3\",\n            \"prompt\": prompt,\n            \"seconds\": \"5\",\n            \"size\": \"1280x720\",\n        },\n        files={\n            \"first_frame\": (\n                \"reference.png\",\n                reference,\n                \"image/png\",\n            )\n        },\n        timeout=120,\n    )\n\nresponse.raise_for_status()\nprint(response.json())\n"
          },
          {
            "lang": "JavaScript",
            "label": "Opening frame from a file",
            "source": "import { readFile } from \"node:fs/promises\";\n\nconst reference = await readFile(\"/path/to/reference.png\");\nconst form = new FormData();\nform.append(\"model\", \"flux-3\");\nform.append(\n  \"prompt\",\n  \"Animate the opening frame with a slow camera move and natural motion.\",\n);\nform.append(\"seconds\", \"5\");\nform.append(\"size\", \"1280x720\");\nform.append(\n  \"first_frame\",\n  new Blob([reference], { type: \"image/png\" }),\n  \"reference.png\",\n);\n\nconst response = await fetch(\"https://api.cometapi.com/v1/videos\", {\n  method: \"POST\",\n  headers: { Authorization: `Bearer ${process.env.COMETAPI_KEY}` },\n  body: form,\n});\n\nif (!response.ok) {\n  throw new Error(await response.text());\n}\n\nconsole.log(await response.json());\n"
          },
          {
            "lang": "Shell",
            "label": "Ordered keyframes from image URLs",
            "source": "curl \\\n  https://api.cometapi.com/v1/videos \\\n  -H \"Authorization: Bearer $COMETAPI_KEY\" \\\n  --form-string 'model=flux-3' \\\n  --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.' \\\n  --form-string 'seconds=5' \\\n  --form-string 'size=1280x720' \\\n  --form-string 'input_reference=https://apidoc.cometapi.com/images/image/gemini/6100640_569429.png' \\\n  --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\n\nimport requests\n\nfields = [\n    (\"model\", (None, \"flux-3\")),\n    (\"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.\")),\n    (\"seconds\", (None, \"5\")),\n    (\"size\", (None, \"1280x720\")),\n    (\"input_reference\", (None, \"https://apidoc.cometapi.com/images/image/gemini/6100640_569429.png\")),\n    (\"input_reference\", (None, \"https://apidoc.cometapi.com/images/image/gemini/6100640_569420.png\")),\n]\n\nresponse = requests.post(\n    \"https://api.cometapi.com/v1/videos\",\n    headers={\"Authorization\": \"Bearer \" + os.environ[\"COMETAPI_KEY\"]},\n    files=fields,\n    timeout=120,\n)\nresponse.raise_for_status()\nprint(response.json())\n"
          },
          {
            "lang": "JavaScript",
            "label": "Ordered keyframes from image URLs",
            "source": "const form = new FormData();\nform.append(\"model\", \"flux-3\");\nform.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.\");\nform.append(\"seconds\", \"5\");\nform.append(\"size\", \"1280x720\");\nform.append(\"input_reference\", \"https://apidoc.cometapi.com/images/image/gemini/6100640_569429.png\");\nform.append(\"input_reference\", \"https://apidoc.cometapi.com/images/image/gemini/6100640_569420.png\");\n\nconst response = await fetch(\"https://api.cometapi.com/v1/videos\", {\n  method: \"POST\",\n  headers: { Authorization: `Bearer ${process.env.COMETAPI_KEY}` },\n  body: form,\n});\n\nif (!response.ok) {\n  throw new Error(await response.text());\n}\n\nconsole.log(await response.json());\n"
          }
        ]
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Bearer authentication. Use your CometAPI API key."
      }
    },
    "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
      }
    }
  }
}
