DokLocker has a REST API, an MCP server for AI assistants, a partner API for vendors who want to build an integration, and webhooks. Everything below is also in the in-app help.
DokLocker has three ways for other software to work with it:
- Personal API tokens (Account › API & AI assistants) let a script or AI assistant act as one person. See API.
- Partner apps let a vendor's product (an IT audit tool, a backup service, an RMM) keep its part of every client's documentation up to date, the way DokLocker's own integrations do.
- Webhooks tell another system the moment something changes in DokLocker.
Connecting a partner app
An admin opens Admin › Integrations › Partner apps, enters the product's name and clicks Make a key. The key starts with mdp_ and is shown once; paste it into the vendor's product with your DokLocker address.
A partner app:
- works on behalf of the admin who connected it, and shows in the audit log as that admin, labelled Partner app. If that admin leaves, another admin clicks Take it over;
- can never read passwords;
- can be read only, or allowed to add and change documentation (the default);
- can add new clients for organizations that don't match one, if you tick that box. Otherwise you match them on the app's page.
Disconnect stops the key at once. What the app sent stays in your documentation.
Partner API reference
Send the key as Authorization: Bearer mdp_… and JSON bodies with Content-Type: application/json. Addresses are relative to your DokLocker, for example https://doklocker.example.com/api/v1/partner/organizations/. Every call answers JSON; errors answer {"error": "…"} with a 4xx status. Send at most 5,000 items per call.
Organizations
POST /api/v1/partner/organizations/
{"organizations": [{"id": "1001", "name": "Acme Inc"}, {"id": "1002", "name": "Globex"}]}
Send every organization (customer) you know about, with your own id for it. Ones with the same name as a client are matched straight away; an admin matches the rest, or ignores them, on the app's page. The answer, and GET /api/v1/partner/organizations/, list each one with status (matched, unmatched or ignored), client_id and client_name. Send organizations again whenever they change; names are kept up to date.
Data for an organization that isn't matched yet is skipped (and reported as such), so send organizations first and send everything else again on your next sync.
Devices
POST /api/v1/partner/devices/
{"devices": [{"id": "dev-77", "org_id": "1001", "name": "ACME-DC01", "category": "Server",
"os": "Windows Server 2022", "serial": "5CG1234XYZ", "make": "Dell Inc.",
"model": "PowerEdge R660", "ip": "10.0.0.10", "mac": "00:11:22:33:44:55",
"warranty": "2028-04-30", "last_seen": "2026-10-30T08:00:00Z",
"extra": {"risk score": 12, "agent version": "4.2"}}]}
id, org_id and name are needed; the rest is optional. Each device lands on a record, matched like an RMM sync: the record it was matched to before, then serial number, then MAC address, then name. New devices are added to the client's first site, as the record type their category and operating system suggest (server, workstation, printer, network device or asset). Your app fills in operating system, serial number, make, model, IP and MAC address, warranty date and last seen; anything else people wrote on the record is left alone. Each extra item shows on the record as "App name label". The answer lists the record_id for each device.
Documents
POST /api/v1/partner/documents/
{"documents": [{"id": "ad-summary", "org_id": "1001", "title": "Active Directory (from Liongard)",
"body": "## Domain\n\nacme.local, 2 domain controllers, **48** enabled users ..."}]}
Each document becomes a note on the client, written in Markdown (headings, lists, tables, bold, links). Send the same id again to update the note in place, even if someone moved it. The answer lists each note_id.
Status tiles and backup results
Use the regular endpoints, with your org_id in place of client_id:
POST /api/v1/tiles/shows a coloured tile on the client's page, like "Patching: 96% up to date". See API.POST /api/v1/backups/reports backup results, which show on Backups and raise an alert when one fails. See Backup status.
Webhooks
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:
X-DokLocker-Event: the event name.X-DokLocker-Delivery: a delivery id. A retried delivery keeps its id, so you can skip ones you've already handled.X-DokLocker-Signature:t=<unix time>,v1=<signature>, where the signature is the hex HMAC-SHA256 of<t>.<raw body>with the webhook's signing secret (shown on its page).
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.
REST API and MCP server
DokLocker has an MCP server for AI assistants and a REST API for scripts and other software. Both use a personal API token.
Make a token
Click your name in the lower left › Account › API & AI assistants, give the token a name, and choose:
- Expires after: 30 days, 90 days, 1 year or never.
- Can add and change things: leave it off for a read-only token. Read-only people always get read-only tokens.
- Can read passwords: only offered if you can view passwords. Every password read is written to the audit log.
The token (it starts with mdk_) is shown once. Copy it into the assistant or script straight away. A token acts as you, so if your access is disabled or suspended, your tokens stop working too. Turn off a token you no longer use.
Connect an AI assistant (MCP)
Your DokLocker has to be on an https:// address the assistant can reach, for example through Cloudflare Tunnel. The MCP server address is your DokLocker address followed by /mcp, such as https://docs.yourcompany.com/mcp. The API & AI assistants page shows ready-to-copy settings for:
- Claude Code: one
claude mcp addcommand. - Claude Desktop: a few lines in its config file (Settings › Developer › Edit Config). It uses the free
mcp-remotehelper, which needs Node.js on that computer. - VS Code with GitHub Copilot: a
.vscode/mcp.jsonfile.
Then just ask, for example "What's the firewall IP at Acme's main office?" or "Add a printer called Front Desk HP to Acme HQ". The assistant can search, read clients, records and notes, and (with a read and write token) add clients, sites, records, contacts and notes. Everything it changes appears in the audit log marked AI assistant.
REST API
Send the token in a header: Authorization: Bearer mdk_…. Data goes in and out as JSON.
| Call | What it does |
|---|---|
GET /api/v1/ |
Who you are, and every endpoint |
GET /api/v1/search/?q=10.0.0.1 |
Search everything |
GET /api/v1/lookup/?number=603.555.0142 |
Who is calling: contacts, clients, sites and records with that phone number, however it was typed, with links |
GET /api/v1/clients/ |
All clients |
GET /api/v1/clients/<id>/ |
One client with its sites, contacts and records |
POST /api/v1/clients/ |
Add a client: {"name": "Acme", "address": "…"} |
POST /api/v1/sites/ |
Add a site: {"client_id": 1, "name": "Warehouse"} |
GET /api/v1/record-types/ |
Record types and their field keys |
GET /api/v1/records/<id>/ |
One record (passwords hidden) |
POST /api/v1/records/ |
Add a record: {"site_id": 1, "type": "printer", "name": "Front Desk", "fields": {"ip_address": "10.0.0.50"}} |
PATCH /api/v1/records/<id>/ |
Change a record's name, notes or fields |
POST /api/v1/records/<id>/reveal/<field>/ |
Read a password (needs a token that can read passwords) |
POST /api/v1/contacts/ |
Add a contact |
GET /api/v1/notes/<id>/, POST /api/v1/notes/ |
Read or add a note |
GET /api/v1/articles/<id>/, POST /api/v1/articles/ |
Read or add a knowledge base article: {"title": "…", "body": "Markdown", "folder": "…"} (search finds articles too) |
GET /api/v1/tiles/?client_id=1 |
A client's status tiles, built-in and posted |
POST /api/v1/tiles/ |
Add or update a status tile (see below) |
DELETE /api/v1/tiles/<id>/ |
Remove a status tile you posted |
GET /api/v1/backups/?client_id=1 |
A client's backup jobs and their last result |
POST /api/v1/backups/ |
Report backup results (see Backup status) |
Example with curl:
curl -H "Authorization: Bearer mdk_…" https://docs.yourcompany.com/api/v1/search/?q=acme
Status tiles from your other tools
Status tiles are the coloured squares at the top of each client and on the Status board. DokLocker makes its own (renewals, passwords to change, IP conflicts, open checklists, out-of-date records and sync health). Your scripts and other tools can add more, such as last backup, antivirus alerts or open tickets.
Post a tile with a token that can add and change things:
curl -X POST https://docs.yourcompany.com/api/v1/tiles/ \
-H "Authorization: Bearer mdk_…" -H "Content-Type: application/json" \
-d '{"client_id": 12, "key": "backup", "title": "Last backup", "value": "Last night",
"status": "ok", "detail": "Nightly image backup", "url": "https://backup.example.com/jobs/88"}'
- key is your own name for the tile, using letters, numbers,
-and_. Posting the same key again updates that tile, so a nightly script just posts each time it runs. - status is
ok(green),warn(amber),bad(red) orinfo(grey). - value is the big text (up to 60 characters), detail the small line under it, and url where a click goes.
- Use
GET /api/v1/clients/to find each client's id.