Webhook
webhook 会在发生某些事情时通知服务器,比如视频结束。它省去了轮询 GET /v1/job/{id}。Webhook 的管理方式和 API 的其他部分一样,API 键 , https://reigniter.ai/api/webhooks。
| 事件 | 发送时间 |
|---|---|
video.completed |
渲染完成。有效载荷有 download_url,一个能工作7天的链接。 |
video.failed |
渲染失败了。你取消的渲染不会发送这个。 |
training.invited |
学习者被分配了一个模块并发送了培训页面。 |
training.completed |
一名有名字的学习者完成了一个模块。有效载荷包含分数(由服务器标记)、 passed 和他们的结果页面。 |
training.passed / training.failed |
带着 training.completed,匹配模块的通过分数。时间耗尽即为不及格。 |
training.overdue |
学员未按时完成。每次邀请一次。 |
training.certificate_expiring |
证书在30天内失效。每张证书一次。 |
post.published |
帖子发布在 YouTube、 TikTok、 LinkedIn、 Facebook 或 Instagram。payload包含平台、账户和 url,当平台发布链接时。 |
post.failed |
帖子无法发布。平台 reason 直白回答。 |
credits.low |
余额降到了10积分或更少。每次掉落一次。 |
credits.purchased |
账户中已加入积分。 |
subscription.created |
开始订阅套餐。 |
subscription.canceled |
计划订阅被取消了。 |
user.signup |
账户已经创建。 |
user.onboarded |
账户完成了入职。 |
GET /api/webhooks/events 返回这份名单。
建立一个webhook
Section titled “建立一个webhook”-
在服务器上构建一个端点,接受
POST请求并快速响应2xxJSON体。必须能通过公共互联网访问。私网和局域网地址均被拒绝。 -
订阅一个事件。一个webhook监听一个事件;每个事件创建一个。
终端窗口 curl https://reigniter.ai/api/webhooks/hooks \-H "Authorization: Bearer $REIGNITER_API_KEY" \-H "Content-Type: application/json" \-d '{"event": "video.completed","webhook_url": "https://hooks.example.com/reignitor","description": "Post finished videos to our CMS"}'const res = await fetch('https://reigniter.ai/api/webhooks/hooks', {method: 'POST',headers: {Authorization: `Bearer ${process.env.REIGNITER_API_KEY}`,'Content-Type': 'application/json',},body: JSON.stringify({event: 'video.completed',webhook_url: 'https://hooks.example.com/reignitor',description: 'Post finished videos to our CMS',}),});const { hook, secret } = await res.json();res = requests.post("https://reigniter.ai/api/webhooks/hooks",headers={"Authorization": f"Bearer {os.environ['REIGNITER_API_KEY']}"},json={"event": "video.completed","webhook_url": "https://hooks.example.com/reignitor","description": "Post finished videos to our CMS",},)data = res.json()hook, secret = data["hook"], data["secret"] -
**存储
201**响应的secret。你需要它来检查签名。 -
发送测试。
POST /api/webhooks/hooks/{id}/test会向你的URL发送一个签名的ping事件,并告诉你端点的回答:{ "delivered": true, "status": 200 }
再次订阅同一个事件和URL,不会创建重复的事件。它会返回已有的webhook并 reused: true 并重新开启。
分娩是什么样子
Section titled “分娩是什么样子”每一次分娩都是JSON 体的 POST:
{ "event": "video.completed", "payload": { "job_id": "7d2e4b10-5c3a-4f8e-a1b2-9c0d8e7f6a54", "user_id": "3f1c2a9e-8b7d-4c1e-9f0a-2d6b5e4c3a21", "output_url": "https://cdn.example.com/exports/7d2e4b10.mp4", "canvas_id": null, "scene_count": 4, "scenes_failed": 0, "credits_charged": 12 }, "emitted_at": "2026-09-25T10:15:00.000Z", "delivery_id": "1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed"}video.failed 携带 job_id、 user_id、 canvas_id 和 reason。
把 payload.job_id 和你从 POST /v1/render 那里得到的 job_id 匹配。
还有这些头:
| 头部 | 价值 |
|---|---|
X-Reigniter-Event |
活动名称。 |
X-Reigniter-Delivery |
本次送达的唯一ID。重试送送时ID保持不变。 |
X-Reigniter-Timestamp |
Unix时间,几秒钟,交付完成时。 |
X-Reigniter-Signature |
sha256= 和 {timestamp}.{raw body} 的六进制HMAC-SHA256,用你的秘密来锁。 |
在信任它之前,请检查每一次送达:
- 在进行任何解析JSON 之前,先阅读原始请求正文。
- 建立
{X-Reigniter-Timestamp}.{raw body}。 - 用你的秘密作为十六进制计算 HMAC-SHA256,并在前面加
sha256=。 - 用常时比较法和
X-Reigniter-Signature比较。 - 如果时间戳超过5分钟,就拒绝送达。
import { createHmac, timingSafeEqual } from 'node:crypto';
export function verifyReigniterWebhook(rawBody, headers, secret) { const timestamp = headers['x-reigniter-timestamp']; const received = headers['x-reigniter-signature'] ?? ''; if (!timestamp || Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;
const expected = 'sha256=' + createHmac('sha256', secret) .update(`${timestamp}.${rawBody}`) .digest('hex');
const a = Buffer.from(expected); const b = Buffer.from(received); return a.length === b.length && timingSafeEqual(a, b);}import hashlib, hmac, time
def verify_reignitor_webhook(raw_body: bytes, headers, secret: str) -> bool: timestamp = headers.get("X-Reigniter-Timestamp") received = headers.get("X-Reigniter-Signature", "") if not timestamp or abs(time.time() - int(timestamp)) > 300: return False
signed = f"{timestamp}.".encode() + raw_body expected = "sha256=" + hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest() return hmac.compare_digest(expected, received)- 每次送达最多等待10秒,等待终端接听。
- 会重试一次
5xx、一次429、一次超时或网络错误,最多三次,间隔约一秒。 - 其他任何
4xx都不会重试。 - 重试保持相同的
X-Reigniter-Delivery。用它来忽略你已经处理过的送货。 - 连续20次送达失败后,webhook会被关闭。
GET /api/webhooks/hooks显示active: false和last_status的最后一个错误。修复你的终端,然后用PATCH /api/webhooks/hooks/{id}和{ "active": true }重新开启。
在你收好货物后尽快回复 2xx ,之后慢慢来。
管理webhook
Section titled “管理webhook”| 方法 | 路径 | 它的作用 |
|---|---|---|
GET |
/api/webhooks/events |
列表事件名称和签名方案 |
GET |
/api/webhooks/hooks |
列出你的网钩 |
POST |
/api/webhooks/hooks |
创建一个 webhook |
PATCH |
/api/webhooks/hooks/{id} |
暂停、继续或更改网址或描述 |
DELETE |
/api/webhooks/hooks/{id} |
删除一个webhook |
POST |
/api/webhooks/hooks/{id}/test |
发送签名 ping |
一个账户最多可以有25个webhook。完整的请求和响应形态都在 端点引用中。