GDDCGeospatial

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

EventPayload-Inhalt
flight.uploadedBilder sind hochgeladen, Validation startet.
flight.processedSfM + Pointcloud + Ortho fertig.
flight.failedEin Verarbeitungs-Schritt ist gescheitert.
pointcloud.readyPunktwolke gestreamt-bar im Web-Viewer.
analysis.doneSoll-Ist / Volumen / Lichtraum / Anomalie fertig.
analysis.failedAnalyse abgebrochen.
report.readyPDF-Bericht generiert, signiert (optional).
anomaly.detectedAnomalie ü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.