Data flows
Visual walkthrough of where patient data lives at each stage - booking, voice calls, clinician review, audit logging - and which sub-processors see what.
This page exists so your DPO or auditor can trace any data element from collection to retention without having to read code.
End-to-end patient journey
Loading diagram…
Where data sits at each moment
| Data | At rest | In transit | In memory |
|---|---|---|---|
| Patient name / phone / email | AES-256-GCM encrypted in patients table | TLS 1.2+ | Decrypted only inside the Go service during request handling |
| Clinical notes | Postgres TDE + AES-256 for sensitive fields | TLS 1.2+ | Short-lived request context |
| Voice audio | Azure Blob with immutable policy, 7-year retention | SRTP via LiveKit | Memory during the call only |
| JWT tokens | Not stored server-side (only jti in Redis if revoked) | TLS 1.2+ + httpOnly cookies | Browser cookie jar (httpOnly, inaccessible to JS) |
| Redis session data | Azure-managed encryption at rest + TLS 1.2+ | TLS 1.2+ | 24-hour inactivity TTL |
Which sub-processor sees what
| Sub-processor | Receives | When | Duration |
|---|---|---|---|
| Microsoft Azure | All platform data | Always | Contract term + 30 days |
| Speechmatics | Voice audio stream | During active call | Audio not retained by Speechmatics |
| Cartesia | Text (post-scrubbing) for TTS | During active call | Not retained |
| Groq / Anthropic / OpenAI | PII-scrubbed prompt text | During voice / agent inference | Provider retention per DPA |
| Stripe | Card data (via Stripe.js) | At payment | Card tokens retained by Stripe |
| Bandwidth | E.164 phone number + SMS body | At send | Standard telco retention |
| Mailgun | Email address + rendered body | At send | 30 days sendgrid logs |
| Dentally | Whatever the clinic chooses to sync | Real-time via their API | Per clinic's own Dentally contract |
See Sub-processors for the DPA status of each.