DokLocker
Webhooks logo

DokLocker + Webhooks integration

Send any event to any tool.

What the Webhooks integration does

Build on DokLocker: read and update documentation from your own scripts, tools and AI assistants.

Setting it up

An admin adds a webhook under Admin › Integrations › Webhooks: an address, and the events to send (or all of them). DokLocker POSTs one JSON request per event:

{"id": "evt_8812", "event": "record.updated", "occurred_at": "2026-10-30T14:02:11+00:00",
 "workspace": "Bogus IT",
 "object": {"type": "record", "id": 431, "name": "ACME-FW01", "url": "https://doklocker.example.com/configurations/431/"},
 "client": {"id": 12, "name": "Acme Inc"},
 "changes": {"WAN IP": {"before": "203.0.113.4", "after": "203.0.113.9"}, "Admin password": {"before": "(changed)", "after": "(changed)"}},
 "by": {"email": "[email protected]", "via": "web"}}

Events are client, site, contact, record, note, file, photo, link, domain, certificate, article, checklist and rack, each .created, .updated or .deleted, plus password.viewed and info_request.submitted. Send a test sends a ping event. Passwords are never sent: a changed password only shows as "(changed)". Changes made by integration syncs aren't sent one by one.

Every request has these headers:

Checking the signature in Python:

import hashlib, hmac, time

def is_from_doklocker(secret, header, body):
    parts = dict(p.split("=", 1) for p in header.split(","))
    expected = hmac.new(secret.encode(), f"{parts['t']}.".encode() + body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, parts["v1"]) and abs(time.time() - int(parts["t"])) < 300

And in Node.js:

const crypto = require("crypto");
function isFromDokLocker(secret, header, rawBody) {
  const parts = Object.fromEntries(header.split(",").map(p => p.split("=")));
  const expected = crypto.createHmac("sha256", secret).update(`${parts.t}.`).update(rawBody).digest("hex");
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1)) && Math.abs(Date.now() / 1000 - parts.t) < 300;
}

Answer with any 2xx status within 15 seconds. Anything else is tried again after 1 minute, 5 minutes, 30 minutes, 2 hours, 6 hours and 12 hours. A webhook that fails 20 times in a row is switched off, and your admins get a "sync failed" alert. Each webhook's page shows its last 50 deliveries.

On the hosted service, webhooks must use https:// and can't point to private network addresses.

Included in every plan

Every integration is included at no extra cost, on the hosted service and self-hosted. Connect it under Admin › Integrations, click Test, and the first sync starts straight away.

More Developer integrations

See all integrations

See it with your own clients in mind.

Free for up to 5 clients. Cloud or self-hosted.

Start free trial