HiAPI
  • Models
  • Pricing
Search

Search HiAPI models, tools, and resources.

  • Models
  • Pricing
HiAPI

One API, All AI Models

Generate images, video, and audio with leading models through one production-ready API.

Get a free API key

AI Image API

  • All image models
  • GPT Image 2
  • Nano Banana 2
  • Seedream 5.0 Pro
  • Qwen Image 2.0 Pro
  • FLUX 1.1 Pro

AI Video API

  • All video models
  • Seedance 2.5
  • FLUX.3 Video
  • Seedance 2.0
  • Veo 3.1
  • Kling 3.0

AI Audio API

  • All audio models
  • MiniMax Music 2.6
  • MiniMax Music 1.5
  • ElevenLabs v3
  • Text to music
  • Text to speech

Product

  • Model marketplace
  • Playground
  • Pricing
  • Image API Cost Calculator
  • Free GPT Image 2 Generator
  • Free Nano Banana Image Generator
  • Outfit Preview
  • Product Photo Lab

Developers

  • Documentation
  • API Reference
  • Agent Skills
  • LLM integration index
  • Blog

Company

  • About
  • Contact support
  • Terms of Service
  • Privacy Policy

© 2026 hiapi. All rights reserved.

Open source on GitHubPython SDK on PyPI
  • 1. Prerequisites
  • 2. Minimal runnable example
  • 2.1 Create the task (curl)
  • 2.2 Poll for the result
  • 2.3 The same flow in Python
  • 3. First-last frame control
  • 4. Production patterns
  • Use a callback instead of polling
  • Duration and resolution limits
  • Idempotency
  • Handling auth errors
  • 5. Related pages
  • FAQ
TutorialAug 10, 20266 min read

Seedance 2.5 Image-to-Video API: A Working curl and Python Example

First-last frame control, async task polling, and callbacks — with copy-pasteable curl and Python.

hiapiseedancevideo-apitutorialasync-tasks

Latest models

Explore models

Contents
  • 1. Prerequisites
  • 2. Minimal runnable example
  • 2.1 Create the task (curl)
  • 2.2 Poll for the result
  • 2.3 The same flow in Python
  • 3. First-last frame control
  • 4. Production patterns
  • Use a callback instead of polling
  • Duration and resolution limits
  • Idempotency
  • Handling auth errors
  • 5. Related pages
  • FAQ

Generate it with HiAPI

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

HiAPI Blog

Related articles

HiAPI

Generate it with HiAPI

Turn a still image into a short clip with hiapi's seedance-2.5/image-to-video model — first-last frame control, async task polling, and callbacks, with copy-pasteable curl and Python.

1. Prerequisites

  • A hiapi account and an API key (sk-...) from the API Keys dashboard.
  • A publicly reachable URL for your starting frame image (and, optionally, a second URL for the ending frame).
  • curl, or Python 3 with requests installed (pip install requests).

Every generation model on hiapi runs through one unified endpoint, POST /v1/tasks. seedance-2.5/image-to-video is called exactly like every other model on the platform — same auth header, same async task lifecycle, only model and input change. Note that seedance-2.5/image-to-video (with the /image-to-video suffix) is the full, correct model id for this model family — it's not an optional modality tag you can drop.

2. Minimal runnable example

2.1 Create the task (curl)

curl -s -X POST https://api.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer sk-<your-api-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "seedance-2.5/image-to-video",
    "input": {
      "prompt": "the boat drifts forward slowly, camera holds steady",
      "first_frame_url": "https://your-cdn.example.com/start-frame.jpg",
      "duration": 5,
      "resolution": "720p"
    }
  }'

A successful call returns a task id immediately — generation itself happens asynchronously:

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

2.2 Poll for the result

curl -s https://api.hiapi.ai/v1/tasks/tk-hiapi-01XXXXXXXXXXXXXXXXXXXXXXXX \
  -H "Authorization: Bearer sk-<your-api-key>"

While the clip is rendering, status is "handling". Once it finishes:

{
  "code": 200,
  "data": {
    "taskId": "tk-hiapi-01XXXXXXXXXXXXXXXXXXXXXXXX",
    "model": "seedance-2.5/image-to-video",
    "status": "success",
    "storage": "temp",
    "created": 1786327257,
    "completed": 1786327396,
    "output": [
      {"artifactId": "72582", "type": "video", "url": "https://temp.hiapi.ai/.../result.mp4", "expireAt": 1786932195}
    ]
  },
  "message": "success"
}

output[0].url is a temporary, expiring link — expireAt is a Unix timestamp. Download or re-host the clip right away; don't store the hot link.

2.3 The same flow in Python

import time
import requests

API_KEY = "sk-<your-api-key>"
BASE = "https://api.hiapi.ai/v1"
HEADERS = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}


def create_task(prompt, first_frame_url, duration=5, resolution="720p", last_frame_url=None):
    payload = {
        "model": "seedance-2.5/image-to-video",
        "input": {
            "prompt": prompt,
            "first_frame_url": first_frame_url,
            "duration": duration,
            "resolution": resolution,
        },
    }
    if last_frame_url:
        payload["input"]["last_frame_url"] = last_frame_url
    resp = requests.post(f"{BASE}/tasks", headers=HEADERS, json=payload, timeout=30)
    resp.raise_for_status()
    return resp.json()["data"]["taskId"]


def wait_for_result(task_id, interval=5, timeout=600):
    deadline = time.time() + timeout
    while time.time() < deadline:
        resp = requests.get(f"{BASE}/tasks/{task_id}", headers=HEADERS, timeout=30)
        resp.raise_for_status()
        data = resp.json()["data"]
        if data["status"] == "success":
            return data["output"][0]["url"]
        if data["status"] == "failed":
            raise RuntimeError(f"task {task_id} failed: {data}")
        time.sleep(interval)
    raise TimeoutError(f"task {task_id} did not finish in {timeout}s")


task_id = create_task(
    prompt="the boat drifts forward slowly, camera holds steady",
    first_frame_url="https://your-cdn.example.com/start-frame.jpg",
)
video_url = wait_for_result(task_id)
print(video_url)

3. First-last frame control

Add last_frame_url alongside first_frame_url to pin down both ends of the clip — hiapi interpolates the motion in between:

{
  "model": "seedance-2.5/image-to-video",
  "input": {
    "prompt": "smooth dolly-in, soft daylight",
    "first_frame_url": "https://your-cdn.example.com/start-frame.jpg",
    "last_frame_url": "https://your-cdn.example.com/end-frame.jpg",
    "duration": 6,
    "resolution": "720p"
  }
}

Two things worth knowing here, both confirmed against the live schema:

  • last_frame_url only works together with first_frame_url — you can't specify only the last frame.
  • aspect_ratio on this model only accepts the value "adaptive". Unlike text-to-video models where you pick "16:9" or "9:16" explicitly, an image-to-video clip always inherits its aspect ratio from first_frame_url and can't be overridden — crop or pad your source image to the ratio you want before calling the API.

4. Production patterns

Use a callback instead of polling

For anything beyond a one-off script, don't poll — register a callback and let hiapi push the result to you:

{
  "model": "seedance-2.5/image-to-video",
  "input": { "...": "..." },
  "callback": { "url": "https://your-server.example.com/hiapi/callback", "when": "final" }
}

callback sits next to input, not inside it. when currently only accepts "final" — you'll get exactly one POST when the task reaches a terminal state (success or failed), not incremental progress events.

Duration and resolution limits

  • duration: integer, 4–30 seconds.
  • resolution: "480p" or "720p" only.

Values outside these ranges are rejected before any generation starts, so validate client-side and you'll never pay for a request that was going to fail anyway.

Idempotency

The task API doesn't take a client-supplied idempotency key — every POST /v1/tasks call creates a new task and, for a paid model, a new charge. If a request times out on your end, check whether you already captured a taskId from that attempt and poll or wait on the callback for it instead of blindly re-submitting the same request.

Handling auth errors

An invalid or under-permissioned key fails synchronously, before any task is created:

HTTP 401
{"error":{"code":"permission_denied","message":"This API key cannot use the selected model. Please check permissions or use another key. If the issue persists, contact support with request ID: <id>","request_id":"<id>","type":"hiapi_error"}}

Treat permission_denied as: wrong or revoked key, or a key scoped without access to seedance-2.5/image-to-video — check both in the API Keys dashboard before assuming your request body is wrong.

5. Related pages

  • seedance-2.5/image-to-video model page — current status and supported modes.
  • Pricing — this model bills per output second; check the live table for the current rate.
  • API docs
  • seedance-2.5 vs seedance-2.0 — when to reach for this model instead of the text-to-video one.
  • seedance-2.0 API guide — same task lifecycle, text-to-video instead of image-to-video.

FAQ

Do I need both first_frame_url and last_frame_url? No. first_frame_url alone gives you standard image-to-video. Add last_frame_url only when you also want to pin the ending frame — it requires first_frame_url to be set.

Can I set a 16:9 or 9:16 aspect ratio? No — aspect_ratio only accepts "adaptive" for this model. Prepare your first_frame_url image at the aspect ratio you want the output in.

Why did I get a 401 with a valid-looking key? permission_denied means the key exists but isn't authorized for this specific model. Check your key's model access in the dashboard, not just whether the key itself is valid.

How long can a clip be? duration accepts any integer from 4 to 30 seconds.

Is there a synchronous version of this endpoint? No — every model on hiapi, including this one, runs through the same async POST /v1/tasks → poll or callback pattern. There's no synchronous image-to-video call.

What happens to the output URL if I don't download it right away? output[0].url expires — expireAt in the response is a Unix timestamp. Download the clip or re-host it to your own storage as soon as the task completes.

Latest models

View all models
  • GPT Image 2From $0.007/image
  • Nano Banana 2From $0.051/image
  • Seedream 5.0 ProFrom $0.050/image
  • Seedance 2.5From $0.121/s

Explore models

TextImageVideoAudio
Back to blog
GPT Image 2From $0.007/image
Nano Banana 2From $0.051/image
Seedream 5.0 ProFrom $0.050/image
Seedance 2.5From $0.121/s
View all models
TextChat and reasoning
ImageGenerate and edit
VideoText and image to video
AudioSpeech and music
Start generating
View model pricing
View all articles
How to Use the flux-3 API for Text-to-Video, Audio, and Continuation

How to Use the flux-3 API for Text-to-Video, Audio, and Continuation

minimax-music-3 API: curl & Python Guide

minimax-music-3 API: curl & Python Guide

How to use grok-imagine-image-2.0/image-to-image via the hiapi API: curl, Python, and a working request

How to use grok-imagine-image-2.0/image-to-image via the hiapi API: curl, Python, and a working request

How to Use grok-imagine-image-2.0/text-to-image via the hiapi API: curl, Python, and a Working Request

How to Use grok-imagine-image-2.0/text-to-image via the hiapi API: curl, Python, and a Working Request

How to Use the qwen-image-3.0 API: curl, Python, and a Working Request

How to Use the qwen-image-3.0 API: curl, Python, and a Working Request

How to Use qwen-image-3.0-pro via the hiapi API: curl, Python, and a Working Request

How to Use qwen-image-3.0-pro via the hiapi API: curl, Python, and a Working Request

Start generating