教程
如何通过 hiapi API 使用 veo-3.1-lite/text-to-video:curl、Python 与一个可运行的请求
veo-3.1-lite/text-to-video 仅凭一段文本提示词即可生成短视频片段——无需起始图像。本指南提供了针对真实 hiapi 任务 API 的可直接复制粘贴的 curl 与 Python 示例、精确的输入 schema(已对照线上端点确认),以及你在生产环境中实际会遇到的错误形态。
1. 前提条件
- 一个 hiapi 账号,以及从 API Keys 仪表盘 获取的 API key(
sk-...)。 - curl,或已安装
requests的 Python 3(pip install requests)。 - 无需其他东西——
text-to-video只需要一个提示词字符串。
hiapi 上的每个生成模型都通过同一个 统一的异步任务 API 运行:POST /v1/tasks 创建任务,然后轮询或等待回调来获取结果。veo-3.1-lite/text-to-video 的调用方式与其他任何视频模型完全一样——相同的认证头、相同的任务生命周期——只有 model 和 input 不同。模型 id 是 veo-3.1-lite/text-to-video,带有 /text-to-video 后缀;同一系列还提供了 veo-3.1-lite/image-to-video,这是一个独立的模型 id,用于改为对源图像做动画。
2. 最小可运行示例
2.1 创建任务(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": "veo-3.1-lite/text-to-video",
"input": {
"prompt": "a paper boat drifting down a rain-slicked city street at night, neon signs reflecting on wet asphalt",
"duration": 6,
"resolution": "720p",
"aspect_ratio": "16:9",
"generate_audio": true
}
}'
调用成功后立即返回一个任务 id——生成是异步进行的:
{"code":200,"data":{"taskId":"tk-hiapi-01XXXXXXXXXXXXXXXXXXXXXXXX"},"message":"success"}
2.2 轮询结果
curl -s https://api.hiapi.ai/v1/tasks/tk-hiapi-01XXXXXXXXXXXXXXXXXXXXXXXX \
-H "Authorization: Bearer sk-<your-api-key>"
片段渲染期间,status 为 "handling"。完成后:
{
"code": 200,
"data": {
"taskId": "tk-hiapi-01XXXXXXXXXXXXXXXXXXXXXXXX",
"model": "veo-3.1-lite/text-to-video",
"status": "success",
"storage": "temp",
"output": [
{"artifactId": "...", "type": "video", "url": "https://temp.hiapi.ai/.../result.mp4", "expireAt": 1786932195}
]
},
"message": "success"
}
output[0].url 是一个临时的、会过期的链接——请在 expireAt 过期之前下载文件(或将输出转为持久存储)。
2.3 完整的 Python 示例
import time
import requests
API_KEY = "sk-<your-api-key>"
BASE = "https://api.hiapi.ai/v1/tasks"
HEADERS = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}
def create_task(prompt: str) -> str:
resp = requests.post(BASE, headers=HEADERS, json={
"model": "veo-3.1-lite/text-to-video",
"input": {
"prompt": prompt,
"duration": 6,
"resolution": "720p",
"aspect_ratio": "16:9",
},
}, timeout=30)
resp.raise_for_status()
return resp.json()["data"]["taskId"]
def wait_for_result(task_id: str, poll_seconds: int = 5, timeout_seconds: int = 600) -> str:
deadline = time.time() + timeout_seconds
while time.time() < deadline:
resp = requests.get(f"{BASE}/{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(poll_seconds)
raise TimeoutError(f"task {task_id} did not finish in {timeout_seconds}s")
if __name__ == "__main__":
tid = create_task("a paper boat drifting down a rain-slicked city street at night")
video_url = wait_for_result(tid)
print(video_url)
3. 输入 schema
以下所有字段都位于 input 之下。该 schema 是严格的——发送一个不存在的字段会返回 400(additional properties '<field>' not allowed),这是在渲染之前快速校验请求的好方法。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
prompt |
string | 是 | 场景描述;请具体说明主体、运动和镜头行为。 |
duration |
integer | 否 | 4、6、8 之一(秒)。 |
resolution |
string | 否 | "720p" 或 "1080p"。 |
aspect_ratio |
string | 否 | "16:9" 或 "9:16"。 |
generate_audio |
boolean | 否 | 在渲染中包含同步的环境/音效音频。 |
negative_prompt |
string | 否 | 要让渲染避开的内容元素。 |
seed |
integer | 否 | 固定值,用于在重试之间复现相同的构图/运动。 |
更长的时长和更高的分辨率都会增加渲染成本——在扩大批量任务规模之前,请查看 价格页面 上的当前按模型计费价格。
4. 生产环境模式
在规模化场景下优先使用回调而非轮询
对于一次性脚本之外的任何场景,请注册回调,而不是在循环中轮询:
{
"model": "veo-3.1-lite/text-to-video",
"input": {"prompt": "..."},
"callback": {"url": "https://your-app.example.com/webhooks/hiapi", "when": "final"}
}
callback.url 必须是可访问的 http(s) URL,且 when 只接受 "final"——hiapi 会在任务达到终态(success 或 failed)时 POST 一次。这样可以避免把请求配额浪费在轮询循环上,并在结果就绪的瞬间拿到它,这对视频更重要(渲染时间比图像生成更长)。
幂等性与重试
如果你的任务运行器可能重试提交(崩溃、超时、重新部署),请在发起请求之前,将自己的幂等键与返回的 taskId 一起记录,这样重试时可以检查“我是否已经提交过这个?”,而不是创建一个重复渲染并为此付两次钱。
错误处理
实践中会出现两种不同的错误形态:
- 输入有误(
400)——请求体的校验错误:{"code":400,"data":null,"error_code":"INVALID_REQUEST","message":"invalid input: prompt: missing required field \"prompt\""} - 认证/权限失败(
401)——密钥缺失、无效或权限不足:{"error":{"code":"permission_denied","message":"This API key cannot use the selected model...","request_id":"...","type":"hiapi_error"}}
先根据 HTTP 状态码分支处理,再检查响应体——400 几乎总意味着字段名或值有误(修正请求),而 401 意味着密钥本身需要处理(仪表盘权限或新密钥)。
5. 相关页面
- veo-3.1-lite/text-to-video 模型页面——实时价格,以及可在接入代码前测试提示词的浏览器内 playground。
- veo-3.1-lite/image-to-video 模型页面——以图像为条件的姊妹模型,用于对现有画面做动画,而不是从文本开始。
- 统一异步 API 简介——hiapi 上每个模型(图像、视频、音频)共享的任务生命周期。
- 认证文档——API key 格式与请求头细节。
- seedance-2.5/text-to-video API 指南——同一任务 API 上的第二个文本生视频模型,可用于对比 schema 和价格。
常见问题
veo-3.1-lite/text-to-video 需要起始图像吗?
不需要。它完全根据 prompt 字符串生成。如果你有要制作动画的源图像,请改用独立的 veo-3.1-lite/image-to-video 模型 id。
支持哪些分辨率和时长?
resolution 为 "720p" 或 "1080p";duration 为 4、6 或 8 秒。发送任何其他值都会返回 400,并列出允许的取值集合。
生成的片段能带音频吗?
可以——在 input 中设置 "generate_audio": true,即可包含同步的环境/音效音频。
如何避免在循环中轮询?
传入一个 callback 对象,包含你的 webhook url 和 "when": "final"。任务完成后 hiapi 会向该 URL 发起 POST,而不需要你定时重新检查 GET /v1/tasks/<id>。
为什么我的请求返回 401 而不是 400?
401 且 error_code/code 为 "permission_denied" 表示 API key 本身无效或没有该模型的访问权限——请检查 API Keys 仪表盘。400 表示对于一个本身有效的 key,请求体格式有误。
返回的视频 URL 是永久的吗?
不是——output[0].url 是带有 expireAt 时间戳的临时链接。请在过期前下载或将其转为持久存储。