Azimo
  1. 首页
  2. 开发者
  3. 进阶用法

指南

进阶用法

Webhook、批量制作、幂等重试、分页和错误处理。

把本页以 Markdown 复制到剪贴板,附带 Azimo 的基本信息,可直接粘贴给 AI 助手。查看 Markdown

接入正式环境前需要了解的几件事:Webhook、安全重试、错误处理、限流、项目与权限、预算批准、修改版本和删除文件。

完整的接口和字段见 API 参考,这里只讲怎么用。

用 Webhook 接收结果

不想轮询,就登记一个回调地址。视频状态每次变化,Azimo 都会 POST 一个事件过来。登记需要 owner 角色的 Key:

curl -s https://azimo.ai/v1/webhooks \
  -H "Authorization: Bearer $AZIMO_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: webhook-001" \
  -d '{"url": "https://example.com/hooks/azimo", "name": "Production updates"}'

返回里的 signing_secret(以 whsec_ 开头)只显示这一次,请保存好。

事件长这样,type 是 video. 加上状态,例如 video.progress、video.needs_input、video.complete、video.rejected、video.failed、video.cancelled:

{"id": "d8009f54780243ea", "sequence": 12, "type": "video.complete", "api_version": "v1", "project_id": "c56eb945e4464aec", "created_at": 1790000000, "data": {"id": "b6bf4689035d474f", "status": "complete", "stage": "complete", "progress": 100}}

每个请求带两个头:Vidgen-Event-Id(事件 ID)和 Vidgen-Signature: t=<时间戳>,v1=<签名>。签名是 HMAC-SHA256(signing_secret, "<时间戳>." + 原始请求体) 的十六进制。一定要对收到的原始字节验签,不要先解析 JSON 再序列化:

import hashlib, hmac, time

def verify(secret: str, header: str, body: bytes, tolerance: int = 300) -> bool:
    try:
        parts = dict(item.split("=", 1) for item in header.split(","))
        timestamp = int(parts["t"])
    except (KeyError, ValueError):
        return False
    if abs(time.time() - timestamp) > tolerance:  # 拒绝 5 分钟以前的请求
        return False
    expected = hmac.new(secret.encode(), f"{timestamp}.".encode() + body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, parts.get("v1", ""))

Python SDK 自带同样的函数 Vidgen.verify_webhook(secret, header, body),TypeScript SDK 是 Vidgen.verifyWebhook(secret, header, body)。

收到事件后:

  • 验签通过就尽快返回 2xx,耗时的处理放到自己的队列里。
  • 投递失败会自动重试,最长持续约 72 小时,所以同一个事件可能到达多次:请按事件 id 去重。
  • 事件不保证按顺序到达。拿不准时,用 GET /v1/videos/{id} 查最新状态。
  • 以后可能增加新的事件类型,遇到不认识的 type 直接忽略即可。
  • 下载链接会过期;需要时重新查询视频,拿新链接。

也可以只给某一条视频设回调:在 POST /v1/videos 里加 webhook_url,响应里的 webhook_signing_secret 就是验签用的密钥。不用 Webhook 的话,可以用 GET /v1/events?after=<sequence> 按顺序拉取事件。

安全重试:Idempotency-Key

所有创建类的 POST(上传、方案、制作、修改、取消、回答、Webhook 等)都接受请求头 Idempotency-Key,长度 1–128 个字符。

  • 同一个 Key、同样的请求体:返回第一次的结果,不会再做一次。
  • 同一个 Key、不同的请求体:返回 409,错误码 idempotency_conflict。
  • 换一个新 Key:就是一个新请求。对同一个方案换 Key 再提交,会再做一条视频。

做法:在发请求前生成 Key,和你的业务记录一起保存;超时或断线后,用同一个 Key 重试。

处理错误

所有错误都是同一种格式:

{"error": {"code": "validation_error", "message": "request validation failed", "details": [{"loc": ["body", "options", "duration_max"], "msg": "Input should be less than or equal to 180", "type": "less_than_equal"}], "request_id": "64ceb19e540b438f8b9a4df3bfe62ba7"}}

按 code 判断,不要按 message 的文字判断。每个响应都有 X-Request-ID 头;联系我们时请附上 request_id。

HTTPcode怎么办
401unauthenticatedKey 缺失、错误或已撤销,换一把有效的 Key
402insufficient_balance / budget_exceeded余额不足或达到额度上限;充值或联系 sales@azimo.ai,不要反复重试
403forbidden角色或项目不允许,例如 read-only key
403contact_sales与价格相关的请求,请联系 sales@azimo.ai
404not_foundID 不存在,或不在当前项目里
409conflict / idempotency_conflict状态不允许(例如视频已结束),或 Key 被用于不同的请求
413payload_too_large / storage_quota_exceeded文件超过 60 MB,或存储空间已满,删掉不用的素材
415unsupported_media_type不支持的文件类型
422validation_error请求字段不对,details 列出具体问题
429rate_limited请求太频繁,按 Retry-After 等待后重试
500internal_error我们这边出错,带上 request_id 联系我们
503backend_unconfigured这个工作流暂时不可用

限流与 429

  • 每把 Key 默认每分钟最多 600 次 API 请求。
  • 每个组织每小时能开始的制作数量有上限;Key 也可以单独设更低的上限。
  • 超出时返回 429,响应头 Retry-After 是需要等待的秒数。

Python SDK 会对 GET 和带 Idempotency-Key 的 POST 自动重试 429 和 5xx,并遵守 Retry-After。轮询视频状态时,每 10 秒左右一次就够了。

项目与 Key 的角色

资源(素材、方案、视频、Webhook)都属于某个项目。请求头 X-Project-ID 选择项目,不传就用默认项目。组织 owner 可以用 POST /v1/projects 新建项目,用 POST /v1/api-keys 创建 Key 并指定 role 和 project_id。

角色能做什么
viewer只读:查看视频、方案、素材、事件和余额
editor另外可以上传、创建方案、开始制作、取消、回答和修改
owner(绑定项目)另外可以管理本项目的 Webhook
owner(不绑定项目)组织 owner:管理所有项目和 Key

每个应用或客户端单独用一把 Key,按最小权限选择角色。

预算批准

制作过程中如果要超出这条视频的花费上限,视频会暂停在 needs_input,result.input_required 是:

{"code": "budget_approval", "actor": "customer", "message": "…", "approvable": true}

同意继续,就回答:

curl -s https://azimo.ai/v1/videos/b6bf4689035d474f/resume \
  -H "Authorization: Bearer $AZIMO_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: approve-b6bf-001" \
  -d '{"approve_budget": true}'

SDK 是 azimo.approve_budget(video_id),命令行是 azimo resume ID --approve-budget。批准后仍然需要余额足够,否则返回 402;已经完成的步骤不会重做。

其他 needs_input 用文字回答:{"message": "..."},需要补资料时加上 "assets": ["<素材 ID>"]。长时间不回应(默认 7 天)的视频会自动取消。

修改版本

对已结束的视频(complete、rejected、failed、cancelled 或 needs_input)可以做一个修改版:

curl -s https://azimo.ai/v1/videos/b6bf4689035d474f/revisions \
  -H "Authorization: Bearer $AZIMO_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: revise-b6bf-001" \
  -d '{"prompt": "完整的新 brief:同样的产品,结尾强调一次能烧两杯水。", "options": {"subtitles": true}}'
  • 返回一条新视频,parent_id 指向原视频,原视频保留不变。
  • prompt 会整体替换原来的 brief,请写完整;options 只改你传的字段;assets 不传就沿用原来的素材(原素材已删除时会返回 404,这时请重新上传并传 assets)。
  • 修改版是一次完整的新制作,会使用余额。视频还在制作中时返回 409。

取消与删除文件

  • 取消:POST /v1/videos/{id}/cancel。排队或等待中的视频立即取消;正在制作的会在下一步开始前停下。取消的视频按已经花掉的用量收费。
  • 质检不过不收费:以 rejected(未通过质检)或 failed(系统未能完成)结束的视频不扣余额,冻结额度全部退回,钱包流水里有一条金额为 0 的 settle 记录说明原因。
  • 删除素材:DELETE /v1/assets/{id}。已经用它做好的视频不受影响,但之后基于这条视频做修改版时要重新提供素材。
  • 删除视频文件:DELETE /v1/videos/{id},只能删已结束的视频(先取消)。成片、字幕和封面会被清除,下载链接失效,视频记录保留。
  • 品牌、模板和 Webhook 也可以用 DELETE 删除。
  • 成片只保留一段时间,请及时下载保存。
反馈