Bỏ qua đến nội dung
Hướng dẫn API

Webhook

Xem dưới dạng Markdown Đã cập nhật

Thay vì polling, hãy cung cấp webhook_url cho một lần chạy. Khi yêu cầu đạt trạng thái cuối cùng (succeeded, failed hoặc canceled), chúng tôi gửi một POST có chữ ký đến URL đó.

terminal
curl -X POST "https://api.doitong.ru/v1/run/{model_id}?webhook_url=https://example.com/hooks/doitong" \
  -H "Authorization: Bearer $DOITONG_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"prompt": "..."}'

Sự kiện

Header yêu cầu
POST /hooks/doitong HTTP/1.1
Content-Type: application/json
User-Agent: Doitong-Webhooks/1
Doitong-Request-Id: req_8k2m4q7x1z9c3v5b6n0p2r4t
Doitong-Signature: t=1760961609,v1=5f1c0d6e2b…
Phần thân yêu cầu
{
  "id": "evt_8k2m4q7x1z9c3v5b6n0p2r4t_succeeded",
  "object": "event",
  "type": "request.succeeded",
  "created_at": "2026-10-20T12:00:09Z",
  "data": {
    "id": "req_8k2m4q7x1z9c3v5b6n0p2r4t",
    "object": "request",
    "status": "succeeded",
    "outputs": [ { "type": "video", "url": "https://content.doitong.com/dev-api/…/0-output.mp4" } ]
  }
}
  • type là request.succeeded, request.failed hoặc request.canceled.
  • data là đối tượng yêu cầu đầy đủ, chính xác như kết quả của GET /requests/{id}.
  • id ổn định cho một yêu cầu và trạng thái cuối cùng của yêu cầu đó. Dùng id này để bỏ qua lần gửi đã xử lý.

Gửi và thử lại

Trả lời bằng bất kỳ trạng thái 2xx nào trong vòng 10 giây. Mọi phản hồi khác (hoặc hết thời gian) sẽ được thử lại: tối đa 6 lần, sau 30 giây, 2 phút, 10 phút, 1 giờ và 6 giờ. Hãy thực hiện công việc chậm sau khi trả lời, không phải trước đó.

Xác minh chữ ký

Mỗi khóa có một bí mật ký riêng. Đọc bí mật này một lần từ GET https://api.doitong.ru/v1/account (webhook_signing_secret, bắt đầu bằng whsec_) và lưu cùng với khóa.

Header Doitong-Signature có dạng t=<unix time>,v1=<signature>, trong đó chữ ký là HMAC-SHA256 dạng hex của "<t>.<raw request body>", dùng bí mật của bạn làm khóa. Để xác minh:

  1. Lấy chính xác các byte của phần thân thô như đã nhận (trước khi phân tích JSON).
  2. Tính HMAC-SHA256 của t + "." + body bằng bí mật của bạn, dưới dạng hex chữ thường.
  3. So sánh với v1 trong thời gian không đổi.
  4. Từ chối sự kiện khi t cách đồng hồ của bạn hơn 5 phút (bảo vệ chống phát lại).

Bộ nhận hoàn chỉnh bằng Node.js (Express) và Python (Flask):

import crypto from "node:crypto";
import express from "express";

const SECRET = process.env.DOITONG_WEBHOOK_SECRET; // whsec_...
const app = express();

app.post("/hooks/doitong", express.raw({ type: "application/json" }), (req, res) => {
  const header = req.get("Doitong-Signature") || "";
  const parts = Object.fromEntries(header.split(",").map((p) => p.split("=", 2)));
  const t = Number(parts.t);
  const expected = crypto.createHmac("sha256", SECRET).update(t + "." + req.body).digest("hex");
  const given = Buffer.from(parts.v1 || "", "utf8");
  const valid =
    given.length === expected.length &&
    crypto.timingSafeEqual(given, Buffer.from(expected, "utf8")) &&
    Math.abs(Date.now() / 1000 - t) < 300;
  if (!valid) return res.status(400).send("bad signature");

  const event = JSON.parse(req.body);
  if (event.type === "request.succeeded") {
    console.log(event.data.id, event.data.outputs.map((o) => o.url));
  }
  res.sendStatus(204);
});

Mẹo

  • Phản hồi nhanh và xếp quy trình xử lý riêng của bạn vào hàng đợi.
  • Bí mật thuộc về khóa API đã khởi chạy lần chạy. Các khóa trong những dịch vụ khác nhau có bí mật khác nhau.