Integrate DFM with your stack.

Everything in DFM, from the verified work log and the equipment register to deficiencies and tenant requests, is reachable four ways: a versioned REST API, an MCP server for AI tooling, signed webhooks pushed to you, and CSV exports. One credential covers the first two; everything below is the complete, tested surface. There are no undocumented endpoints.

Authentication

An org admin creates keys under Settings → Integrations. Keys are org-scoped, carry read and/or write scope, are shown once, and can be revoked independently. Make one per system. Rate limits per key: 600 reads / 5 min and 120 writes / 5 min; 429 responses carry Retry-After.

# Verify a key: the first call to make
curl https://app.digitalfacilitymanagement.com/api/v1/ping \
  -H "Authorization: Bearer sbk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

# → { "ok": true, "organizationId": "…", "organizationName": "…", "scopes": ["read"] }

REST API v1

Base URL /api/v1. All timestamps ISO 8601 UTC; lists return { data, pagination } (page with limit/offset; count < limit means last page); errors return { error: { code, message } }. The wire format is camelCase and stable: breaking changes mean a new version prefix, never a silent change. Full schemas live in the OpenAPI document (import it straight into Postman, Insomnia, or your codegen).

  • get/api/v1/pingVerify a key
  • get/api/v1/sitesList sites
  • get/api/v1/assetsList assets
  • get/api/v1/workflowsList workflows
  • get/api/v1/runsList runs
  • get/api/v1/runs/{id}Get one run with all recorded steps
  • get/api/v1/deficienciesList deficiencies
  • post/api/v1/deficienciesOpen a deficiency
  • get/api/v1/work-requestsList tenant requests
  • post/api/v1/work-requestsFile a request
  • post/api/v1/assignmentsSchedule a workflow run
# Pull yesterday's completed runs into your CMMS
curl "https://app.digitalfacilitymanagement.com/api/v1/runs?status=completed&from=2026-06-09T00:00:00Z&limit=100" \
  -H "Authorization: Bearer $STRINGBEAN_API_KEY"

# File a work request from your ticketing system (write scope)
curl -X POST https://app.digitalfacilitymanagement.com/api/v1/work-requests \
  -H "Authorization: Bearer $STRINGBEAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"siteId":"<uuid>","reporterName":"Front desk","title":"Lobby door closer slamming","category":"other"}'

MCP server

Point Claude, Cursor, or any Model Context Protocol client at your org and ask questions in plain language: “which assets have open deficiencies?”, “show me last week's unverified runs”. Streamable HTTP transport, stateless, same API key. Write tools are advertised but refuse politely on read-only keys.

{
  "mcpServers": {
    "dfm": {
      "url": "https://app.digitalfacilitymanagement.com/api/mcp",
      "headers": { "Authorization": "Bearer sbk_live_…" }
    }
  }
}
  • list_sitesList the organization’s buildings/sites with their timezones.
  • list_assetsList tracked equipment (optionally for one site): name, tag, category, manufacturer/model, install date, warranty expiry.
  • get_asset_historyService history for one asset: recent runs (who/when/duration/verification) and its deficiencies.
  • list_open_deficienciesEverything currently broken or pending a documented fix, worst severity first.
  • list_recent_runsThe execution log: recent field runs with timing, identity verification, and review state.
  • get_runOne run in full: metadata plus every recorded step value (readings, answers, evidence refs).
  • search_workflowsFind published workflows by name fragment (empty query lists all).
  • get_portfolio_healthPer-building roll-up: open/overdue assignments, open deficiencies, pending reviews, new tenant requests.
  • create_work_requestwriteFile a tenant/maintenance request into the triage queue (requires a write-scope key).
  • create_deficiencywriteOpen a tracked corrective action (requires a write-scope key).

Webhooks

Configure endpoints under Settings → Integrations (https only). Events: run.completed, deficiency.opened, deficiency.resolved, work_request.created. Deliveries retry with exponential backoff (5 attempts) and endpoints auto-disable after 50 consecutive failures. Every delivery is signed:

X-DFM-Signature: t=<unix seconds>,v1=<hex>

// Verify (Node): recompute over the RAW body, reject stale timestamps
const [t, v1] = header.split(',').map(part => part.split('=')[1]);
const expected = crypto.createHmac('sha256', endpointSecret)
  .update(`${t}.${rawBody}`).digest('hex');
const fresh = Math.abs(Date.now() / 1000 - Number(t)) < 300;
const valid = fresh && crypto.timingSafeEqual(Buffer.from(v1, 'hex'), Buffer.from(expected, 'hex'));

Delivery bodies are { id, event, createdAt, data } where id is unique per delivery. Deduplicate on it, since retries re-send the same id.

CSV exports

For spreadsheet-driven reconciliation without code: signed-in org managers can download runs, the deficiency register, labor hours (worker × site × day), and the equipment register from Settings → Integrations and the Capital plan. Cells are formula-escaped; date ranges via ?from=YYYY-MM-DD&to=YYYY-MM-DD.