dunops.com/Docsbeta

API reference

Webhooks

DunOps can push events to your systems in real time — run completed, approval requested, provider connected.

Setting up a webhook

Go to Settings → Webhooks → Add endpoint. Enter your HTTPS URL and select which events to subscribe to. DunOps sends a POST request to your endpoint for every matching event.

Note

Your endpoint must respond with a 2xx status within 10 seconds. DunOps retries failed deliveries up to 5 times with exponential backoff.

Event types

EventWhen it fires
run.startedA playbook run begins
run.step.completedA single step in a run finishes
run.approval_requiredA step is waiting for human approval
run.completedThe entire run finishes (success or failure)
provider.connectedA provider is successfully connected
provider.disconnectedA provider is removed

Payload shape

Example: run.completed
{
  "event": "run.completed",
  "workspace_id": "ws_abc",
  "timestamp": "2026-06-17T12:05:00Z",
  "data": {
    "run_id": "run_5678",
    "playbook_id": "pb_1234",
    "playbook_name": "Deploy storefront to prod",
    "status": "succeeded",
    "duration_ms": 4200
  }
}

Verifying the signature

Every webhook request includes a X-DunOps-Signature header — an HMAC-SHA256 signature of the raw request body, keyed with your webhook secret. Always verify it before processing.

Verify signature (Node.js)
import crypto from "node:crypto";

function isValidSignature(body: string, header: string, secret: string) {
  const expected = crypto
    .createHmac("sha256", secret)
    .update(body)
    .digest("hex");
  const actual = header.replace("sha256=", "");
  return crypto.timingSafeEqual(
    Buffer.from(expected, "hex"),
    Buffer.from(actual, "hex"),
  );
}

Warning

Use timingSafeEqual — a plain string comparison is vulnerable to timing attacks.

Next steps