דילוג לתוכן
מדריך API

וובהוקים

הצגה כ-Markdown עודכן

במקום לבצע תשאול, העבירו להרצה webhook_url. כאשר הבקשה מגיעה לסטטוס סופי (succeeded,‏ failed או canceled), אנו שולחים POST חתום לכתובת הזו.

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

האירוע

כותרות הבקשה
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…
גוף הבקשה
{
  "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 הוא request.succeeded,‏ request.failed או request.canceled.
  • data הוא אובייקט הבקשה המלא, בדיוק כפי שמחזיר GET /requests/{id}.
  • id יציב עבור בקשה והסטטוס הסופי שלה. השתמשו בו כדי להתעלם ממסירה שכבר עיבדתם.

מסירות וניסיונות חוזרים

השיבו בכל סטטוס 2xx בתוך 10 שניות. כל דבר אחר (או פסק זמן) נשלח שוב: עד 6 ניסיונות בסך הכול, לאחר 30 שניות, 2 דקות, 10 דקות, שעה ו-6 שעות. בצעו עבודה איטית לאחר המענה, לא לפניו.

אימות החתימה

לכל מפתח יש סוד חתימה משלו. קראו אותו פעם אחת מ-GET https://api.doitong.com/v1/account (webhook_signing_secret, הוא מתחיל ב-whsec_) ושמרו אותו לצד המפתח.

כותרת Doitong-Signature היא t=<unix time>,v1=<signature>, כאשר החתימה היא HMAC-SHA256 הקסדצימלי של "<t>.<raw request body>" באמצעות הסוד שלכם כמפתח. כדי לאמת:

  1. קחו את בתי גוף הבקשה הגולמיים בדיוק כפי שהתקבלו (לפני ניתוח JSON כלשהו).
  2. חשבו HMAC-SHA256 של t + "." + body באמצעות הסוד שלכם, בהקסדצימלי באותיות קטנות.
  3. השוו אותו ל-v1 בזמן קבוע.
  4. דחו את האירוע כאשר t רחוק ביותר מ-5 דקות מהשעון שלכם (הגנה מפני השמעה חוזרת).

מקבל מלא ב-Node.js (Express) וב-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);
});

טיפים

  • השיבו במהירות והכניסו את העיבוד שלכם לתור.
  • הסוד שייך למפתח API שהתחיל את ההרצה. למפתחות בשירותים שונים יש סודות שונים.