Search

Search HiAPI models, tools, and resources.

Back to blog
Tutorial

How to Use the Creatify Boreal API: Text, Image and Audio to Video

hiapivideocreatifyapitutorial

creatify-boreal is a video model on hiapi that returns a finished clip with speech and sound already mixed in. One model id covers three starting points: a prompt only, a prompt plus a reference image, or a prompt plus your own narration audio. This guide shows the request, the polling loop, and what a real generation looked like when I ran it.

You need an API key from the hiapi dashboard. Every call goes through the unified task endpoint, POST /v1/tasks.

Input fields

These were checked against the live model page and by sending deliberately invalid values to /v1/tasks, which return a 400 and are not billed.

FieldRequiredAccepted values
promptyestext, up to 5000 characters
image_urlnoJPG/PNG/WebP, 10 MB; sets subject and composition
audio_urlnoMP3/WAV/M4A, 15 MB; only the first duration seconds are used
negative_promptnoup to 2000 characters
resolutionno720p, 1080p, 2k
aspect_rationoauto, 16:9, 9:16, 1:1, 4:3, 3:4
durationnowhole seconds, 1 to 20

The three modes are not separate model ids. Leave out image_url and audio_url for text-to-video, add image_url for image-to-video, and add audio_url (usually with an image) to have the presenter follow your narration.

Minimal working request

curl -X POST 'https://api.hiapi.ai/v1/tasks' \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "creatify-boreal",
    "input": {
      "prompt": "Vertical selfie-style UGC video: a young woman in a bright bedroom holds up a pastel lip balm and says to camera: \"Okay, this is the only lip balm that survived my winter.\" Natural room tone.",
      "resolution": "720p",
      "aspect_ratio": "9:16",
      "duration": 4
    }
  }'

The response gives you a task id:

{"code":200,"data":{"taskId":"tk-hiapi-01M5MJC8NG8E1E0XN9NEJRDBQH"},"message":"success"}

Python: submit and poll

import os, time, requests

BASE = "https://api.hiapi.ai/v1/tasks"
HEADERS = {"Authorization": f"Bearer {os.environ['HIAPI_API_KEY']}"}

def create(payload: dict) -> str:
    r = requests.post(BASE, headers=HEADERS, json=payload, timeout=30)
    r.raise_for_status()
    return r.json()["data"]["taskId"]

def wait(task_id: str, every: int = 10, limit: int = 900) -> dict:
    start = time.time()
    while time.time() - start < limit:
        try:
            d = requests.get(f"{BASE}/{task_id}", headers=HEADERS, timeout=30).json()["data"]
        except (requests.RequestException, ValueError):
            time.sleep(every)  # transient network error: keep polling the same id
            continue
        if d["status"] == "success":
            return d
        if d["status"] == "fail":
            raise RuntimeError(d.get("error"))
        time.sleep(every)
    raise TimeoutError(task_id)

task_id = create({
    "model": "creatify-boreal",
    "input": {
        "prompt": "Vertical selfie-style UGC video: a young woman holds up a pastel lip balm and says to camera: \"Okay, this is the only lip balm that survived my winter.\" Natural room tone.",
        "resolution": "720p",
        "aspect_ratio": "9:16",
        "duration": 4,
    },
})
result = wait(task_id)
print(result["output"][0]["url"])

Status moves through handling, then archiving, then success. The video URL is in data.output[0].url.

Image and audio modes

Image-to-video adds one field:

{"model": "creatify-boreal",
 "input": {"prompt": "The woman smiles and talks to the camera in her kitchen: \"I swapped my coffee for this oat latte mix.\" Natural kitchen ambience.",
           "image_url": "https://your-cdn.example/presenter.jpg",
           "resolution": "720p", "duration": 8}}

Audio-driven adds audio_url pointing at your narration file. The model page describes it as narration kept in the video with lips following it, and says only the first duration seconds of the audio are used, so set duration to the length of the clip you want. The model page's audio examples pair the audio with a reference image; I did not run an image-plus-audio generation myself, so treat that combination as documented rather than verified here.

What a real run looked like

I ran the request above (text-only, 720p, 9:16, 4 seconds).

  • Generation time: the task was in handling for about 283 seconds, then archiving for roughly 10 seconds. Plan for minutes, not seconds, even for a 4-second clip. Poll every 10 seconds or use a callback rather than a short timeout.
  • Output file: an MP4 at 720x1280, H.264 video at 24 fps plus an AAC audio track, 4.04 seconds long. Audio was present although the request had no audio field, which fits the model's native-sound design.
  • Temporary URL: the output URL is on temp.hiapi.ai and carries an expireAt about 7 days out. Download the file and store it yourself instead of linking it from a page.
  • Cost shape: billing is per second and depends on resolution (see the pricing page), so the cheapest way to iterate on a prompt is 720p with a short duration, then re-render the keeper at 1080p or 2k.

Gotchas I hit

  • Bad values fail fast and free. Sending aspect_ratio: "7:5", duration: 25 or resolution: "4k" each returned HTTP 400 INVALID_REQUEST with a message naming the allowed values ('auto', '16:9', '9:16', '1:1', '4:3', '3:4', a maximum of 20, and '720p', '1080p', '2k'). Use that to validate your own form before submitting.
  • Bad media URLs fail later, at poll time. I submitted audio_url: "https://example.com/a.mp3" (not a real audio file). The create call returned HTTP 200 with a task id, and about 15 seconds later the task ended with status: "fail" and error.code: "INVALID_REQUEST". So a 200 on create does not mean your media was usable; always check the terminal status and read data.error. In that case the failure is surfaced inside an HTTP 200 poll response, not as an HTTP error.
  • Failure is status: "fail", not an HTTP status. The poll request itself returns 200, so check data.status.

FAQ

Do I need separate model ids for text, image and audio input? No. All three use creatify-boreal; the fields you include in input decide the mode.

How long can a clip be? Whole seconds from 1 to 20. A value of 25 is rejected with HTTP 400.

Does the output include sound? Yes. The 4-second test clip had an AAC audio track even though no audio input was supplied.

Which resolutions are available? 720p, 1080p and 2k. Billing differs by resolution; check the pricing page.

How long should I wait? My 4-second 720p test took about five minutes end to end. Use polling with a generous limit or a callback.

Generate it with HiAPI

Choose a model, enter your prompt, and see the result.

HiAPI Blog

Related articles

HiAPI

Generate it with HiAPI

Start generating