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

# Opprett en HappyHorse-video

> Opprett en HappyHorse-oppgave for tekst-til-video eller referansebilde-video via CometAPI med POST /v1/videos, kontroller deretter oppgaven regelmessig og last ned den fullførte MP4-filen.

Opprett en HappyHorse-video fra tekst, referansebilder eller et startbilde. API-et returnerer umiddelbart en oppgave-ID. Lagre den returnerte `id` for å kontrollere oppgaven regelmessig og laste ned den fullførte videoen.

`POST /v1/videos` bruker `multipart/form-data`. Send kontroller som skjemafelt og referansebilder som `input_reference`-felt, med én HTTPS-URL eller opplastet bildefil per felt.

## Velg en inndatamodus

| Formål                           | Modell                             | Obligatoriske felt                                          | Valgfrie felt     |
| -------------------------------- | ---------------------------------- | ----------------------------------------------------------- | ----------------- |
| Tekst-til-video                  | `happyhorse-1.0`, `happyhorse-1.1` | `model`, `prompt`                                           | `seconds`, `size` |
| Referanse-til-video              | `happyhorse-1.0`, `happyhorse-1.1` | `model`, `prompt`, 1–9 `input_reference` URL-er eller filer | `seconds`, `size` |
| Bilde-til-video med første bilde | `happyhorse-1.0`, `happyhorse-1.1` | `model`, `prompt`, én `first_frame`-URL eller fil           | `seconds`, `size` |

Referansebilder styrer motivene og de visuelle detaljene i videoen. Send 1–9 offentlig tilgjengelige HTTPS-bilde-URL-er eller 1–9 bildefiler, og gjenta `input_reference` én gang per bilde i bilderekkefølge.

Bruk enten bare URL-er eller bare filer i dette feltet. Send hver URL separat i stedet for å sette sammen URL-er med kommaer.

For `input_reference` må hvert referansebilde være på maksimalt 10 MB med `happyhorse-1.0`.
Med `happyhorse-1.1` må hvert referansebilde være på maksimalt 20 MB.
Disse modellgrensene gjelder både for bilde-URL-er og opplastede filer.

Bruk JPEG-, JPG-, PNG- eller WEBP-bilder med en korteste side på minst 400 px.

Opplastingsgrensen for `input_reference` er 20 MiB (20 × 1024 × 1024 byte) per fil. Opplastede bilder må også oppfylle den modellspesifikke grensen ovenfor.

Forespørselseksemplene øverst på denne siden viser flere bilde-URL-er for HappyHorse 1.1 og flere filopplastinger for begge modellene.

For å angi startbildet sender du `first_frame` én gang med én offentlig tilgjengelig HTTPS-bilde-URL eller én bildefil. Bruk dette feltet i en separat forespørsel fra `input_reference`.

## Angi varighet og størrelse

| Modell-ID        | `seconds`        | Standard                  |
| ---------------- | ---------------- | ------------------------- |
| `happyhorse-1.0` | heltall `3`-`15` | `5` sekunder, `1920x1080` |
| `happyhorse-1.1` | heltall `3`-`15` | `5` sekunder, `1920x1080` |

Velg en nøyaktig `WxH`-verdi for `size` fra tabellen nedenfor.

For forespørsler med første bilde bestemmer bildet innrammingen og størrelsesforholdet, mens `size` velger oppløsningsnivået for utdataene.

| Modell           | Bildeformat             | `size` verdier          |
| ---------------- | ----------------------- | ----------------------- |
| `happyhorse-1.0` | Liggende                | `1280x720`, `1920x1080` |
|                  | Stående                 | `720x1280`, `1080x1920` |
|                  | Kvadratisk              | `1440x1440`             |
| `happyhorse-1.1` | Liggende                | `1280x720`, `1920x1080` |
|                  | Stående                 | `720x1280`, `1080x1920` |
|                  | Kvadratisk              | `1440x1440`             |
|                  | Klassisk liggende       | `1440x1080`             |
|                  | Klassisk stående        | `720x960`, `1080x1440`  |
|                  | Bredt liggende          | `2520x1080`             |
|                  | Bredt stående           | `1080x2520`             |
|                  | Nær kvadratisk liggende | `900x720`, `1350x1080`  |
|                  | Nær kvadratisk stående  | `720x900`, `1080x1350`  |

## Oppgaveflyt

<Steps>
  <Step title="Opprett oppgaven">
    Send multipart-skjemaforespørselen og lagre den returnerte `id`.
  </Step>

  <Step title="Kontroller oppgaven regelmessig">
    Kall [Hent en HappyHorse-video](./retrieve) til `status` er `completed`, `failed` eller `error`.
  </Step>

  <Step title="Last ned resultatet">
    Når oppgaven er `completed`, kaller du [Hent HappyHorse-videoinnhold](./retrieve-content) for å laste ned MP4-filen.
  </Step>
</Steps>


## OpenAPI

````yaml api/openapi/video/happyhorse/post-create.openapi.json POST /v1/videos
openapi: 3.1.0
info:
  title: HappyHorse Video Create API
  version: 1.0.0
  description: >-
    Create an asynchronous HappyHorse video task through CometAPI. Send
    text-to-video and reference-image video requests through the same POST
    /v1/videos multipart endpoint. Save the returned id, poll GET
    /v1/videos/{task_id}, and download the completed MP4 file.
servers:
  - url: https://api.cometapi.com
security:
  - bearerAuth: []
paths:
  /v1/videos:
    post:
      summary: Create a HappyHorse video task
      description: >-
        Create a HappyHorse text-to-video, reference-to-video, or first-frame
        video task. Send fields as multipart/form-data. For reference-to-video,
        send 1–9 HTTPS image URLs or 1–9 uploaded image files by repeating
        input_reference once per image. Use only URLs or only files within
        input_reference. Use first_frame separately to set the opening frame.
      operationId: happyhorse_create_video
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/HappyHorseCreateRequest'
            encoding:
              input_reference:
                contentType: text/plain, image/jpeg, image/png, image/webp
                style: form
                explode: true
              first_frame:
                contentType: text/plain, image/jpeg, image/png, image/webp
            examples:
              happyhorse_1_1_text_to_video:
                summary: HappyHorse 1.1 text-to-video
                value:
                  model: happyhorse-1.1
                  prompt: >-
                    A close-up cinematic shot of a ceramic coffee cup on a
                    wooden table. Steam rises slowly while morning light moves
                    across the background.
                  seconds: 3
                  size: 1920x1080
              happyhorse_1_1_reference_to_video:
                summary: HappyHorse 1.1 reference-to-video
                value:
                  model: happyhorse-1.1
                  prompt: >-
                    Use the uploaded reference image as the visual guide. Create
                    a short cinematic shot with gentle natural motion.
                  seconds: 3
                  size: 1280x720
                  input_reference:
                    - '@/path/to/reference.png'
              happyhorse_1_0_text_to_video:
                summary: HappyHorse 1.0 text-to-video
                value:
                  model: happyhorse-1.0
                  prompt: >-
                    A person reads beside a tall window while soft daylight
                    moves across the room.
                  seconds: 3
                  size: 1280x720
              happyhorse_1_1_uploaded_references_to_video:
                summary: HappyHorse 1.1 multiple reference images
                value:
                  model: happyhorse-1.1
                  prompt: Keep both reference subjects in gentle motion.
                  seconds: 3
                  size: 1280x720
                  input_reference:
                    - '@/path/to/reference-1.png'
                    - '@/path/to/reference-2.png'
              happyhorse_1_1_first_frame_url:
                summary: HappyHorse 1.1 first frame from URL
                value:
                  model: happyhorse-1.1
                  prompt: Start from this image and slowly pan right.
                  seconds: 3
                  size: 1280x720
                  first_frame: >-
                    https://apidoc.cometapi.com/images/image/gemini/6100640_569429.png
              happyhorse_1_1_first_frame_file:
                summary: HappyHorse 1.1 first frame from file
                value:
                  model: happyhorse-1.1
                  prompt: Start from this image and slowly pan right.
                  seconds: 3
                  size: 1280x720
                  first_frame: '@/path/to/first-frame.png'
              happyhorse_1_0_uploaded_references_to_video:
                summary: HappyHorse 1.0 multiple reference images
                value:
                  model: happyhorse-1.0
                  prompt: Keep both reference subjects in gentle motion.
                  seconds: 3
                  size: 1280x720
                  input_reference:
                    - '@/path/to/reference-1.png'
                    - '@/path/to/reference-2.png'
              happyhorse_1_0_first_frame_url:
                summary: HappyHorse 1.0 first frame from URL
                value:
                  model: happyhorse-1.0
                  prompt: Start from this image and slowly pan right.
                  seconds: 3
                  size: 1280x720
                  first_frame: >-
                    https://apidoc.cometapi.com/images/image/gemini/6100640_569429.png
              happyhorse_1_0_first_frame_file:
                summary: HappyHorse 1.0 first frame from file
                value:
                  model: happyhorse-1.0
                  prompt: Start from this image and slowly pan right.
                  seconds: 3
                  size: 1280x720
                  first_frame: '@/path/to/first-frame.png'
              happyhorse_1_1_reference_image_url:
                summary: HappyHorse 1.1 reference image URLs
                value:
                  model: happyhorse-1.1
                  prompt: >-
                    Use both reference images as visual guides. Preserve their
                    visual details with gentle natural motion.
                  seconds: 3
                  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/HappyHorseVideoTask'
              example:
                id: task_example
                task_id: task_example
                object: video
                model: happyhorse-1.1
                status: queued
                progress: 0
                created_at: 1779938152
        '400':
          description: >-
            The request is missing a required field or contains a value that the
            selected model cannot use.
        '401':
          description: The API key is missing or invalid.
      security:
        - bearerAuth: []
      x-codeSamples:
        - lang: Shell
          label: HappyHorse 1.1 text-to-video
          source: |-
            curl https://api.cometapi.com/v1/videos \
              -H "Authorization: Bearer $COMETAPI_KEY" \
              -F model=happyhorse-1.1 \
              -F 'prompt=A close-up cinematic shot of a ceramic coffee cup on a wooden table. Steam rises slowly while morning light moves across the background.' \
              -F seconds=3 \
              -F size=1920x1080
        - lang: Python
          label: HappyHorse 1.1 text-to-video
          source: |
            import os
            import requests

            fields = [
                ("model", (None, "happyhorse-1.1")),
                ("prompt", (None, "A close-up cinematic shot of a ceramic coffee cup on a wooden table. Steam rises slowly while morning light moves across the background.")),
                ("seconds", (None, "3")),
                ("size", (None, "1920x1080")),
            ]

            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: HappyHorse 1.1 text-to-video
          source: >
            const form = new FormData();

            form.append("model", "happyhorse-1.1");

            form.append("prompt", "A close-up cinematic shot of a ceramic coffee
            cup on a wooden table. Steam rises slowly while morning light moves
            across the background.");

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

            form.append("size", "1920x1080");


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


            const result = await response.json();

            console.log(result);
        - lang: Shell
          label: HappyHorse 1.1 reference-to-video
          source: |-
            curl https://api.cometapi.com/v1/videos \
              -H "Authorization: Bearer $COMETAPI_KEY" \
              -F model=happyhorse-1.1 \
              -F 'prompt=Use the uploaded reference image as the visual guide. Create a short cinematic shot with gentle natural motion.' \
              -F seconds=3 \
              -F size=1280x720 \
              -F 'input_reference=@/path/to/reference.png'
        - lang: Python
          label: HappyHorse 1.1 reference-to-video
          source: >
            import os

            import requests


            prompt = "Use the uploaded reference image as the visual guide.
            Create a short cinematic shot with gentle 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": "happyhorse-1.1",
                        "prompt": prompt,
                        "seconds": "3",
                        "size": "1280x720",
                    },
                    files={"input_reference": ("reference.png", reference, "image/png")},
                    timeout=120,
                )

            response.raise_for_status()

            print(response.json())
        - lang: JavaScript
          label: HappyHorse 1.1 reference-to-video
          source: >
            import { readFile } from "node:fs/promises";


            const reference = await readFile("/path/to/reference.png");


            const form = new FormData();

            form.append("model", "happyhorse-1.1");

            form.append("prompt", "Use the uploaded reference image as the
            visual guide. Create a short cinematic shot with gentle natural
            motion.");

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

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

            form.append("input_reference", 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,
            });


            const result = await response.json();

            console.log(result);
        - lang: Shell
          label: HappyHorse 1.0 text-to-video
          source: |-
            curl https://api.cometapi.com/v1/videos \
              -H "Authorization: Bearer $COMETAPI_KEY" \
              -F model=happyhorse-1.0 \
              -F 'prompt=A person reads beside a tall window while soft daylight moves across the room.' \
              -F seconds=3 \
              -F size=1280x720
        - lang: Python
          label: HappyHorse 1.0 text-to-video
          source: |
            import os
            import requests

            fields = [
                ("model", (None, "happyhorse-1.0")),
                ("prompt", (None, "A person reads beside a tall window while soft daylight moves across the room.")),
                ("seconds", (None, "3")),
                ("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: HappyHorse 1.0 text-to-video
          source: >
            const form = new FormData();

            form.append("model", "happyhorse-1.0");

            form.append("prompt", "A person reads beside a tall window while
            soft daylight moves across the room.");

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

            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,
            });


            const result = await response.json();

            console.log(result);
        - lang: Shell
          label: HappyHorse 1.1 multiple reference images
          source: |
            curl \
              https://api.cometapi.com/v1/videos \
              -H "Authorization: Bearer $COMETAPI_KEY" \
              --form-string model=happyhorse-1.1 \
              --form-string 'prompt=Keep both reference subjects in gentle motion.' \
              --form-string seconds=3 \
              --form-string size=1280x720 \
              --form 'input_reference=@/path/to/reference-1.png;type=image/png' \
              --form 'input_reference=@/path/to/reference-2.png;type=image/png'
        - lang: Python
          label: HappyHorse 1.1 multiple reference images
          source: |
            import os
            from contextlib import ExitStack

            import requests

            with ExitStack() as stack:
                fields = [
                    ("model", (None, "happyhorse-1.1")),
                    ("prompt", (None, "Keep both reference subjects in gentle motion.")),
                    ("seconds", (None, "3")),
                    ("size", (None, "1280x720")),
                    (
                        "input_reference",
                        (
                            "reference-1.png",
                            stack.enter_context(open("/path/to/reference-1.png", "rb")),
                            "image/png",
                        ),
                    ),
                    (
                        "input_reference",
                        (
                            "reference-2.png",
                            stack.enter_context(open("/path/to/reference-2.png", "rb")),
                            "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: HappyHorse 1.1 multiple reference images
          source: >
            import { readFile } from "node:fs/promises";


            const form = new FormData();

            form.append("model", "happyhorse-1.1");

            form.append("prompt", "Keep both reference subjects in gentle
            motion.");

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

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

            form.append(
              "input_reference",
              new Blob([await readFile("/path/to/reference-1.png")], {
                type: "image/png",
              }),
              "reference-1.png",
            );

            form.append(
              "input_reference",
              new Blob([await readFile("/path/to/reference-2.png")], {
                type: "image/png",
              }),
              "reference-2.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: HappyHorse 1.1 first frame from URL
          source: >-
            image1=https://apidoc.cometapi.com/images/image/gemini/6100640_569429.png


            curl https://api.cometapi.com/v1/videos \
              -H "Authorization: Bearer $COMETAPI_KEY" \
              --form-string model=happyhorse-1.1 \
              --form-string 'prompt=Start from this image and slowly pan right.' \
              --form-string seconds=3 \
              --form-string size=1280x720 \
              --form-string "first_frame=$image1"
        - lang: Python
          label: HappyHorse 1.1 first frame from URL
          source: >
            import os


            import requests


            url1 =
            "https://apidoc.cometapi.com/images/image/gemini/6100640_569429.png"


            prompt = "Start from this image and slowly pan right."


            fields = [
                ("model", (None, "happyhorse-1.1")),
                ("prompt", (None, prompt)),
                ("seconds", (None, "3")),
                ("size", (None, "1280x720")),
                (
                    "first_frame",
                    (None, url1),
                ),
            ]


            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: HappyHorse 1.1 first frame from URL
          source: >
            const form = new FormData();

            form.append("model", "happyhorse-1.1");

            form.append("prompt", "Start from this image and slowly pan
            right.");

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

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

            form.append(
              "first_frame",
              "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: HappyHorse 1.1 first frame from file
          source: |-
            curl https://api.cometapi.com/v1/videos \
              -H "Authorization: Bearer $COMETAPI_KEY" \
              --form-string model=happyhorse-1.1 \
              --form-string 'prompt=Start from this image and slowly pan right.' \
              --form-string seconds=3 \
              --form-string size=1280x720 \
              --form 'first_frame=@/path/to/first-frame.png;type=image/png'
        - lang: Python
          label: HappyHorse 1.1 first frame from file
          source: |
            import os

            import requests

            prompt = (
                "Start from this image and slowly pan right."
            )

            with open("/path/to/first-frame.png", "rb") as image_1:
                fields = [
                    ("model", (None, "happyhorse-1.1")),
                    ("prompt", (None, prompt)),
                    ("seconds", (None, "3")),
                    ("size", (None, "1280x720")),
                    ("first_frame", ("first-frame.png", image_1, "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: HappyHorse 1.1 first frame from file
          source: >
            import { readFile } from "node:fs/promises";


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


            const form = new FormData();

            form.append("model", "happyhorse-1.1");

            form.append("prompt", "Start from this image and slowly pan
            right.");

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

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

            form.append(
              "first_frame",
              new Blob([image_1], { type: "image/png" }),
              "first-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: HappyHorse 1.0 multiple reference images
          source: |
            curl \
              https://api.cometapi.com/v1/videos \
              -H "Authorization: Bearer $COMETAPI_KEY" \
              --form-string model=happyhorse-1.0 \
              --form-string 'prompt=Keep both reference subjects in gentle motion.' \
              --form-string seconds=3 \
              --form-string size=1280x720 \
              --form 'input_reference=@/path/to/reference-1.png;type=image/png' \
              --form 'input_reference=@/path/to/reference-2.png;type=image/png'
        - lang: Python
          label: HappyHorse 1.0 multiple reference images
          source: |
            import os
            from contextlib import ExitStack

            import requests

            with ExitStack() as stack:
                fields = [
                    ("model", (None, "happyhorse-1.0")),
                    ("prompt", (None, "Keep both reference subjects in gentle motion.")),
                    ("seconds", (None, "3")),
                    ("size", (None, "1280x720")),
                    (
                        "input_reference",
                        (
                            "reference-1.png",
                            stack.enter_context(open("/path/to/reference-1.png", "rb")),
                            "image/png",
                        ),
                    ),
                    (
                        "input_reference",
                        (
                            "reference-2.png",
                            stack.enter_context(open("/path/to/reference-2.png", "rb")),
                            "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: HappyHorse 1.0 multiple reference images
          source: >
            import { readFile } from "node:fs/promises";


            const form = new FormData();

            form.append("model", "happyhorse-1.0");

            form.append("prompt", "Keep both reference subjects in gentle
            motion.");

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

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

            form.append(
              "input_reference",
              new Blob([await readFile("/path/to/reference-1.png")], {
                type: "image/png",
              }),
              "reference-1.png",
            );

            form.append(
              "input_reference",
              new Blob([await readFile("/path/to/reference-2.png")], {
                type: "image/png",
              }),
              "reference-2.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: HappyHorse 1.0 first frame from URL
          source: >-
            image1=https://apidoc.cometapi.com/images/image/gemini/6100640_569429.png


            curl https://api.cometapi.com/v1/videos \
              -H "Authorization: Bearer $COMETAPI_KEY" \
              --form-string model=happyhorse-1.0 \
              --form-string 'prompt=Start from this image and slowly pan right.' \
              --form-string seconds=3 \
              --form-string size=1280x720 \
              --form-string "first_frame=$image1"
        - lang: Python
          label: HappyHorse 1.0 first frame from URL
          source: >
            import os


            import requests


            url1 =
            "https://apidoc.cometapi.com/images/image/gemini/6100640_569429.png"


            prompt = "Start from this image and slowly pan right."


            fields = [
                ("model", (None, "happyhorse-1.0")),
                ("prompt", (None, prompt)),
                ("seconds", (None, "3")),
                ("size", (None, "1280x720")),
                (
                    "first_frame",
                    (None, url1),
                ),
            ]


            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: HappyHorse 1.0 first frame from URL
          source: >
            const form = new FormData();

            form.append("model", "happyhorse-1.0");

            form.append("prompt", "Start from this image and slowly pan
            right.");

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

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

            form.append(
              "first_frame",
              "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: HappyHorse 1.0 first frame from file
          source: |-
            curl https://api.cometapi.com/v1/videos \
              -H "Authorization: Bearer $COMETAPI_KEY" \
              --form-string model=happyhorse-1.0 \
              --form-string 'prompt=Start from this image and slowly pan right.' \
              --form-string seconds=3 \
              --form-string size=1280x720 \
              --form 'first_frame=@/path/to/first-frame.png;type=image/png'
        - lang: Python
          label: HappyHorse 1.0 first frame from file
          source: |
            import os

            import requests

            prompt = (
                "Start from this image and slowly pan right."
            )

            with open("/path/to/first-frame.png", "rb") as image_1:
                fields = [
                    ("model", (None, "happyhorse-1.0")),
                    ("prompt", (None, prompt)),
                    ("seconds", (None, "3")),
                    ("size", (None, "1280x720")),
                    ("first_frame", ("first-frame.png", image_1, "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: HappyHorse 1.0 first frame from file
          source: >
            import { readFile } from "node:fs/promises";


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


            const form = new FormData();

            form.append("model", "happyhorse-1.0");

            form.append("prompt", "Start from this image and slowly pan
            right.");

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

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

            form.append(
              "first_frame",
              new Blob([image_1], { type: "image/png" }),
              "first-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: HappyHorse 1.1 reference image URLs
          source: |
            curl \
              https://api.cometapi.com/v1/videos \
              -H "Authorization: Bearer $COMETAPI_KEY" \
              --form-string model=happyhorse-1.1 \
              --form-string 'prompt=Use both reference images as visual guides. Preserve their visual details with gentle natural motion.' \
              --form-string seconds=3 \
              --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: HappyHorse 1.1 reference image URLs
          source: |
            import os

            import requests

            fields = [
                ("model", (None, "happyhorse-1.1")),
                (
                    "prompt",
                    (
                        None,
                        "Use both reference images as visual guides. Preserve their "
                        "visual details with gentle natural motion."
                    ),
                ),
                ("seconds", (None, "3")),
                ("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: HappyHorse 1.1 reference image URLs
          source: |
            const form = new FormData();
            form.append("model", "happyhorse-1.1");
            form.append(
              "prompt",
              "Use both reference images as visual guides. Preserve their visual " +
              "details with gentle natural motion.",
            );
            form.append("seconds", "3");
            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:
    HappyHorseCreateRequest:
      type: object
      required:
        - model
        - prompt
      properties:
        model:
          type: string
          description: HappyHorse model ID for this endpoint.
          enum:
            - happyhorse-1.0
            - happyhorse-1.1
          example: happyhorse-1.1
        prompt:
          type: string
          description: >-
            Text prompt that describes the video to generate. For image inputs,
            describe the motion and visual details to preserve.
          example: >-
            Use the uploaded reference image as the visual guide. Create a short
            cinematic shot with gentle natural motion.
        seconds:
          type: integer
          minimum: 3
          maximum: 15
          default: 5
          description: >-
            Requested clip duration in whole seconds. Send an integer from 3
            through 15 as a form field. The default is 5.
          example: 3
        size:
          type: string
          description: >-
            Output size as an exact WxH value. Use one of the documented size
            values for the selected HappyHorse model. For first-frame requests,
            size selects the resolution tier; the image determines the framing
            and aspect ratio.
          example: 1920x1080
        input_reference:
          description: >-
            Reference images for reference-to-video. Send 1–9 publicly
            accessible HTTPS image URLs or 1–9 uploaded image files by repeating
            input_reference once per image. Use only URLs or only files within
            this field; do not join URLs with commas. Reference images guide
            subjects and visual details. CometAPI preserves image order. Use
            JPEG, JPG, PNG, or WEBP images with a shortest side of at least 400
            px. Each reference image must be at or below 10 MB for
            happyhorse-1.0 or 20 MB for happyhorse-1.1. These model limits apply
            to both image URLs and uploaded files. The input_reference file
            upload limit is 20 MiB (20 x 1024 x 1024 bytes) per file. Keep
            uploads within the model limit as well. Keep this field separate
            from first_frame.
          anyOf:
            - title: Single image URL
              type: string
              format: uri
              pattern: ^https://
              description: One publicly accessible HTTPS image URL.
            - title: Image URLs
              type: array
              minItems: 1
              maxItems: 9
              items:
                type: string
                format: uri
                pattern: ^https://
                description: One publicly accessible HTTPS image URL.
            - title: Image files
              type: array
              minItems: 1
              maxItems: 9
              items:
                type: string
                format: binary
                description: One uploaded reference image file.
        first_frame:
          description: >-
            Opening-frame image as one publicly accessible HTTPS URL or one
            image file. Send this field once, using either a URL or a file. Use
            JPEG, JPG, PNG, or WEBP images up to 20 MB. Do not combine
            first_frame with input_reference.
          anyOf:
            - type: string
              format: uri
              pattern: ^https://
            - type: string
              format: binary
      additionalProperties: false
      not:
        required:
          - first_frame
          - input_reference
    HappyHorseVideoTask:
      type: object
      required:
        - id
        - object
        - model
        - status
        - progress
        - created_at
      properties:
        id:
          type: string
          description: Task ID. Use this value with retrieve and content endpoints.
          example: task_example
        task_id:
          type: string
          description: Compatibility alias for id when present.
          example: task_example
        object:
          type: string
          description: Object type. Video tasks return video.
          example: video
        model:
          type: string
          description: Model ID used for the task.
          example: happyhorse-1.1
        status:
          type: string
          description: >-
            Task lifecycle status. Poll until the value is completed, failed, or
            error.
          enum:
            - queued
            - in_progress
            - completed
            - failed
            - error
          example: queued
        progress:
          type: integer
          minimum: 0
          maximum: 100
          description: Task progress as a coarse percentage.
          example: 0
        created_at:
          type: integer
          description: Task creation time as a Unix timestamp in seconds.
          example: 1779938152
        completed_at:
          type: integer
          description: >-
            Task completion time as a Unix timestamp in seconds. This field
            appears on completed tasks.
          example: 1779938219
        video_url:
          type: string
          description: Temporary video delivery URL. This field appears on completed tasks.
          example: <temporary-video-url>
        error:
          type: object
          description: Failure details. This field appears when the task fails.
          additionalProperties: true
      additionalProperties: true
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: Bearer authentication. Use your CometAPI API key.

````