Entwickler
Webhooks.
Wir pushen Events, sobald sie passieren — du musst nicht pollen. HMAC-signiert, Retry mit exponential Backoff.
Setup
UI: Settings → Webhooks → Add. URL angeben (HTTPS Pflicht), Events wählen, Secret generieren. Wir senden ein webhook.test beim ersten Speichern — wenn dein Endpoint 2xx antwortet, ist alles gut.
Event-Liste
| Event | Payload-Inhalt |
|---|---|
| flight.uploaded | Bilder sind hochgeladen, Validation startet. |
| flight.processed | SfM + Pointcloud + Ortho fertig. |
| flight.failed | Ein Verarbeitungs-Schritt ist gescheitert. |
| pointcloud.ready | Punktwolke gestreamt-bar im Web-Viewer. |
| analysis.done | Soll-Ist / Volumen / Lichtraum / Anomalie fertig. |
| analysis.failed | Analyse abgebrochen. |
| report.ready | PDF-Bericht generiert, signiert (optional). |
| anomaly.detected | Anomalie über Schwellwert — Helpdesk-Ticket angelegt. |
Payload-Format
{
"id": "evt_b8K2zM4N",
"event": "flight.processed",
"created_at": "2026-04-27T08:14:22Z",
"account_id": "acc_GdC8sH",
"data": {
"flight_id": "FLT_kL2Pq8",
"project_id": "PRJ_aT3Dd9",
"pointcloud_id": "PCL_xY9Vn4",
"orthomosaic_id": "ORT_rT8Uo2",
"duration_ms": 11_842_000
}
}Signatur prüfen
Header: X-Gddc-Signature: sha256=… und X-Gddc-Timestamp: …. Compute HMAC-SHA256 über timestamp + "." + raw_body mit deinem Webhook-Secret und vergleiche mit dem Header.
import crypto from "node:crypto";
export function verify(req, secret) {
const sig = req.headers["x-gddc-signature"]?.split("=")[1];
const ts = req.headers["x-gddc-timestamp"];
if (!sig || !ts) return false;
// Reject stale events (5 min window)
const age = Date.now() / 1000 - Number(ts);
if (Math.abs(age) > 300) return false;
const expected = crypto
.createHmac("sha256", secret)
.update(ts + "." + req.rawBody)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(sig, "hex"),
Buffer.from(expected, "hex"),
);
}Retry-Verhalten
Bei Non-2xx-Antwort retryen wir mit exponential Backoff: 30 s, 2 min, 10 min, 1 h, 6 h. Nach 5 Versuchen markieren wir den Webhook als failed und benachrichtigen den Account-Owner. Du kannst Failed-Events im UI manuell re-senden.
Idempotenz
Jedes Event hat eine eindeutige id. Speichere die letzten 1 000 Event-IDs und ignoriere Duplikate — das kann passieren, wenn dein Endpoint 2xx antwortet aber die Antwort unterwegs verloren geht.