创建密钥
在开发者中心生成密钥,明文仅显示一次。
https://vi.91jiguang.com/api/v1选择模型、发起任务,然后使用返回的 generation id 轮询结果。
在开发者中心生成密钥,明文仅显示一次。
读取当前开放的模型、输入限制与参数选项。
每次 POST 都携带唯一 Idempotency-Key。
轮询任务,或在 Webhook 中接收终态事件。
curl -X POST "https://vi.91jiguang.com/api/v1/generations" \
-H "Authorization: Bearer jg_live_<key_id>_<secret>" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: product-video-20260901-001" \
-d '{
"model": "video-model-public-id",
"input": {
"prompt": "特写镜头展示商品细节,柔和影棚光"
},
"parameters": {
"duration": 5,
"aspect_ratio": "9:16"
}
}'生成是异步的。HTTP 202 代表任务已入队,不代表媒体已生成完成。
在每个业务请求的 Authorization 头中传入 API Key。
API Key 格式为 jg_live_<key_id>_<secret>。密钥与账号绑定,不要放在浏览器端代码、日志或公开仓库中。
账号同时只保留一把有效 Key。轮换后旧 Key 立即失效;轮换冷却为 1 小时,且每个北京时间自然日最多创建或轮换 5 次。
系统只保存密钥摘要。如果遗失,请重置密钥,旧密钥会立即失效。
Authorization: Bearer jg_live_<key_id>_<secret>{ "data": ..., "request_id": "req_..." }{ "error": { ... }, "request_id": "req_..." }所有响应同时携带 X-Request-Id。联系支持时请提供该值。
/models列出已开放模型只返回当前账号可调用、已启用且已完成积分定价的模型。不要在客户端硬编码供应商模型名称。
curl "https://vi.91jiguang.com/api/v1/models" \
-H "Authorization: Bearer jg_live_<key_id>_<secret>"{
"data": {
"object": "list",
"data": [
{
"id": "video-model-public-id",
"object": "model",
"name": "商品视频生成",
"type": "video",
"input": {
"prompt": { "required": true, "max_bytes": 10000 },
"images": { "max_count": 3, "required": false, "allowed_mime_types": ["image/jpeg", "image/png"] },
"videos": { "max_count": 1, "required": false, "allowed_mime_types": ["video/mp4"] }
},
"parameters": [
{ "name": "duration", "label": "时长", "type": "select", "required": true, "options": [{ "value": 5 }, { "value": 10 }] },
{ "name": "aspect_ratio", "label": "画面比例", "type": "select", "required": true, "options": [{ "value": "9:16" }, { "value": "16:9" }] }
],
"fixed_parameters": {},
"pricing": {
"unit": "credits",
"rules": [{ "when": { "duration": 5, "aspect_ratio": "9:16" }, "credits": 20 }]
}
}
],
"has_more": false
},
"request_id": "req_01J..."
}/uploads创建 COS 直传签名生成接口不接受任意公网 URL。先为本地素材创建上传签名,再用返回的 asset_* 作为生成输入。
curl -X POST "https://vi.91jiguang.com/api/v1/uploads" \
-H "Authorization: Bearer jg_live_<key_id>_<secret>" \
-H "Content-Type: application/json" \
-d '{
"file_name": "product-front.jpg",
"mime_type": "image/jpeg",
"size_bytes": 1842031
}'curl -X PUT "<upload.url>" \
-H "Content-Type: image/jpeg" \
-H "Cache-Control: public, max-age=31536000, immutable" \
--upload-file "./product-front.jpg"{
"data": {
"id": "asset_01J...",
"object": "asset",
"kind": "image",
"mime_type": "image/jpeg",
"size_bytes": 1842031,
"status": "pending",
"upload": {
"method": "PUT",
"url": "https://cos.example.com/presigned-upload...",
"headers": {
"Content-Type": "image/jpeg",
"Cache-Control": "public, max-age=31536000, immutable"
},
"expires_at": "2026-09-01T14:10:00.000Z"
}
},
"request_id": "req_01J..."
}PUT 时必须逐项、原样发送 upload.headers 返回的全部签名 header,客户端不得遗漏或自行改写,否则 COS 会拒绝签名。
预签名有效期较短,请立即上传。待接收素材需在 24 小时内用于生成;任务成功接收后可复用 7 天,每次被新任务接收都会续期。单账号最多保留 64 个 / 512 MiB 待接收素材,以及 128 个 / 1 GiB 未过期素材。
/generations创建图片或视频生成使用 model 选择公开模型,使用 input 传入提示词与素材,使用 parameters 传入该模型允许的可见参数。
{
"model": "video-model-public-id",
"input": {
"prompt": "保持商品外观一致,缓慢环绕镜头",
"images": ["asset_01JIMAGE..."],
"videos": ["asset_01JVIDEO..."]
},
"parameters": {
"duration": 5,
"aspect_ratio": "9:16"
}
}{
"data": {
"id": "gen_01J...",
"object": "generation",
"model": "video-model-public-id",
"type": "video",
"status": "queued",
"progress": 0,
"credits": 20,
"output": { "assets": [] },
"error": null,
"created_at": "2026-09-01T14:00:00.000Z",
"updated_at": "2026-09-01T14:00:00.000Z",
"completed_at": null,
"idempotent_replay": false
},
"request_id": "req_01J..."
}queued已入队processing处理中succeeded成功failed失败canceled已取消上述是对外稳定状态,不暴露供应商内部阶段。v1 暂不提供主动取消接口。
/generations/{id}查询单个任务curl "https://vi.91jiguang.com/api/v1/generations/gen_01J..." \
-H "Authorization: Bearer jg_live_<key_id>_<secret>"{
"data": {
"id": "gen_01J...",
"object": "generation",
"model": "video-model-public-id",
"type": "video",
"status": "succeeded",
"progress": 100,
"credits": 20,
"output": {
"assets": [
{
"type": "video",
"url": "https://cdn.example.com/result.mp4",
"mime_type": "video/mp4",
"duration": 5
}
]
},
"error": null,
"created_at": "2026-09-01T14:00:00.000Z",
"updated_at": "2026-09-01T14:03:12.000Z",
"completed_at": "2026-09-01T14:03:12.000Z"
},
"request_id": "req_01J..."
}/generations分页列出任务可使用 status、limit 查询,并把响应中的 next_cursor 作为下一页的 starting_after。任务仅对创建它的账号可见。
curl "https://vi.91jiguang.com/api/v1/generations?status=succeeded&limit=20" \
-H "Authorization: Bearer jg_live_<key_id>_<secret>"客户端必须安全重试,同时遵守账号级速率和并发容量限制;轮换 Key 不会重置配额。
POST /generations 必须携带 8–128 个可见 ASCII 字符。同一账号 + 同一 Idempotency-Key + 相同请求体会返回原任务,不会重复扣积分;请求体不同时返回 HTTP 409。
| 范围 | 默认限制 | 适用接口 |
|---|---|---|
| 匿名入口 | 300 次/分钟/客户端 IP | 所有 /api/v1 请求,鉴权前 |
| 读取接口 | 120 次/分钟/账号 | 模型列表、任务查询 |
| 上传签名 | 30 次/分钟/账号 | POST /uploads |
| 生成创建 | 10 次/分钟/账号 | POST /generations |
| 用户并发 | 3 个非终态任务 | queued + processing |
响应包含 X-RateLimit-Limit、X-RateLimit-Remaining 和 X-RateLimit-Reset。429 响应还包含 Retry-After。如供应商限制更低,以更低值为准。
在开发者中心配置一个固定 HTTPS 端点,接收任务终态事件。
generation.succeededgeneration.failed{
"id": "evt_01J...",
"type": "generation.succeeded",
"created_at": "2026-09-01T14:03:12.000Z",
"data": {
"id": "gen_01J...",
"object": "generation",
"model": "video-model-public-id",
"type": "video",
"status": "succeeded",
"progress": 100,
"credits": 20,
"output": {
"assets": [
{ "type": "video", "url": "https://cdn.example.com/result.mp4", "mime_type": "video/mp4" }
]
},
"created_at": "2026-09-01T14:00:00.000Z",
"completed_at": "2026-09-01T14:03:12.000Z"
}
}X-Jiguang-Event-Id稳定事件 ID,用于接收方去重X-Jiguang-TimestampUnix 时间戳(秒)X-Jiguang-Signaturev1=<hex hmac sha256>import crypto from "node:crypto";
function verifyWebhook(rawBody, timestamp, signature, secret) {
const timestampSeconds = Number(timestamp);
if (!Number.isInteger(timestampSeconds)) return false;
if (Math.abs(Date.now() / 1000 - timestampSeconds) > 300) return false;
const matched = /^v1=([a-f0-9]{64})$/i.exec(signature);
if (!matched) return false;
const expected = crypto
.createHmac("sha256", secret)
.update(timestamp + "." + rawBody)
.digest("hex");
const expectedBytes = Buffer.from(expected, "hex");
const receivedBytes = Buffer.from(matched[1], "hex");
return expectedBytes.length === receivedBytes.length
&& crypto.timingSafeEqual(expectedBytes, receivedBytes);
}必须对未解析的原始请求体验签:HMAC_SHA256(secret, timestamp + "." + rawBody)。拒绝与当前时间相差超过 5 分钟的请求,并按 X-Jiguang-Event-Id 幂等去重;不要对重新序列化后的 JSON 计算签名。
2xx 表示送达成功。网络错误、408、429 和 5xx 按 1 分钟、5 分钟、30 分钟、2 小时、6 小时、24 小时递增重试;其他 4xx 视为终止失败。
根据机器可读的 error.code 分支处理,不要依赖可读文案。
{
"error": {
"code": "invalid_request",
"message": "parameters.duration 不在模型允许范围内",
"param": "parameters.duration",
"details": { "allowed": [5, 10] }
},
"request_id": "req_01J..."
}| error.code | HTTP | 处理说明 |
|---|---|---|
invalid_request | 400 | 请求体、查询参数或素材不符合要求 |
invalid_api_key | 401 | API Key 缺失、格式错误、已停用或已失效 |
model_forbidden | 403 | 当前账号无权使用该模型 |
model_not_found | 404 | 模型不存在或未对 OpenAPI 开放 |
generation_not_found | 404 | 生成任务不存在或不属于当前账号 |
invalid_asset | 400 | 素材不存在、不属于当前账号或不符合模型要求 |
asset_not_uploaded | 400 | 素材未完成上传或上传元数据不匹配 |
asset_expired | 400 | 素材的待上传或可复用租约已到期 |
asset_quota_exceeded | 429 | 账号临时素材数量或容量已达上限 |
invalid_parameters | 400 | 模型参数名或参数值不合法 |
invalid_idempotency_key | 400 | Idempotency-Key 缺失或格式不合法 |
idempotency_conflict | 409 | 同一幂等键被用于不同请求体 |
idempotency_in_progress | 409 | 相同幂等请求正在提交,请稍后重试 |
model_changed | 409 | 提交期间模型配置发生变化,请刷新模型列表 |
insufficient_credits | 402 | 账号积分不足 |
rate_limit_exceeded | 429 | API Key 速率限制已触发 |
concurrency_limit_exceeded | 429 | 账号的非终态生成任务已达上限 |
openapi_disabled | 503 | OpenAPI 全局服务当前未启用 |
rate_limit_unavailable | 503 | 限流服务不可用;系统 fail-closed 拒绝请求 |
storage_unavailable | 503 | 素材上传存储暂时不可用 |
service_unavailable | 503 | 限流或依赖服务暂时不可用 |
internal_error | 500 | 未预期的服务端错误 |
只对 408、429 和 5xx 执行带随机抖动的指数退避。重试创建任务时必须复用原 Idempotency-Key。