Webhookura
Sode polling, de jekh webhook_url ko run. Kana o mangipen avel ko agoruno status (succeeded, failed vaj canceled), bičhalas jekh sinjalizime POST ko URL.
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": "..."}'
O event
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" } ]
}
}
typesirequest.succeeded,request.failedvajrequest.canceled.datasi sa o mangipenosko objekto, exaktno soGET /requests/{id}del.idsi stabilno pентru jekh mangipen thaj lesko agoruno status. Labar les te na primis tu jekh delivery so već obradas.
Deliveryura thaj retryura
Phen palem le savo 2xx status ande 10 sekunda. Savo aver (vaj timeout) kerel retry: dži 6 akharipena savorre, palal 30 sekundura, 2 minuta, 10 minuta, 1 minuta thaj 6 minuta. Na keres sigo buća anglal te phenes palem; ker len palal.
Proveri o sinjal
Sakone klidines si lesko korkori sinjalizipnako sekretо. Ginav les jekhvar katar GET https://api.doitong.com/v1/account (webhook_signing_secret, startil le whsec_-sa) thaj arakh les paš o klidin.
O Doitong-Signature header si t=<unix time>,v1=<signature>, kaj o sinjal si hex HMAC-SHA256 e "<t>.<raw request body>"-esko, tiro sekretо sar klidin. Te proveris:
- Le sa raw body bytes exaktno sar resle (anglal JSON parsing).
- Ginav HMAC-SHA256 e
t + "." + body-esko le tire sekretosa, sar lowercase hex. - Sravnis les le
v1-sa constant time-esa. - Na prihvatin o event kana
tsi maj dur katar 5 minuta tire reloresko (replay protection).
Jekh pherdo receiver ande Node.js (Express) thaj 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);
});
import hashlib
import hmac
import json
import os
import time
from flask import Flask, abort, request
SECRET = os.environ["DOITONG_WEBHOOK_SECRET"].encode() # whsec_...
app = Flask(__name__)
@app.post("/hooks/doitong")
def doitong_hook():
body = request.get_data() # raw bytes
parts = dict(p.split("=", 1) for p in request.headers.get("Doitong-Signature", "").split(",") if "=" in p)
t = parts.get("t", "0")
expected = hmac.new(SECRET, t.encode() + b"." + body, hashlib.sha256).hexdigest()
if not hmac.compare_digest(expected, parts.get("v1", "")) or abs(time.time() - int(t)) > 300:
abort(400)
event = json.loads(body)
if event["type"] == "request.succeeded":
print(event["data"]["id"], [o["url"] for o in event["data"]["outputs"]])
return "", 204
Sugeratura
- Dava palem sigo thaj queue-isar tiro korkoro procesiripen.
- O sekreto si lesko API klidines so startisardas o run. Keys ande aver servisa si le aver sekretоnça.