HiAPI
博客

教程

通过 HiAPI 调用 HappyHorse 1.1 文生视频 API:一份可用的 curl + Python 教程

2026年11月3日
通过 HiAPI 调用 HappyHorse 1.1 文生视频 API:一份可用的 curl + Python 教程
模型
happyhorse-1.1

HappyHorse 1.1 是阿里巴巴的文生视频模型:支持 720p / 1080p 视频片段,时长 3–15 秒,一次调用即可生成原生音频(无需单独的配乐步骤)。HiAPI 通过与其他所有生成式模型相同的统一异步端点对外提供该模型,因此如果你已经在 /v1/tasks 上调用过图像模型,那么唯一变化的就是模型 id 和几个 input 字段。

本页提供交付一个可用集成所需的最小内容:确切的 schema、可直接复制的 curl、一个 Python 轮询客户端,以及生产环境的回调模式。它还特别指出了两件不太明显、模型并不接受的事情(一个 audio 开关和一个 seed),这样你就不会因为一个 400 而白白浪费一次请求。

前置条件。 从 HiAPI 控制台 获取一个密钥,并将其导出为 HIAPI_API_KEY。每个请求都通过 Authorization: Bearer sk-… 进行认证;如需回顾,请参阅 Authentication。

端点与请求结构

一切都通过同一个端点:

POST https://api.hiapi.ai/v1/tasks
Authorization: Bearer sk-<your-key>
Content-Type: application/json

请求体有三个顶层键:

  • model — happyhorse-1.1/text-to-video(字面模型 id — 斜杠要保留)。
  • input — 模型特定字段。对于 HappyHorse 1.1 T2V:
    • prompt(字符串,必填)— 描述视频片段。
    • resolution(720p | 1080p,默认 1080p)。
    • aspect_ratio(16:9 | 9:16 | 3:4 | 4:3 | 4:5 | 5:4 | 1:1 | 9:21 | 21:9,默认 16:9)。
    • duration(整数,3–15,默认 5)。费用随秒数增加。
  • callback(可选,对象)— callback.url HTTPS 端点 + callback.when: "final"。HiAPI 会为每个任务向该地址恰好 POST 一次最终结果。

两件看起来应该可用但实际上不可用的事情:

  • ❌ 没有 audio 字段。 音频随视频原生生成;没有开关。发送 "audio": true 会返回 additional properties 'audio' not allowed。
  • ❌ 没有 seed 字段。 同样返回 400。如果你现在需要批次确定性,就生成多个版本再挑选——没有可调整的 seed 杠杆。

一个最小的有效请求体:

{
  "model": "happyhorse-1.1/text-to-video",
  "input": {
    "prompt": "A golden retriever running on a beach, slow motion, gentle waves, warm sunset tones",
    "resolution": "1080p",
    "aspect_ratio": "16:9",
    "duration": 5
  }
}

最小可运行示例:curl

创建任务——响应立即返回,且只包含一个 taskId:

curl -sS -X POST https://api.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "happyhorse-1.1/text-to-video",
    "input": {
      "prompt": "A snow mountain lake in morning mist, slow camera push-in, warm cinematic light",
      "resolution": "1080p",
      "aspect_ratio": "16:9",
      "duration": 5
    }
  }'
# => {"code":200,"data":{"taskId":"tk-hiapi-01KW3..."},"message":"success"}

然后轮询直到进入终态:

TASK_ID=tk-hiapi-01KW3...

curl -sS "https://api.hiapi.ai/v1/tasks/$TASK_ID" \
  -H "Authorization: Bearer $HIAPI_API_KEY"
# while .data.status is "handling", sleep a few seconds and retry.
# On success:
# {
#   "code": 200,
#   "data": {
#     "status": "success",
#     "model": "happyhorse-1.1/text-to-video",
#     "output": [
#       {"type":"video","url":"https://temp.hiapi.ai/.../...-0.mp4","expireAt":1783130616}
#     ],
#     ...
#   }
# }

mp4 URL 是临时的(expireAt 是一个约 7 天后的 Unix 时间戳)。任务成功后立即下载并持久化保存——不要热链。如果你更希望由 HiAPI 管理长期存储,请参阅 Output Storage 文档,了解如何将输出从临时存储提升为持久存储。

Python:一个小巧的、生产形态的客户端

一个真正的客户端需要三样东西:返回 id 的 create_task、带截止时间进行轮询的 wait_task,以及下载步骤。这个骨架包含全部三项,并且接近 HiAPI 的 Python SDK 页面 的起点——保持小巧,再从中扩展。

# pip install requests
import os, time, json, requests

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


def create_task(prompt: str, *, resolution="1080p", aspect_ratio="16:9", duration=5) -> str:
    body = {
        "model": "happyhorse-1.1/text-to-video",
        "input": {
            "prompt": prompt,
            "resolution": resolution,
            "aspect_ratio": aspect_ratio,
            "duration": duration,
        },
    }
    r = requests.post(API_BASE, headers={**HEADERS, "Content-Type": "application/json"},
                      data=json.dumps(body), timeout=60)
    r.raise_for_status()
    data = r.json()
    if data.get("code") != 200:
        raise RuntimeError(f"create failed: {data}")
    return data["data"]["taskId"]


def wait_task(task_id: str, *, timeout_s: int = 600, poll: int = 5) -> dict:
    deadline = time.time() + timeout_s
    while time.time() < deadline:
        r = requests.get(f"{API_BASE}/{task_id}", headers=HEADERS, timeout=30)
        r.raise_for_status()
        task = r.json().get("data") or {}
        status = task.get("status")
        if status == "success":
            return task
        if status == "fail":
            raise RuntimeError(f"task {task_id} failed: {task.get('error')}")
        time.sleep(poll)
    raise TimeoutError(f"task {task_id} did not finish within {timeout_s}s")


def download(url: str, path: str) -> None:
    with requests.get(url, stream=True, timeout=120) as r:
        r.raise_for_status()
        with open(path, "wb") as f:
            for chunk in r.iter_content(1 << 14):
                f.write(chunk)


if __name__ == "__main__":
    task_id = create_task(
        "A neon street at night after rain, reflections on the ground, "
        "cyberpunk mood, slow pan",
        resolution="720p", aspect_ratio="9:16", duration=5,
    )
    task = wait_task(task_id)
    url = task["output"][0]["url"]
    download(url, "out.mp4")
    print("saved out.mp4")

生产环境的一些注意事项:

  • 状态字段。 将除 success 或 fail 之外的任何值都视为进行中(平台目前使用 handling)。
  • raise_for_status 并不够。 对于某些校验错误,HiAPI 会返回 HTTP 200,但 code 不是 200——务必也检查 data["code"]。对于全新集成,最常见的是 401 permission_denied,这意味着 bearer token 错误或缺失——重新导出 HIAPI_API_KEY 并在控制台中确认。

生产环境:优先使用回调而非轮询

对于快速入门之外的任何场景,给 HiAPI 一个 webhook,让它在任务完成时调用你:

{
  "model": "happyhorse-1.1/text-to-video",
  "input": {
    "prompt": "A snow mountain lake in morning mist, slow camera push-in, warm cinematic light",
    "resolution": "1080p",
    "aspect_ratio": "16:9",
    "duration": 5
  },
  "callback": {
    "url": "https://your-domain.com/hiapi/callback",
    "when": "final"
  }
}

确保你的回调处理器做到以下几点:

  • 按 taskId 去重。 success 和 fail 都是终态——你的服务应将两次收到同一个 taskId 视为无操作(以 taskId 为键的幂等写入)。
  • 快速返回 2xx。 将繁重工作(下载 mp4、持久化、通知用户)放入队列。Webhook 处理器应在几秒内确认。
  • 保留 GET /v1/tasks/:id 作为后备。 如果 webhook 丢失(部署、网络抖动),一个对账定时任务按 id 拉取卡住的任务并应用同样的处理器,是最简单的安全网。

如果你要选择一条路径:轮询适合一次性脚本和本地调试,而任何有真实流量的地方都应该用回调。

选择正确的参数(resolution × aspect_ratio × duration)

需求 resolution aspect_ratio duration
社交媒体竖屏短片,成本最低 720p 9:16 5
方形预览 / 缩略图循环 720p 1:1 3
横屏叙事 / 广告镜头 1080p 16:9 5–8
宽银幕主视觉片段 1080p 21:9 8–12

费用随分辨率和时长增加——确切的每秒定价见 HiAPI 定价。当你不确定正确的值时,就不要填:resolution 默认为 1080p,aspect_ratio 默认为 16:9,duration 默认为 5。

常见问题

HappyHorse 1.1 文生视频有 seed 参数吗? 没有。API 会以 additional properties 'seed' not allowed 拒绝 seed。如果你需要多个选项来选择,就用同一个 prompt 提交几个任务——不同的运行会自然产生差异。

如何打开或关闭音频? 你无法操作——HappyHorse 1.1 在同一次调用中原生生成音轨。schema 中没有 audio 开关;发送一个会返回 400。如果你需要无声片段,请在后期去除音频。

有效的时长是多少? 3 到 15(秒)的整数。超出该范围的任何值会返回 duration: minimum: got 0, want 3 或 duration: maximum: got 20, want 15。小数也会被拒绝(该字段类型为整数)。

它支持哪些宽高比? 九种:16:9、9:16、3:4、4:3、4:5、5:4、1:1、9:21、21:9。默认为 16:9。

output[].url 保持有效多久? 大约一周——响应中包含一个 expireAt Unix 时间戳。立即下载 mp4 并重新托管(S3、R2、你的 CDN),或通过 Output Storage API 将其提升为持久存储。

图生视频呢? HappyHorse 1.1 在同一端点上有一个 I2V 变体——请参阅 HappyHorse 1.1 I2V。相同的认证、相同的异步生命周期,不同的 input schema。

完整的异步 API 参考在哪里? 请求信封见 Create Task,轮询端点见 Get Task Detail,规范的输入 schema 见 HappyHorse 1.1 T2V 模型页面。如果你从零开始,Quickstart 会端到端地带你完成第一次调用。

立即开始构建持久 AI 产物

获取 API 密钥,通过一个基于任务(task)的 API 调用图像、视频和音频模型。

阅读 API 文档