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, read Retry-After and wait.
  • On 401, check whether the key is disabled or revoked.
  • For reference media, presign upload first and pass IDs in ref_media_ids.