Healthcare & telehealth

HIPAA compliant app development, control by control.

This page isn’t a claim about healthcare clients. We’ve published none, and you should distrust any studio whose vertical page implies otherwise. What follows is what the HIPAA Security Rule and the interoperability standards demand of a system, decision by decision, and how we’d build a telehealth product against them.

Talk through an architecture

Start here

A BAA with AWS doesn’t make your application compliant.

Almost every “HIPAA-compliant hosting” claim on the internet resolves to one artefact: a signed Business Associate Agreement with a cloud provider. That obligation is real, and it sits at §164.308(b). A covered entity may only disclose protected health information to a business associate under a written contract, and a subcontractor handling PHI needs one too. Your developer needs one. Your error tracker needs one. Your transactional email vendor needs one.

The agreement covers what the provider operates, which is infrastructure. Every major cloud publishes a list of HIPAA-eligible services and a shared responsibility model saying plainly that the customer owns the application. Row-level authorisation, audit logging on reads, session handling and what ends up in a log line all sit with the team writing the code, and nobody else. You can run an entirely non-compliant application on perfectly compliant infrastructure, and most breach settlements read exactly like that.

Strike one term from any proposal you receive: HIPAA-certified. No such accreditation exists. HHS certifies no vendor, no product and no development studio. What exists is third-party attestation against a framework, either HITRUST CSF or a SOC 2 Type II report scoped to the HIPAA criteria. We hold neither. If procurement requires one from your build partner, we are the wrong firm, and we’d say so on the first call.

Technical safeguards

§164.312, and which half you can’t retrofit.

Five standards. Some specifications are required, some are addressable, and most readers take that difference for required-versus-optional. It is not. Addressable means assess it, implement it if reasonable, and document the equivalent alternative if you don’t.

Access control

§164.312(a)

Unique user ID and emergency access required. Automatic logoff and encryption at rest are addressable.

Unique user identification is the one you can’t retrofit. A shared nurse-station login destroys every audit trail downstream of it, and no amount of later work reconstructs who read what.

Audit controls

§164.312(b)

Required. No addressable escape hatch.

Record and examine activity in systems containing ePHI. Reads count, not just writes. That’s a data-layer decision: a query interceptor or an outbox on every PHI-touching repository, written on day one or bolted on badly forever.

Integrity

§164.312(c)

Addressable mechanism to authenticate ePHI.

Prove a record hasn’t been altered or destroyed improperly. In practice that pushes you toward append-only clinical history with versioned amendments, rather than an UPDATE that overwrites the previous observation.

Person or entity authentication

§164.312(d)

Required.

Verify the person seeking access is who they claim to be. Session fixation, a reset flow that leaks account existence, or a JWT with no revocation path all fail this at the application layer. Your hosting provider can’t fix any of them for you.

Transmission security

§164.312(e)

Addressable integrity controls and encryption.

Addressable doesn’t mean optional. It means implement it, or document in writing why it isn’t reasonable and what equivalent measure you put in its place. Writing that memo credibly for transport encryption in 2026 is close to impossible.

Sitting above all five is the minimum necessary standard, and it’s the one that reshapes a schema. A role check at the route (is this user a clinician, yes, render the chart) satisfies nothing. Minimum necessary is a row-level and column-level question: this clinician, for this encounter, may see these fields of this patient, and the billing coder beside them may see the diagnosis codes but not the psychotherapy notes. You get there with Postgres row-level security or an equivalent policy layer in the data access path, plus a break-glass route that grants emergency access and screams about it in the audit log. Decide it in week one and it’s a schema convention. Decide it in month six and it’s a rewrite of every query, the same arithmetic we lay out in our piece on rewriting versus refactoring a legacy codebase.

Integration surface

Reading a record out of Epic is an OAuth problem, not a database problem.

Hospitals still run on HL7 v2. Pipe-delimited segments, ADT messages announcing an admission, transfer or discharge, ORU messages carrying observation results, moving over MLLP on a port somebody opened in 2009. Interface engines like Mirth Connect, Rhapsody and Cloverleaf exist because every site profiles the standard differently, and the Z-segments a given hospital invented are load-bearing. If your plan says “FHIR” and the counterparty says “we’ll send you an ADT feed”, you have an interface engine in your architecture whether you budgeted for one or not.

FHIR R4 is the better road. Treat it as a wire format rather than a schema to mirror internally. Modelling your own database as Patient, Encounter, Observation and DocumentReference resources feels tidy for a fortnight and then punishes you, because FHIR is deliberately permissive: almost every field is optional, cardinalities are loose, and extensions carry what matters locally. Keep a normalised domain model of your own and validate FHIR at the boundary, in both directions.

SMART on FHIR is how a third-party app gets authorised against an EHR, and the two launch modes are genuinely different products. EHR launch means a clinician opens your app from inside the chart; you receive a launch token, exchange it for an access token, and get launch context back, with the patient and encounter already in focus. Standalone launch means the user starts at your app and picks an EHR, which puts patient selection and scope negotiation on you. Scopes are the fiddly part: patient/Observation.rs versus user/Patient.r versus system-level backend access with a signed JWT client assertion and no human present at all.

Then the part no sprint plan survives. Registering an application with Epic’s vendor programme or Oracle Health’s equivalent, promoting it from sandbox to a real customer organisation, and getting that customer’s IT department to enable it is calendar time measured in months, and it isn’t yours to compress. Build against the public sandboxes from day one and keep the registration queue off the critical path. Any of this is on offer for a regulatory reason: the 21st Century Cures Act information-blocking rule is why patient-facing API access became table stakes rather than a differentiator.

Approach

How we would build a telehealth platform.

What follows is an illustration, not a description of delivered work. The telemedicine app architecture we’d propose puts every PHI read behind a single data access layer that emits an audit event with actor, patient, purpose and timestamp to an append-only store the application role cannot delete. That store has to outlive the record it describes. When a record is amended or purged, the trail of who read it must remain, so it can’t be a foreign key into the table it audits. Video runs through a HIPAA-eligible provider under a BAA rather than hand-rolled WebRTC, and clinical documents live in an object store with server-side encryption, deny-by-default policies and access logging turned on before the first upload rather than after.

The failure modes are boringly consistent, and three of them are logging bugs. PHI written into application logs and shipped to a third-party error tracker that has no BAA. Push-notification payloads carrying a patient name or an appointment reason, rendered on a lock screen by an operating system nobody in your compliance scope controls. The fix there is a content-free ping and a fetch after unlock, a decision that belongs in the mobile app architecture rather than patched later. Video-consult recordings landing in an unaudited bucket because a convenience feature shipped ahead of the retention policy. And session tokens with no server-side revocation, so a lost device stays authenticated for the life of the JWT.

The clinician and patient surfaces themselves are ordinary product engineering, built the way we build any Next.js web application with server components, a typed data layer, and real accessibility work, because a portal that fails keyboard navigation fails a meaningful share of the people it exists for. You can see how we write up scope and tradeoffs in the builds we have published.

AI on clinical data

De-identification is harder than your budget assumes.

Routing PHI to a language model is a disclosure. It requires an endpoint covered by a BAA with zero-retention terms in writing. The consumer tier of most model APIs isn’t that endpoint; the enterprise and cloud-hosted tiers generally are. Read the contract rather than the marketing page.

The tempting alternative is to de-identify first and then use anything. Safe Harbor at §164.514(b) lists eighteen identifiers you have to strip, including all dates more precise than a year and any age above 89. On structured fields that’s tractable. On free-text clinical notes it’s a genuinely hard extraction problem, because the identifiers arrive as “saw Dr Okafor at the Riverside clinic on the 14th” buried in a paragraph, and one missed name means the dataset was never de-identified at all. Budget it as its own project with its own evaluation set, the way we treat every extraction pipeline in our document processing automation work. Before any of it, an AI readiness assessment is the cheaper way to find out whether the use case survives contact with the constraints and the unit economics.

When not to hire us

Most clinics should buy, not build.

If what you need is scheduling, charting, e-prescribing, claims and a patient portal for a practice, buy a vertical SaaS. Athenahealth, DrChrono and SimplePractice already carry the certified EHR module, the clearinghouse relationships, the prescribing integrations and the compliance paperwork, and no custom build at any budget we’d quote reaches parity. Video is the same story. Buy a HIPAA-eligible telehealth vendor rather than commissioning WebRTC infrastructure.

Custom earns its place when the workflow is the product and no vendor sells it: a remote monitoring pathway, a specialist triage tool, a payer-side data product, an app that has to sit on top of an EHR through SMART on FHIR rather than replace one. That’s the boundary, and it’s the same one we draw in choosing between in-house, an agency and a freelancer.

On budget, our published bands apply here without a healthcare surcharge: platforms from $28,000, mobile from $20,000, MVPs from $24,000, AI pilots from $7,500. Integration count and audit surface move the number inside those bands, not the word HIPAA. One SMART on FHIR connection to a sandbox is a few weeks. Three EHR vendors, an HL7 v2 feed and a de-identified analytics path is a different project.

The bands above are estimates, shown in US dollars and drawn from comparable work already delivered, because no two projects carry the same scope. Your own quote is not an estimate: it is fixed in writing after scoping, before kickoff, and it does not move.

Send us the architecture question.

Tell us which systems you have to talk to and who’s allowed to see what. We will come back with a scope, a price and the parts we think you should buy instead.