跳转到主要内容

Documentation Index

Fetch the complete documentation index at: https://docs.topify.ai/llms.txt

Use this file to discover all available pages before exploring further.

Webhook 让您可以在操作工作流到达检查点或完成时接收实时通知。new_content 操作所使用的 执行工作流 必须使用 Webhook。

注册 Webhook

POST /webhooks
注册一个新的 Webhook 端点以接收事件通知。

请求体

字段类型必填描述
urlstringYes用于接收 Webhook 事件的 HTTPS 端点 URL
eventsstring[]Yes要订阅的事件类型数组

有效事件

事件描述
action.checkpoint工作流在审核检查点暂停(大纲、草稿或终稿审核)
action.completed工作流成功完成
action.failed工作流遇到错误
curl -X POST "https://topify-customer-api-production.up.railway.app/api/public/v1/webhooks" \
  -H "X-API-Key: tk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/webhooks/topify",
    "events": ["action.checkpoint", "action.completed", "action.failed"]
  }'

响应(201 Created)

{
  "success": true,
  "data": {
    "id": "wh_a1b2c3d4-...",
    "url": "https://example.com/webhooks/topify",
    "events": ["action.checkpoint", "action.completed", "action.failed"],
    "is_active": true,
    "secret": "whsec_k7m9p2...",
    "created_at": "2026-04-08T12:00:00Z"
  }
}
secret 字段仅在创建时返回一次。请妥善保管 —— 您将需要它来验证 Webhook 签名。

错误响应

状态原因
400缺少 url、URL 不是 HTTPS、events 数组为空,或事件类型无效
403API 密钥具有只读权限
409已存在使用此 URL 的 Webhook

列出 Webhook

GET /webhooks
返回您账户下注册的所有 Webhook。
curl "https://topify-customer-api-production.up.railway.app/api/public/v1/webhooks" \
  -H "X-API-Key: tk_live_..."

响应

{
  "success": true,
  "data": [
    {
      "id": "wh_a1b2c3d4-...",
      "url": "https://example.com/webhooks/topify",
      "events": ["action.checkpoint", "action.completed", "action.failed"],
      "is_active": true,
      "created_at": "2026-04-08T12:00:00Z"
    }
  ]
}
列表响应中不包含 secret 字段。它仅在 Webhook 首次创建时返回。

删除 Webhook

DELETE /webhooks/{webhook_id}
永久删除一个 Webhook。事件将不再发送至该端点。

路径参数

参数类型描述
webhook_idstringWebhook ID
curl -X DELETE "https://topify-customer-api-production.up.railway.app/api/public/v1/webhooks/{webhook_id}" \
  -H "X-API-Key: tk_live_..."

响应

{
  "success": true,
  "data": {
    "id": "wh_a1b2c3d4-...",
    "message": "Webhook deleted successfully"
  }
}

错误响应

状态原因
403API 密钥具有只读权限
404未找到 Webhook

Webhook 载荷格式

事件触发时,Topify 会向您注册的 URL 发送一个 POST 请求,JSON 请求体如下。

action.checkpoint 载荷

{
  "event": "action.checkpoint",
  "timestamp": "2026-04-08T21:19:13.463Z",
  "data": {
    "action_id": "a1b2c3d4-...",
    "workflow_id": "w1x2y3z4-...",
    "checkpoint": "outline",
    "content": "## Article Outline\n\n1. Introduction to project management tools...",
    "options": [
      { "action": "approve", "label": "Approve & Write" },
      { "action": "edit", "label": "Edit Outline" },
      { "action": "regenerate", "label": "Regenerate" },
      { "action": "reject", "label": "Cancel" }
    ]
  }
}

action.completed 载荷

{
  "event": "action.completed",
  "timestamp": "2026-04-08T21:25:00.000Z",
  "data": {
    "action_id": "a1b2c3d4-...",
    "workflow_id": "w1x2y3z4-...",
    "result": {
      "title": "Best Project Management Tools in 2026",
      "content": "..."
    }
  }
}

action.failed 载荷

{
  "event": "action.failed",
  "timestamp": "2026-04-08T21:22:00.000Z",
  "data": {
    "action_id": "a1b2c3d4-...",
    "workflow_id": "w1x2y3z4-...",
    "error": "LLM generation timed out after 120 seconds"
  }
}

载荷字段

字段类型描述
eventstring事件类型(action.checkpointaction.completedaction.failed
timestampstring事件发生的 ISO 8601 时间戳
data.action_idstring (UUID)触发事件的操作
data.workflow_idstring (UUID)当前活跃的工作流 ID
data.checkpointstring检查点名称(仅 action.checkpoint
data.contentstring待审核内容(仅 action.checkpoint
data.optionsobject[]可用的响应操作(仅 action.checkpoint
data.resultobject最终输出(仅 action.completed
data.errorstring错误消息(仅 action.failed

验证签名

每个 Webhook 请求都包含一个 X-Webhook-Signature 请求头,其中是基于原始请求体并使用创建时返回的 Webhook 密钥计算得出的 HMAC-SHA256 签名。 请始终在处理载荷之前验证此签名,以确保请求的真实性。
import hmac
import hashlib

def verify_webhook(body: bytes, signature: str, secret: str) -> bool:
    expected = hmac.new(
        secret.encode(),
        body,
        hashlib.sha256,
    ).hexdigest()
    return hmac.compare_digest(expected, signature)

# In your webhook handler:
signature = request.headers["X-Webhook-Signature"]
is_valid = verify_webhook(request.body, signature, WEBHOOK_SECRET)
您的端点应在 10 秒内返回 200 状态码。如果端点未能响应或返回非 2xx 状态,Topify 将以指数退避策略最多重试 3 次。