Reference
Data protection — what a practice needs to know
Written for a practice owner rather than a lawyer. It describes what data Mila creates, where it sits, who else touches it and what you are responsible for. It is not legal advice and it is not a substitute for advice on your own practice’s obligations.
Last reviewed 10 September 2026, settled against the source rather than against anything previously published here. Every status below describes the v0.1.0 build you can download; where the code has since moved on, the row says so. Each one is a fact about code and about a cloud account, and both have moved once already.
Mila v0.1.0 is a development preview. It is used by one dentist — its founder — in his own practice. Some of what a second practice would need (a contract, a data-processing agreement, an agreed answer to “whose vendor account is this”) does not exist yet, and is listed as an open item below rather than glossed over.
The short version
In v0.1.0, one thing leaves the machine: the appointment audio, to Speechmatics in the EU, to be turned into text. Every AWS Bedrock call in Mila is switched off in the build you can download.
Which build This page was read against commit 967d22f, the source the published v0.1.0 files were rebuilt from on 9 September 2026. Where the older 1 September files differed, this page now describes the current ones.
Everything Mila keeps lives on the computer it runs on, encrypted. There is no Mila server holding your patients’ data, because there is no Mila server — but local storage is not the same as local processing, and the audio upload above is real. Mila does not draft notes in this version; the drafting lane is built and has never been run.
Where your patient’s voice goes
This drawing used to sit on the homepage, where a visitor had to learn its notation before understanding the product. It belongs here, at a size where every destination and caveat can actually be read. Inside the outline is your computer; outside it is a named third-party service. A labelled crossing passes through the outline. Audio leaves once. Everything else that leaves is text.
Dashed box and dashed crossing: built, but not reachable in the build you can download.
The drawing in words
- 01 · Device. A clip-on microphone you wear, on 2.4 GHz to a USB dongle rather than Bluetooth.
- 02 · Local. Your computer. The recording is written to your own disk and encrypted there, with AES-256 and SQLCipher.
- Exit 1 — audio out. The first of the two crossings. Audio out, text back.
- 03 · Outside your computer. Speechmatics, EU: the only point at which patient audio leaves your machine. What comes back is a transcript — text, not audio — encrypted on your machine.
- Exit 2 — text out. The second crossing. Text out, draft back. Not reachable in v0.1.0.
- 04 · Outside your computer. AWS Bedrock, London. Text only, no audio, ever.
- 05 · Local. Your note, back home: encrypted on your disk, for you to read and edit. No note has ever been produced by this system.
Recordings and transcripts stay inside the outline, encrypted at rest. What would cross Exit 2 is more than the transcript; every field is listed in the inventory below.
The same drawing, as a table
| Data | Purpose | Destination | Region | Current or planned |
|---|---|---|---|---|
| Microphone audio | Capturing the appointment | The Mila app on your own computer, over a 2.4 GHz USB dongle | Your machine | Current |
| The recording, encrypted (AES-256, SQLCipher) | Storage until you delete the appointment | Your own disk. No Mila server, no account, no backup | Your machine | Current |
| The whole appointment recording, plus a configuration block | Transcription and speaker separation — Exit 1 | Speechmatics batch API | EU endpoint. Speechmatics is a UK company | Current |
| Your own Speechmatics API key | Authentication | Speechmatics | EU endpoint | Current |
| The transcript, coming back | Review and correction by you | Your own disk, encrypted | Your machine | Current |
| Traffic between the desktop app and the Chrome side panel | Showing appointments beside browser-based practice software | The loopback address on your own machine. Never bound to the network | Your machine | Current |
| Tooth references and dental terms in the transcript | Normalising notation to canonical form — “upper left six” becomes UL6 | Your own machine. A fixed rule, no model and no network call | Your machine | Current |
| Transcript word tokens | A second, model-based correction pass over the same tokens — Exit 2 | AWS Bedrock | London region, EU inference profile | Built — off until you add AWS keys |
| The draft-note payload: the transcript with clinical roles, the appointment type, the patient’s name when the app holds it, your style profile, and up to four of your own past notes, word for word | Drafting the clinical note — Exit 2 | AWS Bedrock | London region, EU inference profile | Built — off until you add AWS keys |
| The style-compilation payload: the full text of up to thirty of your past notes, at set-up | Working out your house style — Exit 2 | AWS Bedrock | London region, EU inference profile | Built — off until you add AWS keys |
| Two quality-check payloads: a draft note, and the transcript beside it | Checking a draft before you see it — Exit 2 | AWS Bedrock | London region, EU inference profile | Built — off until you add AWS keys |
| The drafted note | Reading and editing by you | Your own disk, encrypted | Your machine | Planned — never produced |
Current means it happens in the shipped build during normal use. Planned means the code exists but no ordinary user of v0.1.0 can make it fire; the row below each one in the inventory says exactly why. No note has ever been generated by this system, by any means.
The data-flow inventory
One table, dated, and the full version of the drawing above. The homepage carries a short summary rather than any of this; where the two differ, this page is the one settled against the source. Three words are used precisely:
- Active — it happens in the shipped build during normal use.
- Disabled — the code exists and is wired, but no ordinary user of v0.1.0 can make it fire.
- Planned — not built.
| What is sent | Why | Where it goes | Status in v0.1.0 | Deletion | How we know |
|---|---|---|---|---|---|
The whole appointment recording, as one audio file, plus a configuration block: language en, enhanced model, speaker separation on, and the dental word list when it is not empty |
Transcription and speaker separation | Speechmatics batch API, their EU endpoint. Speechmatics is a UK company | Active from the moment you paste your own Speechmatics key into Settings. With no key, recordings sit at “Waiting” and nothing leaves | The job is deleted as soon as the transcript has been fetched and read, with up to three attempts. A job abandoned because polling timed out is deliberately not deleted and falls to the vendor’s documented seven-day sweep. Billing metadata — the job’s duration — outlives the content | Read in the code; the delete confirmed by a live probe on 26 August 2026. The seven-day sweep is the vendor’s documentation, not our observation |
| Your own Speechmatics API key, as an authentication header | Authentication | Speechmatics | Active | Held by Speechmatics as an account credential. Not ours to delete | Read in the code |
| Transcript word tokens — one record per word: its position, the word as recognised, the confidence, and the vendor’s anonymous speaker label — with a fixed instruction and a schema. No audio, no timings, no punctuation, no identifiers, no clinical roles | A second, model-based pass over dental terms and tooth notation, as a bounded set of edits rather than a rewrite. It is not what normalises tooth references today: that is a fixed rule that runs on your own machine, and it is listed as Current in the inventory above | AWS Bedrock, London region, EU inference profile | Disabled in the shipped v0.1.0 build. The path is live and reachable, but the only place that build can find AWS credentials is the process environment, and it has no setting that puts them there. A build you open by double-clicking finds none, and the pass records that it was skipped for want of credentials | Nothing to delete at our end. AWS’s no-retention default is unverified — see below | Read in the v0.1.0 source (ed9ed78): the credential gate, and the absence of any other place credentials could come from. Since that release a later commit (f02c8fe) added an AWS credential field to Settings, so a future build will be able to reach this path. It is not in anything published today |
| The draft-note payload: the transcript grouped by speaker with clinical roles attached, the low-confidence word list, the appointment type, the patient’s name when the app holds it, your style profile, and up to four of your own past notes, word for word, unredacted, about other patients | Drafting the clinical note | AWS Bedrock, London region, EU inference profile | Built — off until you add AWS keys. In the build you can download, the button and the channel behind it exist and are answered. Nothing is sent unless you paste an AWS access key and secret into Settings; leave them out and the call cannot be built. With keys present, a daily token limit on the account separately throttles it. | Only if you have entered AWS keys | Read in the source the published files were built from (967d22f): the handler is registered in the main process, credentials are read from encrypted settings and nowhere else, and the field list is the one the prompt builds. Checked in the packaged application bundle: the drafting and style channels are present. |
| The style-compilation payload: the full text of the historical notes you paste in at set-up, up to thirty at a time, each labelled with its appointment type. Storage identifiers are replaced with throwaway labels | Working out your house style, once, at onboarding | AWS Bedrock, London region, EU inference profile | Built — off until you add AWS keys, on the same gate as drafting | Only if you have entered AWS keys | Read in the code |
| Two quality-check payloads: a draft note, and the transcript alongside it for the check that asks whether every line traces to something said | Checking a draft before you see it | AWS Bedrock, London region, EU inference profile | Built — off until you add AWS keys. They run only over a draft, and no draft has yet been produced | Only if you have entered AWS keys | Read in the code |
| Traffic between the desktop app and the Chrome side panel | Showing the note beside browser-based practice software | The loopback address on your own machine, on one of four ports. Never bound to the network | Active | Local only | Read in the code |
| Encrypted audio files, the database (transcripts, notes, style profile, day list, settings), the two encryption keys, and the side panel’s pairing token | — | Never leaves the machine. No Mila server, no account, no analytics, no crash reporter, no update check | — | Held indefinitely until you delete an appointment in Settings, which removes its database rows and its audio file | Read in the code: the only two outbound hosts anywhere in the app are the Speechmatics EU endpoint and the AWS Bedrock London endpoint |
Two things that table will not let us round off
The correction payload is not anonymous. Mila asks you to say the patient’s name aloud at the start of the session, so that it has something to map roles with. That means the name is in the word tokens, along with anything else said in the room. The vendor’s speaker labels are anonymous; the words are not, and calling the payload anonymous would be doing work the word cannot do. The call runs only if you enter AWS keys in Settings; the design is the design and you should judge it now.
Your historical notes are first sent by the style compiler, not by drafting. Earlier versions of this page attached them only to note drafting. In the code they leave at set-up, in larger quantity, before a single appointment has been recorded. Both calls are unreachable today, so this is an exposure that has not yet occurred — which is exactly why it is worth reading before it does.
What data exists
| What | Where it lives | Encrypted |
|---|---|---|
| Appointment audio | One file per appointment, on the practice computer | Yes — AES-256-GCM, key held by the operating system |
| Transcripts, with speaker labels and notation corrections | The Mila database on the same computer | Yes — SQLCipher |
| Your style profile and the example notes it was built from | The same database | Yes |
| Today’s patient list, as you pasted or typed it | The same database | Yes |
| Settings, including your transcription key | The database and the operating system’s credential store | Yes |
| The side panel’s pairing token | Chrome’s extension storage on that computer | Chrome’s own protection |
Draft notes are not in that list, because none exists. The database has somewhere to put them; nothing has ever put one there.
A forty-minute appointment is roughly 230 MB of encrypted audio, and it accrues daily. That is why the data deliberately does not sit in the roaming part of a Windows profile: on a practice machine with roaming profiles, everything there is copied to the practice server at every logoff, and a growing pile of patient audio should not ride that.
Who processes what
Two companies are named in the code. Only one of them receives anything in v0.1.0.
Speechmatics — transcription
What they get: the appointment audio, and a configuration block. The block asks for English, their enhanced model, speaker separation, and a dental word list when one is set.
What the configuration does not say. Earlier versions of this page described it as UK English with a medical domain setting. Neither is true: the request asks for English generally, and the medical-domain flag is off. It is off because two identical submissions differing only in that flag produced identical output, and a flag that cannot be shown to do anything should not be sent with patient audio.
What they do not get: the patient’s name as a field, the appointment record, your practice details, or any identifier. Anything actually said aloud during the appointment is, of course, in the audio.
Where: their EU endpoint, processed in the EU. Speechmatics is a UK company based in Cambridge.
Why them: they are the only vendor that publishes a dental case for its own product — capture through masks, suction and handpiece noise, and separation of clinician from patient — and they already sit behind another UK dental product. That is their claim on their own page, not an independent measurement, which is why the bake-off against two competitors on real dental audio still has to happen before anyone outside the founder’s practice uses Mila.
One honest gap: Speechmatics has an account-level setting for whether your data may be used to train their models. No part of their API exposes it, so Mila can neither read nor set it. It is a check in their web console, and that check has not been done. It is on the open-items list below.
Amazon Web Services — every call, off unless you add keys
Mila has five distinct AWS payloads, set out in the table above: correcting dental terms, compiling your style at set-up, drafting a note, and two quality checks over a draft. None of them fires unless you paste an AWS access key and secret into Settings. The build you can download has the handlers and the settings fields; without keys the gate stays closed and no request is built. With keys, every call goes to Bedrock in London on an EU inference profile, and the account’s own daily token limit applies.
That matters for an evaluator in a practical way: the main page tells you that you need your own Speechmatics account and key. Expect Bedrock traffic only if you have also entered AWS keys; otherwise there is none.
Where they would go: Amazon Bedrock in the London region, on EU inference profiles. Anthropic’s own direct interface was rejected for this product because it offers no EU processing option.
What we have verified ourselves is the envelope: requests address the London endpoint on an EU profile, and the code enforces both with no way to override it from the environment.
Three things are Amazon’s word rather than ours, and no client can observe any of them: that EU inference profiles route inference only within EU regions; that prompts and completions are not retained by default; and the carve-out Amazon documents, under which inputs and outputs may be stored in certain other EU regions for abuse detection. Closing that last one needs an account-level control, and it has not been applied.
Nobody else
No analytics service, no error reporting, no update server, no advertising, no third-party library phoning home. If you run a network monitor against Mila and see traffic anywhere other than the transcription endpoint, that is a defect and we want the report.
Under UK GDPR, roughly where everyone stands
You are the controller. Your patients, your clinical record, your legal basis, your decision to record. Mila does not change any of that.
The vendors above are processors for the specific jobs described. Because Mila keeps everything else on your own machine, no third party holds a copy of your patients’ records.
The UK/EU question. Every cloud dependency is UK or EU by default; that is a written non-negotiable for this product, and a deviation would need its own documented decision. There are none today. EU processing is covered for UK personal data by the UK’s adequacy finding for the EU.
Open items, honestly. For a practice other than the founder’s, the following do not exist and would need to before any real patient data is processed:
- A contract and a data-processing agreement between the practice and Mila.
- A decision on whose vendor accounts are used — the practice’s own, or Mila’s on the practice’s behalf. That determines who signs which agreement, and it has not been made.
- The Speechmatics training-data console check, evidenced.
- The account-level control that would close Amazon’s abuse-detection carve-out, applied.
- A record-of-processing entry and, in all likelihood, a data protection impact assessment. Appointment audio of patients is exactly the sort of processing that warrants one. That is your practice’s document; we can supply the technical detail for it, and this page is most of what it needs.
We would rather list these than let a practice assume they are handled.
Retention
On your machine: indefinite until you delete it. Mila does not delete recordings, transcripts or notes on a schedule. Choosing a retention period for you would be the wrong call — retention of clinical records is your practice’s policy, and it is longer and more constrained than anything a note-taking tool should decide.
Deleting an appointment. Settings has a delete control: pick the appointment, confirm, and Mila removes its database rows and its audio file. Use it if a patient withdraws consent, or if a recording should not have been made.
At Speechmatics: the job is deleted as soon as the transcript has been fetched, with up to three attempts. Two qualifications, both of which earlier versions of this page left out. A job that had to be abandoned because polling timed out is deliberately left in place rather than deleted blind, and is swept by the vendor after seven days — that seven days is their documentation, not our observation. And the job’s billing metadata survives the deletion: the content goes, the record that a job of that length existed does not.
At Amazon: nothing is sent in v0.1.0, so there is nothing to retain. Were the calls switched on, Amazon’s no-retention default would apply — and that is Amazon’s documentation rather than something we or you could observe.
The note in your practice system is your record, under your retention policy, exactly as if you had typed it.
What to decide before using this in earnest: how long you keep the audio. It is the most sensitive thing Mila produces and, once a reviewed note is in the patient record, arguably the least useful. A practice policy of “delete the recording once the note is filed” is easy to operate with the control above, and it removes most of the risk on this page. We are not imposing it; we are pointing at it.
Consent
Mila assumes consent to record has already been obtained through your practice’s existing workflow. It does not ask for consent, does not record that consent was given, and will not stop you recording if it was not. Obtaining and documenting consent remains yours as the clinician, exactly as it is today.
That is a design decision rather than an oversight: a consent gate in the app would duplicate a process your practice already has, and create a second, weaker record of something that belongs in your own notes. Practically: whatever you do today before recording anything, keep doing. If a patient declines, do not press record.
The patient’s rights, in practice
Because everything lives on your machine, answering a patient request is a local operation.
- “What do you hold about me?” The note in your practice system, plus — if you have not deleted them — the recording and transcript in Mila. Both are on the practice computer.
- “Correct it.” The transcript is a record of what the microphone heard, and it cannot be edited in the app — but nothing reaches the patient’s record without you putting it there, and the note you write in your practice system is yours to word as you choose. You can correct who was speaking in the app, and that correction is kept with the transcript.
- “Delete it.” The Settings control removes the recording and transcript. The clinical note in the practice system is governed by your record-retention rules rather than by this request; that distinction is a normal one and your usual process applies.
- “Was a computer making decisions about me?” No. Mila produces descriptive documentation of what happened and what was said. It does not diagnose, does not recommend treatment and does not provide clinical decision support. So far no note has been drafted by a model at all.
- “Where does the recording go?” To one transcription company in the EU, and nowhere else. It is deleted there once the transcript comes back — with the two qualifications set out under Retention: a transfer abandoned partway is left for the vendor’s seven-day sweep, and the billing record of the job outlives its content.
Backups and recovery
Mila hasn’t got any. No backup, no sync, and no export beyond copying the note out. If the practice computer dies, the recordings, transcripts and style profile go with it.
Two things follow from that, and they pull in opposite directions.
- The notes that matter are in your practice system, because that is where you paste them. That is the record, and it is untouched by any of this.
- If you do back that machine up, be clear about what you are backing up: encrypted patient audio, at roughly 230 MB per forty-minute appointment, into whatever regime you already run. Make sure it is a regime you would be comfortable describing to a patient.
Optional encrypted sync in a UK or EU region is a planned later module. Restore tools are on the list. Neither exists today.
If something goes wrong
Write to Mila-app@protonmail.com. A dentist reads it, usually the one who built this. Send the shape of the problem — screen, time, what you were doing — and never patient content: ordinary email is not an approved channel for it, and this is not one.
- You think patient data went somewhere it should not have. Stop using the app, note the date, time and appointment, and tell us.
- A note contains something the appointment did not. That is the failure this whole system is built to prevent, and it is the single most important thing to report.
- The speaker labels are swapped — the dentist’s words attributed to the patient, or the reverse. Also top priority. Mila is built to say “who was speaking is not settled” and label nobody rather than guess, so a confident swap is a defect worth stopping for.
Where the detail is
Behind this page sit the project’s own working documents, which are read next to the code and which win wherever they and this page disagree:
| What it covers | Where to find it |
|---|---|
| Exactly what leaves the machine, field by field, and the architecture around it | Summarised in the table at the top of this page; the full note is in the project and we will send it on request |
| Encryption, threat model and known weaknesses | Summarised on the development status page; full note on request |
| Why Speechmatics, and what would change it | Summarised under “Who processes what” above |
| Why AWS Bedrock in London, and what was rejected on residency | Summarised under “Who processes what” above |
| What is proven and what is not, item by item | Development status |
These are not published as files today, which is a gap and we know it. Ask and you will get the extract rather than a summary of it.