सामग्री पर जाएँ
API गाइड

वेबहुक

Markdown के रूप में देखें अपडेट किया गया

पोलिंग करने के बजाय, किसी रन को webhook_url दें। जब अनुरोध अंतिम स्थिति (succeeded, failed या canceled) तक पहुँचता है, तो हम उस URL पर हस्ताक्षरित 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 किसी अनुरोध और उसकी अंतिम स्थिति के लिए स्थिर होता है। पहले से प्रोसेस की गई डिलीवरी को अनदेखा करने के लिए इसका उपयोग करें।

डिलीवरी और पुनःप्रयास

10 सेकंड के भीतर किसी भी 2xx स्थिति के साथ जवाब दें। इसके अलावा कुछ भी (या टाइमआउट) होने पर पुनःप्रयास किया जाता है: कुल 6 प्रयास तक, 30 सेकंड, 2 मिनट, 10 मिनट, 1 घंटा और 6 घंटे बाद। धीमा काम जवाब देने के बाद करें, उससे पहले नहीं।

हस्ताक्षर सत्यापित करें

हर कुंजी का अपना हस्ताक्षर रहस्य होता है। इसे GET https://api.doitong.com/v1/account से (webhook_signing_secret, यह whsec_ से शुरू होता है) एक बार पढ़ें और इसे कुंजी के पास संग्रहीत करें।

Doitong-Signature हेडर t=<unix time>,v1=<signature> होता है, जहाँ हस्ताक्षर आपकी सीक्रेट कुंजी के रूप में उपयोग करके "<t>.<raw request body>" का hex HMAC-SHA256 होता है। सत्यापित करने के लिए:

  1. प्राप्त की गई रॉ बॉडी बाइट्स को ठीक उसी रूप में लें (किसी भी JSON पार्सिंग से पहले)।
  2. अपनी सीक्रेट के साथ t + "." + body का HMAC-SHA256 लोअरकेस hex के रूप में निकालें।
  3. इसकी तुलना v1 से constant time में करें।
  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 कुंजी से संबंधित होती है जिसने रन शुरू किया। अलग-अलग सेवाओं की कुंजियों की सीक्रेट अलग होती हैं।