HIPAA first-enablement runbook
This runbook stands alone. Every curl command and expected response is inline, so a compliance officer can print it, follow it end to end, tick each box, and hand the result to operations — without chasing the pointer links on the wider HIPAA onboarding walkthrough, which remains the page for context and explanation.When this page applies
Run this sequence only when Protected Health Information (PHI) is entering your workspace — clinic messaging, patient notifications, care-coordination over voice or SMS. If PHI is never in scope, the default attestation isnot_required, both gates stay open, and nothing below applies:
- Enabling HIPAA mode returns
403 Forbiddenwhile BAA status is notexecuted. - Any PHI send is rejected with
422 HIPAA_BAA_REQUIREDuntil HIPAA mode is enabled.
https://api.orbit.devotel.io/api/v1 with an X-API-Key header on an owner or admin key. Sandbox keys (dv_test_sk_…) return the same envelopes without touching live compliance state:
{ "data": { … }, "meta": { "request_id", "timestamp" } }; errors are { "error": { code, message, status }, "meta": … }.
First-enablement sequence
1. Execute the BAA — owner
Distinguish who does what: steps 1a and 1b require an owner key (execute binds the legal agreement); 1c reads back with an owner-or-admin key. 1a — Attest that PHI is in scope. Move the organization fromnot_required to pending:
data.baa_status is pending.
1b — Execute with a type-the-name e-signature. typed_attestation must match signer_name exactly:
data.baa_status is executed, with baa_executed_at, expires_at (one-year term), and days_until_expiry populated. Dashboard equivalent: Compliance → BAA.
1c — Confirm the BAA is executed:
data.baa_status: "executed". Note days_until_expiry — an executed BAA expires after its one-year term and must be re-executed. Without executed status, the next step returns 403 Forbidden and PHI sends are rejected with 422 HIPAA_BAA_REQUIRED.
2. Enable HIPAA mode — owner
One call activates the controls: it turns on the per-organization HIPAA flag, arms the 365-day retention default, starts PHI access logging, and begins reporting BAA posture in the status object.- Dashboard: Settings → Compliance → HIPAA Mode Toggle.
- API:
executed, the call returns 403 Forbidden.
3. Restrict roles and API scopes to minimum necessary — administrator
HIPAA’s minimum necessary standard is tenant-owned. Provision honestly, with the controls that exist today:- Assign the
billingrole to finance-only staff — billing members are confined to billing, pricing, and usage and receive403on message-content endpoints. - Mint API keys with only the scopes the integration needs; grant
messages:readonly to services that genuinely read PHI-bearing content — every read lands in the PHI access log. - Known limitation: message-content reads are not restricted to a narrower set of roles beyond the billing confinement, and the message read endpoints do not require an operator-supplied reason code. Meet the standard by keeping workspace membership and API-key scopes tight. If your program requires per-role read restriction on message content, contact support@orbit.devotel.io before relying on it.
4. Designate PHI-adjacent audiences — owner / admin
Register the lists and segments whose members carry PHI so the campaign launch precheck gates them on the BAA. Without a designation, a PHI-bearing list launches like any other; with one, the precheck warns operators before a send goes out under an un-executed BAA. Endpoint semantics: PHI-adjacent audience designations.5. Set the retention window — owner
data_retention_days accepts 30–3,650; enablement arms the 365-day default, so set this only when your policy window differs:
data.data_retention.days echoes your value. Dashboard equivalent: Settings → Compliance → HIPAA → Data Retention. A background job deletes expired message content, call recordings, and media attachments; audit logs and PHI access logs are retained independently — the deletion clock does not erase your evidence trail. If you record calls, pin the voice region to match your residency obligations at the same time — see Voice Data Residency & Retention.
Verify after every enablement
Run all four reads after the last write, in order — owner or admin key — and compare each against its expected output:- The status object agrees with what you set.
Expected:
enabledistrue,baa_statusisexecuted,data_retention.daysmatches your window,disabled_atisnull. Treatencryption_algorithmas reporting-only — platform-wide at-rest encryption (Google-managed AES-256 on Cloud SQL), not a per-organization application-layer cipher. Do not cite it to an auditor as evidence that message bodies are individually encrypted at the application layer. - PHI access logging is recording. Exercise a message read in the dashboard or API, then page the log:
Expected: your read appears as an entry (
resource: "message:msg_…",reason: "read"). Pass the last entry’sidas?cursor=to page forward whilehas_moreistrue. - The designated-audience gate behaves as intended. Attempt a draft-campaign launch against one of the lists you designated in step 4. With the BAA executed it launches; run the same attempt against a scratch organization without an executed BAA to see the
422 HIPAA_BAA_REQUIREDrejection operators would hit. Details: PHI-adjacent audience designations. - The compliance-health score moved.
Expected: the HIPAA posture no longer reads as an open risk surface. Compare against a snapshot taken before step 1 — an open HIPAA posture scores as an unresolved risk until this sequence resolves it. Scoring semantics: Compliance health scores.
Checklist
Tick in order; the role on each line owns that line.- BAA executed and
baa_status: "executed"confirmed — owner - HIPAA mode enabled;
403on enable without BAA understood — owner - Membership trimmed to minimum necessary;
messages:readscoped — administrator - PHI-adjacent audiences designated — owner / admin
- Retention window set to your policy days — owner
-
GET /settings/hipaaverified;encryption_algorithmfiled as reporting-only — compliance officer - PHI access log returning entries — compliance officer
- Designated-audience gate exercised once — compliance officer
- Compliance-health score compared before/after — compliance officer
- Evidence binder generated via
POST /api/v1/compliance/binder/generateand handed off through the 24-hour download link — compliance officer (step 9)
9. Generate the evidence binder — compliance officer
The verification above proves the controls work today; the binder is what you hand to an auditor or a buyer’s procurement team. Generate the HIPAA pack of the evidence binder — it assembles PHI access logging, BAA posture, and your configured retention into a signed, download-ready pack recorded in your audit log:- Dashboard: Settings → Compliance → Binder → generate HIPAA.
- API:
202 with data.jobId and data.status: "pending". Poll GET /api/v1/compliance/binder/{jobId} until the download is ready, then hand the link off — it expires after 24 hours; if it lapses, generate a fresh one. If the binder opens with a tamper-alert banner, treat it as a signal to investigate before handing it to anyone external.
Related pages
- HIPAA onboarding: from BAA to audit-ready — the end-to-end walkthrough with context and explanation behind every step here
- HIPAA compliance controls — the full reference for every surface touched here
- BAA — Business Associate Agreement flow — the lifecycle this checklist sequences first
- PHI-adjacent audience designations — registry endpoint semantics
- Per-domain data retention policy — the retention surface beyond the HIPAA window
- Compliance evidence binder — the export that hands the posture to an auditor
- Compliance health scores — the rollup the final verification check compares
HIPAA posture is tenant-owned — Orbit provides the controls and the ledger; the legal determination that PHI is in scope is yours. This page is not legal advice.