This page is all code. Assume you already registered and created an API key starting with h3k_.
Python
Install httpx first:
pip install httpx
import time
import httpx
API = "https://api.h3hub.cn"
KEY = "h3k_your-key"
client = httpx.Client(headers={"X-API-Key": KEY})
# 1. Submit
r = client.post(f"{API}/api/v1/video/generate", json={
"prompt": "a golden retriever running in a wheat field",
"duration": 5,
"resolution": "480p",
})
r.raise_for_status()
task_id = r.json()["task_id"]
print("task:", task_id)
# 2. Poll
while True:
task = client.get(f"{API}/api/v1/task/{task_id}").json()
if task["status"] in ("completed", "failed"):
break
time.sleep(5)
if task["status"] == "failed":
raise SystemExit(f"failed: {task['error']}")
# 3. Download
with client.stream("GET", f"{API}/api/v1/result/{task_id}") as resp:
resp.raise_for_status()
with open("output.mp4", "wb") as f:
for chunk in resp.iter_bytes():
f.write(chunk)
print("saved output.mp4")
Node.js
Node 18+ with built-in fetch:
const API = "https://api.h3hub.cn";
const KEY = "h3k_your-key";
async function main() {
// 1. Submit
const gen = await fetch(`${API}/api/v1/video/generate`, {
method: "POST",
headers: { "X-API-Key": KEY, "Content-Type": "application/json" },
body: JSON.stringify({
prompt: "a golden retriever running in a wheat field",
duration: 5,
resolution: "480p",
}),
});
const { task_id } = await gen.json();
// 2. Poll
let task;
while (true) {
const resp = await fetch(`${API}/api/v1/task/${task_id}`, {
headers: { "X-API-Key": KEY },
});
task = await resp.json();
if (task.status === "completed" || task.status === "failed") break;
await new Promise((r) => setTimeout(r, 5000));
}
if (task.status === "failed") throw new Error(task.error);
// 3. Download
const video = await fetch(`${API}/api/v1/result/${task_id}`, {
headers: { "X-API-Key": KEY },
});
const buf = Buffer.from(await video.arrayBuffer());
require("fs").writeFileSync("output.mp4", buf);
console.log("saved output.mp4");
}
main().catch((err) => {
console.error(err);
process.exit(1);
});
Notes
- Poll every 5 seconds or more.
- On
429, readRetry-Afterand wait. - On
401, check whether the key is disabled or revoked. - For reference media, presign upload first and pass IDs in
ref_media_ids.