Naar inhoud springen
API-handleiding

Webhooks

Als Markdown bekijken Bijgewerkt

Geef een run een webhook_url in plaats van te pollen. Wanneer de request een definitieve status bereikt (succeeded, failed of canceled), versturen we een ondertekende POST naar die URL.

terminal
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": "..."}'

De event

Request headers
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…
Request body
{
  "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 is request.succeeded, request.failed of request.canceled.
  • data is het volledige request-object, precies wat GET /requests/{id} retourneert.
  • id is stabiel voor een request en diens definitieve status. Gebruik dit om een levering die je al hebt verwerkt te negeren.

Leveringen en retries

Antwoord binnen 10 seconden met een status in 2xx. Al het andere (of een time-out) wordt opnieuw geprobeerd: maximaal 6 pogingen in totaal, na 30 seconden, 2 minuten, 10 minuten, 1 uur en 6 uur. Voer traag werk na je antwoord uit, niet ervoor.

De handtekening verifiëren

Elke sleutel heeft een eigen ondertekeningsgeheim. Lees dit één keer uit met GET https://api.doitong.com/v1/account (webhook_signing_secret, het begint met whsec_) en bewaar het naast de sleutel.

De Doitong-Signature-header is t=<unix time>,v1=<signature>, waarbij de handtekening de hexadecimale HMAC-SHA256 is van "<t>.<raw request body>", met je geheim als sleutel. Zo verifieer je deze:

  1. Neem de onbewerkte body-bytes exact over zoals ontvangen (vóór JSON-parsing).
  2. Bereken HMAC-SHA256 van t + "." + body met je geheim, als hexadecimale tekst in kleine letters.
  3. Vergelijk deze in constante tijd met v1.
  4. Weiger de event wanneer t meer dan 5 minuten van je klok afwijkt (replaybeveiliging).

Een complete receiver in Node.js (Express) en 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);
});

Tips

  • Reageer snel en zet je eigen verwerking in een wachtrij.
  • Het geheim hoort bij de API-sleutel die de run heeft gestart. Sleutels in verschillende services hebben verschillende geheimen.