Вебхуктар
Сұрау күйін мерзімді тексерудің орнына, іске webhook_url беріңіз. Сұрау соңғы күйге (succeeded, failed немесе
canceled) жеткенде, сол URL мекенжайына қолтаңбасы қойылған POST жібереміз.
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": "..."}'
Оқиға
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.ru/v1/account арқылы (webhook_signing_secret,
whsec_ префиксінен басталады) бір рет оқып, кілтпен бірге сақтаңыз.
Doitong-Signature тақырыбының пішімі — t=<unix time>,v1=<signature>, мұндағы қолтаңба — құпия кілт ретінде өз құпияңыз
пайдаланылатын "<t>.<raw request body>" мәнінің hex түріндегі HMAC-SHA256 хэші. Тексеру үшін:
- Алынған бастапқы дене байттарын дәл сол күйінде алыңыз (JSON талдауы орындалмай тұрып).
- Құпияңызбен
t + "." + bodyмәнінің HMAC-SHA256 хэшін кіші әріппен жазылған hex түрінде есептеңіз. - Оны
v1мәнімен тұрақты уақытта салыстырыңыз. 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);
});
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
Кеңестер
- Жылдам жауап беріп, өз өңдеу кезегіңізге қосыңыз.
- Құпия іске қосқан API кілтіне тиесілі. Әртүрлі сервистердегі кілттердің құпиялары да әртүрлі.