接收生成通知
下面的接口说明为英文原文。
Signed per the Standard Webhooks specification. Verify with an official Standard Webhooks library and the endpoint's whsec_ signing secret: it checks Base64(HMAC-SHA256(Base64-decoded secret, webhook-id + '.' + webhook-timestamp + '.' + raw_body)) against each v1 entry in webhook-signature in constant time and rejects timestamps more than five minutes from now. Deduplicate by webhook-id. Redelivery preserves the body and webhook-id and signs again with a new timestamp.
VizoAPI 会把这个请求发送到你在控制台创建的 Webhook 端点。
请求头
| 字段 | 说明 |
|---|---|
| webhook-idstring必填 | Unique event ID, equal to event_id in the body. Unchanged on retries and redelivery; use it to deduplicate. |
| webhook-timestampstring必填 | Unix time in seconds when this attempt was sent. |
| webhook-signaturestring必填 | Space-delimited list of v1 signatures. Two are sent for 24 hours after a secret rotation; accept the request if any one matches. |
请求体
JSON 对象,不接受未列出的字段。
| 字段 | 说明 | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| billing_statusstring必填 | Pending awaits funding; unfunded closed without a hold; held means Credits are held for the task; settled charges verified delivery; released returns the hold; refunded reverses previously consumed generation Credits. pendingunfundedheldsettledreleasedrefunded | ||||||||||
| closed_statusstring必填 | Immutable customer closure. Unresolved means the resolution deadline passed without confirmed delivery. succeededfailedcanceledunresolved | ||||||||||
| created_atdate-time必填 | |||||||||||
| delivery_statusstring必填 | Managed output delivery state, independent of supplier execution. pendingcopyingreadyfailed | ||||||||||
| error_codestring可选 | Stable accepted-task failure code, matching generation error.code. Omitted when no failure code applies. Funding or recovery refusals, provider capacity, content policy, media validity, draft expiry and other execution failures remain distinct. insufficient_balancebalance_negativebudget_exceededspending_blockedrecovery_reviewprovider_unavailableinput_moderatedoutput_moderatedinput_media_invalidinput_media_unreachabledraft_expiredinput_rejectedgeneration_failed | ||||||||||
| event_idstring必填 | |||||||||||
| execution_statusstring必填 | Supplier execution state: processing until execution ends. Succeeded can precede verified media delivery. processingsucceededfailedcanceledunresolved | ||||||||||
| freeboolean必填 | |||||||||||
| late_result_availableboolean必填 | 关闭后才到的结果,免费提供。 | ||||||||||
| priceobject必填 | 这个任务的积分:estimated 是预估额,也就是冻结额,实际扣费按实际用量计算,可能与预估略有差异;reserved 是当前冻结的积分;charged 是按实际用量和固定费率扣的积分,结算前为 0.000;refunded 是退款退回的积分。 price 的字段
| ||||||||||
| resultobject, 可为 null必填 | 交付后的素材。 result 的字段
| ||||||||||
| task_idstring必填 | |||||||||||
| typestring必填 | generation.succeededgeneration.failedgeneration.canceledgeneration.unresolvedgeneration.refundedgeneration.late_result_available | ||||||||||
| versioninteger必填 |
响应
2XX Delivery accepted
请求示例
cURL
# Your endpoint receives a POST signed per Standard Webhooks. Replay one locally to test your handler:
curl -X POST "$YOUR_WEBHOOK_URL" \
-H "Content-Type: application/json" \
-H "webhook-id: $EVENT_ID" \
-H "webhook-timestamp: $TIMESTAMP" \
-H "webhook-signature: v1,$SIGNATURE" \
--data-binary @event.jsonPython
# pip install standardwebhooks
from standardwebhooks import Webhook, WebhookVerificationError
wh = Webhook("whsec_...") # your endpoint's signing secret
def verify(headers, raw_body: bytes):
try:
return wh.verify(raw_body, headers) # returns the parsed event
except WebhookVerificationError:
return NoneNode.js
// npm install standardwebhooks
import { Webhook } from "standardwebhooks";
const wh = new Webhook(process.env.WEBHOOK_SECRET); // whsec_...
// rawBody is a Buffer of the request body as received, e.g. express.raw({ type: "application/json" }).
export function verify(headers, rawBody) {
try {
return wh.verify(rawBody, headers); // returns the parsed event
} catch {
return null;
}
}{
"billing_status": "held",
"closed_status": "succeeded",
"created_at": "2026-11-02T08:01:43Z",
"delivery_status": "pending",
"error_code": "insufficient_balance",
"event_id": "string",
"execution_status": "processing",
"free": false,
"late_result_available": false,
"price": {
"charged": "0.000",
"estimated": "157.000",
"refunded": "0.000",
"reserved": "157.000",
"unit": "credit"
},
"result": null,
"task_id": "gen_01JD8Z5QW3XR",
"type": "generation.succeeded",
"version": 1
}