The REST API is available on every plan, including the free tier, as is
SSO (SAML 2.0).
The REST API at /api/v1/ lets external tools read and update your compliance data. Authenticate with a Bearer API key:
Authorization: Bearer ohk_...
Keys carry explicit scopes. Read scopes (findings:read, assessments:read, remediation:read) gate GET; write scopes (*:write) gate POST/PATCH. Grant only what an integration needs, and set an expiry on write-capable keys.
A scope is necessary but not sufficient, on reads as well as writes. A scope answers "may this key touch findings at all"; it never answers "may this PERSON".
Every call is checked against the key owner's current role, and the check mirrors the corresponding screen in the app: if the owner cannot open a register in the dashboard, their key cannot read it through the API either. So a key owned by a contributor is refused the audit log, the incident register, webhooks, the compliance score and the training endpoints; a key owned by a read-only auditor is refused the remediation register outright, and is refused findings, policies, evidence, assessments and scans unless their auditor grant covers that scope. Findings and remediation are also row-scoped the same way the screens are: a contributor's key returns only records assigned to them.
Writes add two further requirements: the owner must hold an organization-admin role (for assessments and remediation, any non-auditor role), and your organization must have an executed Business Associate Agreement.
Point integrations at a key owned by an organization admin. A key inherits its owner's current role, so moving that person to auditor or contributor narrows what the key can do — reads included.
If any call returns 403 where you expect 200, check the key owner's role, the key's scopes, and your BAA status before regenerating the key. Regenerating does not change what a key is permitted to do.
GET /api/v1/{findings,assessments,remediation} — list with filters + paging (?limit= 1–100, ?offset=).GET /api/v1/{evidence,vendors} — read evidence metadata (never file contents) and vendors/BAAs.GET /api/v1/webhooks — list endpoints; ?catalog=1 lists subscribable events.POST /api/v1/remediation — create a task (returns 201).PATCH /api/v1/{findings,remediation,assessments} — update by id.POST/PATCH/DELETE /api/v1/webhooks — manage webhook endpoints.Findings and assessments are update-only via the API (findings are generated from assessments; assessments need question/scope setup done in the app).
scans:read / scans:write)Requires the network-scan module (enable it under Settings → Organization → Features). Lets you request scans, pull results, download reports, and manage recurring schedules.
GET /api/v1/scans — list scans (?status=, ?limit= ≤200), or ?id=<uuid> for one scan plus its full retest chain and severity counts.POST /api/v1/scans — request an automated scan. Body: either targets: [{type: ip|cidr|url, value}] or from_systems: true (collect from your ePHI systems & assets), optional assessment_id. Targets are SSRF-validated; private/reserved/malformed are rejected 422 and listed in the response's dropped. Returns 202 with the new scan id. 429 if you're at the concurrency limit.DELETE /api/v1/scans?id=<uuid> — cancel an in-flight scan (409 if it's already finished).GET /api/v1/scan-report?id=<uuid> — download the completed scan's report file (streamed bytes, not JSON). 404 until a report exists.GET/POST/PATCH/DELETE /api/v1/scan-schedules — manage recurring scans. Create with frequency (daily|weekly|monthly — daily is the tightest) and window_start_hour (0–23, the start of a 4-hour launch window).See the Network Vulnerability Scanning help page for scope best-practices and the retest workflow, and openapi.yaml for full request/response schemas.
Responses are JSON with a data array plus count/limit/offset (findings and remediation also include total). Errors return a non-2xx status with a single error key; an unhandled 500 additionally carries message and request_id. Keys are rate-limited to 100 requests/minute (see the X-RateLimit-* response headers). The API is on every plan; create and scope keys in Settings → API.
MCP (Model Context Protocol) lets an AI harness (Claude Desktop, Claude Code, …) read your compliance data, and — only if you switch it on — update a few records. Two ways to connect, both read-only by default (list/get); write access is opt-in and is described under "Write access is off by default" below:
/.well-known/oauth-protected-resource, registers automatically (DCR), and sends you through Prusik Health login + a consent screen; it then receives a short-lived, user-bound token scoped to your own read permissions. No key to paste. Revoke anytime under Settings → API.web/tools/mcp-stdio/bin.mjs with a read-scoped ohk_ key in OH_API_KEY (see web/tools/mcp-stdio/README.md).The assistant always acts with your permissions — it can never see or do more than you can, and every action is logged.
Write access is off by default. A connected assistant can read your data; it can only change data (update findings, create remediation tasks, add comments) if an org admin enables MCP write access under Settings → API and the connection was granted write scope. Enable it only if your agreement with the AI client's provider covers sending compliance data (which may include PHI in free-text fields) to that provider. Write actions still prompt the user to confirm in the MCP client.
See web/docs/CONTRACT-mcp.md for the full security model.