Webhook'ler
Yoklama yapmak yerine bir çalıştırmaya webhook_url verin. İstek nihai bir duruma (succeeded, failed veya
canceled) ulaştığında bu URL'ye imzalı bir POST göndeririz.
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": "..."}'
Olay
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.failedveyarequest.canceleddeğerlerinden biridir.data,GET /requests/{id}çağrısının döndürdüğü istek nesnesinin tamamıdır.id, bir istek ve onun nihai durumu için sabittir. Daha önce işlediğiniz bir teslimatı yok saymak için bunu kullanın.
Teslimatlar ve yeniden denemeler
10 saniye içinde herhangi bir 2xx durumuyla yanıt verin. Diğer her şey (veya zaman aşımı) yeniden denenir: toplamda en fazla 6 deneme,
30 saniye, 2 dakika, 10 dakika, 1 saat ve 6 saat sonra yapılır. Yavaş işlemleri yanıt verdikten sonra gerçekleştirin; öncesinde değil.
İmzayı doğrulama
Her anahtarın kendine ait bir imzalama gizli anahtarı vardır. Bu anahtarı GET https://api.doitong.ru/v1/account çağrısından (webhook_signing_secret,
whsec_ ile başlar) bir kez okuyun ve API anahtarının yanında saklayın.
Doitong-Signature başlığı t=<unix time>,v1=<signature> biçimindedir; buradaki imza, gizli anahtarınız kullanılarak
"<t>.<raw request body>" ifadesinin HMAC-SHA256 değerinin onaltılık gösterimidir. Doğrulamak için:
- Alındığı haliyle ham gövde baytlarını alın (JSON ayrıştırmasından önce).
- Gizli anahtarınızla
t + "." + bodyifadesinin HMAC-SHA256 değerini küçük harfli onaltılık biçimde hesaplayın. - Bunu
v1ile sabit zamanda karşılaştırın. tdeğeri saatinizden 5 dakikadan fazla uzaksa olayı reddedin (tekrar oynatma koruması).
Node.js (Express) ve Python (Flask) ile hazırlanmış eksiksiz bir alıcı:
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
İpuçları
- Hızlı yanıt verin ve kendi işlemlerinizi kuyruğa alın.
- Gizli anahtar, çalıştırmayı başlatan API anahtarına aittir. Farklı hizmetlerdeki anahtarların gizli anahtarları farklıdır.