seedance-2.5/reference-to-video generates a new clip guided by one or more existing video clips — plus optional reference images and audio — instead of starting from a blank prompt or a single still frame. Feed it footage of a character, a set, or a camera move and a text prompt, and it produces new video that follows those references. This guide has a copy-pasteable curl and Python example, the exact input schema, pricing, and the errors you'll actually hit.
1. Prerequisites
- A hiapi account and an API key (
sk-...) from the API Keys dashboard. - At least one publicly reachable URL for a reference video (
.mp4). Optionally, URLs for a reference image and/or reference audio. - curl, or Python 3 with
requestsinstalled (pip install requests).
Every generation model on hiapi runs through the same unified endpoint, POST /v1/tasks. seedance-2.5/reference-to-video is called exactly like every other model — same auth header, same async task lifecycle — only model and input change. The model id is seedance-2.5/reference-to-video, with the /reference-to-video suffix; it is not an optional modality tag.
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/reference-to-video",
"input": {
"prompt": "the same character walks through a rain-lit street, neon reflections on wet pavement",
"reference_video_urls": ["https://your-cdn.example.com/reference-clip.mp4"],
"duration": 4,
"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/reference-to-video",
"status": "success",
"storage": "temp",
"created": 1786327257,
"completed": 1786327501,
"output": [
{"artifactId": "72583", "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, reference_video_urls, duration=4, resolution="720p", aspect_ratio=None):
payload = {
"model": "seedance-2.5/reference-to-video",
"input": {
"prompt": prompt,
"reference_video_urls": reference_video_urls,
"duration": duration,
"resolution": resolution,
},
}
if aspect_ratio:
payload["input"]["aspect_ratio"] = aspect_ratio
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 same character walks through a rain-lit street, neon reflections on wet pavement",
reference_video_urls=["https://your-cdn.example.com/reference-clip.mp4"],
)
video_url = wait_for_result(task_id)
print(video_url)
3. Multimodal references: video, image, and audio together
reference_video_urls is the only required reference field (an array, minimum one URL — you can pass more than one clip). On top of it you can layer:
reference_image_urls— additional still-image references (array).reference_audio_urls— reference audio, for matching a voice or sound character (array).
{
"model": "seedance-2.5/reference-to-video",
"input": {
"prompt": "same character and voice, now standing on a rooftop at sunset",
"reference_video_urls": [
"https://your-cdn.example.com/reference-clip-1.mp4",
"https://your-cdn.example.com/reference-clip-2.mp4"
],
"reference_image_urls": ["https://your-cdn.example.com/character-ref.jpg"],
"reference_audio_urls": ["https://your-cdn.example.com/voice-ref.mp3"],
"duration": 6,
"resolution": "720p",
"aspect_ratio": "9:16"
}
}
A reference input doesn't have to be freshly generated — any video, image, or audio file you already host at a public URL works. If you already have footage of the character or scene you want to keep consistent, point reference_video_urls at that instead of generating a new reference clip first.
aspect_ratio
aspect_ratio accepts one of: 16:9, 4:3, 1:1, 3:4, 9:16, 21:9, adaptive. This is a real, settable enum on this model — unlike some other Seedance modes, it is not locked to a single value.
Fields that don't exist on this model
The input schema is strict (additionalProperties: false) — sending any of these gets rejected before generation starts: seed, negative_prompt, ratio (use aspect_ratio), fps, audio_urls / image_urls (use the reference_-prefixed names).
4. Production patterns
Duration, resolution, and pricing
duration: integer,4–30seconds.resolution:"480p"or"720p".- Pricing is $0.2714 per output second at 720p, flat regardless of how many reference inputs you attach. A minimal 4-second clip costs $1.09 — check pricing for the current rate before batching requests, since this is a video-tier cost, not an image-tier one.
Use a callback instead of polling
{
"model": "seedance-2.5/reference-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" — one POST when the task reaches a terminal state (success or failed), not incremental progress. If your callback endpoint isn't receiving that POST, check why hiapi task callbacks don't fire before assuming the task itself failed.
Idempotency
POST /v1/tasks doesn't take a client-supplied idempotency key — every call creates a new task and, for a paid model like this one, a new charge. If a request times out on your end, check whether you already captured a taskId from that attempt before retrying, rather than resubmitting blindly.
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"}}
permission_denied means the key exists but isn't authorized for seedance-2.5/reference-to-video specifically — check model access in the API Keys dashboard before assuming the request body is wrong.
5. Related pages
- seedance-2.5/reference-to-video model page
- Create Task docs and Authentication docs
- Pricing
- HappyHorse 1.1 reference-to-video API tutorial — a second reference-to-video model, useful for comparison.
- Seedance 2.5 vs Seedance 2.0 — where reference-to-video fits in the 2.5 lineup.
FAQ
Do I need a reference video, or can I use just an image?
reference_video_urls is required — at least one video URL. reference_image_urls and reference_audio_urls are additive, not substitutes.
Can I pass more than one reference video?
Yes, reference_video_urls is an array and accepts multiple clips.
What aspect ratios are supported?
16:9, 4:3, 1:1, 3:4, 9:16, 21:9, or adaptive.
Why did my request fail with a schema error even though the field name looked right?
The schema is strict and rejects unknown fields outright — common mistakes are sending seed, ratio instead of aspect_ratio, or image_urls/audio_urls instead of the reference_-prefixed names.
How much does a single clip cost? $0.2714 per output second at 720p — a 4-second clip is about $1.09. There's no separate cheaper tier for shorter clips.
Why did I get a 401 with a key I know is valid?
permission_denied means the key isn't scoped for this model, not that the key itself is invalid. Check the key's model permissions in the dashboard.








