Skip to main content

What gets sent, and what doesn't

The AI tools are the main route by which clinical content leaves your device, so this page is deliberately precise rather than reassuring. If you are assessing MedJot for an organisation, read this alongside Data flows.

Nothing is sent until you run a tool​

Autosave writes to the device only. Opening MedJot, building a report and exporting it involve no transmission of clinical content at all. The transmission happens when you press the button on an AI tool, and only then.

What is sent​

A summary built from your structured findings — the findings you tapped, the scores you completed, the observation sets you recorded, the ingestions you logged, and the free text you typed in the relevant sections.

The request is assembled from MedJot's internal state, not from the report text in the preview panel. This is a meaningful distinction: it means the content sent is a known, enumerable set of fields rather than whatever happens to be on screen.

Observation sets are sent under their own separate structure, and every set is included — the include-in-report toggle governs the ePRF only.

What is stripped before sending​

Redaction runs twice: once in the browser before the request is made, and again on the server before the prompt is assembled.

The two passes are separate copies of the same ruleset — one in the app bundle, one on the server. They are kept identical by a test that runs a shared corpus of realistic scene notes through both and fails the build if their output differs by a single character. Drift is caught mechanically rather than noticed later.

Both passes exist deliberately:

  • On the device, so identifiable text never crosses the network at all. This is the part that matters for the promise the product makes.
  • On the server, because a server must never trust what a client claims to have already done. Requests are redacted again on arrival regardless of what they contain.

The rules, in order​

What it matchesReplaced withExample
Email addresses[email]m.ellis@nhs.net → [email]
UK phone numbers — mobile or landline, spaced, hyphenated or +44[phone]07700 900123 → [phone]
NHS numbers — spaced, hyphenated, or run together against a label[NHS number]NHS 943 476 5919, nhs9434765919 → [NHS number]
UK postcodes, with or without the space[postcode]LS1 4AP, sw1a1aa → [postcode]
Written dates of birthDOB [date]DOB 3rd April 1948 → DOB [date]
Numeric dates[date]03/04/1948 → [date]
A name after a titleInitialsMrs Margaret Ellis → M.E.
A name after "named" or "called"Initialspatient called John Smith → named J.S.
A name after a relationship wordInitialsnext of kin son Peter → next of kin son P.

The order is part of the design, not incidental. The shape of the pipeline — illustrative, not the shipping source:

out = out.replace(EMAIL, '[email]'); // first: emails contain digits
out = out.replace(UK_PHONE, '[phone]'); // before NHS: an 11-digit mobile
out = out.replace(NHS_NUMBER, '[NHS number]'); // contains a 10-digit run
out = out.replace(UK_POSTCODE, '[postcode]');
out = out.replace(WRITTEN_DOB, 'DOB [date]'); // before the numeric date rule
out = out.replace(NUMERIC_DATE, '[date]');
out = out.replace(TITLED_NAME, toInitials); // Mrs Margaret Ellis -> M.E.
out = out.replace(NAMED_OR_CALLED, toInitials);
out = out.replace(RELATION_THEN_NAME, toInitials);

The relationship words that mark the next capitalised word as a person are an explicit list: next of kin, NOK, patient, pt, son, daughter, wife, husband, partner, spouse, mother, father, mum, dad, brother, sister, neighbour, carer, friend, landlord, GP, guardian, grandson, granddaughter, grandmother, grandfather.

Two strengths, and why there are two​

Some tools apply an additional rule that collapses any capitalised pair of words to initials — enough to catch a bare John Smith with no cue in front of it. That rule is on for the safeguarding tool and text assist, where the input is narrative.

It is off for differential diagnosis, ATMIST and GP handover. Collapsing every capitalised pair also turns Sinus Tachycardia into S.T., and a tool fed mangled clinical terminology gives worse clinical output — which drives clinicians toward whichever feature redacts least. That is a worse privacy outcome than the one it prevents.

This is a stated trade-off, not an oversight. The structured identifiers above — NHS number, phone, postcode, date of birth, address — are what actually re-identify a person, and those are removed on every route, in both modes, without exception. A protected list of common clinical pairs (chest pain, atrial fibrillation, pulmonary embolism, days and months, and around fifty more) survives collapsing even in the strict mode.

The whole payload, not a list of fields​

Redaction sweeps the entire request object recursively rather than naming the fields to clean:

function redactPayload(value, opts) {
if (typeof value === 'string') return redactPII(value, opts);
if (Array.isArray(value)) return value.map(v => redactPayload(v, opts));
if (isPlainObject(value)) return mapValues(value, v => redactPayload(v, opts));
return value; // numbers, booleans, null pass through
}

This matters more than it looks. A per-field approach depends on every future change remembering to add the new field to a list, and that is precisely how free-text fields once reached the model unredacted. Sweeping the object means a field added tomorrow is redacted by default, and there is no list that can fall out of date.

Measurements keep their words, never their identifiers​

Observation sets and reported ingestions are sent under their own keys and are exempt from name-collapsing — Rhythm Sinus Tachycardia and Sodium Valproate reach the model intact, because collapsing them destroys clinical meaning for no privacy gain. Vital signs contain no identifiers.

The exemption is narrow and one-way. Identifier stripping still runs on them:

in: Obs (09:05) - HR 130, BP 90/60, NHS 943 476 5919, 07700 900123
out: Obs (09:05) - HR 130, BP 90/60, [NHS number], [phone]

A name or number typed into an observation note is still removed. There is no path through the redactor that skips it.

Redaction on the way back, too​

The safeguarding tool redacts the model's response as well as the request, and its prompts forbid the model from producing or asking for a full name — people are referred to by role or initials. It applies the strictest handling in MedJot and never outputs a full name: not the patient's, not a family member's, not a professional's.

What else is bounded before it reaches a prompt​

  • Conversation history in the safeguarding interview is capped in length and in number of turns, and is re-redacted server-side even though the browser already redacted it — the server treats every field of an inbound request as untrusted, including ones it generated itself earlier.
  • Safeguarding categories come from a closed list. Anything not on it is dropped, not sanitised — there is no legitimate reason for arbitrary text to arrive in that field.
  • Text assist input is capped at 4,000 characters, and the field label at 40.
  • All AI routes are rate limited per account.

How this is kept honest​

The redactor is covered by tests that assert, among other things:

  • the client and server copies produce identical output across the whole corpus, in both modes;
  • every structured identifier is removed in both modes;
  • a normal set of vitals — BP 120/80, HR 88, RR 18, SpO2 96%, GCS 15, BM 5.4 — passes through completely unchanged, because a redactor that mangles observations is one clinicians route around;
  • the specific traps the rules were written for stay fixed, including capturing the name rather than the relationship word in next of kin son Peter;
  • the patterns run in linear time on adversarial input, so redaction can never itself become a way to hang the app.

The limits, stated plainly​

warning

Redaction is a safety net, not a guarantee. It is pattern matching, not named-entity recognition. It cannot reliably catch a name written into free text with no surrounding cue, an unusual identifier format, or a non-UK phone number or postcode.

It exists because clinicians under time pressure do type identifiable detail, not because doing so is acceptable. The real control is the standing instruction: keep patient-identifiable information out of MedJot in the first place — initials, ages and de-identified descriptions.

What is not sent, ever​

  • Your notepad — it is not part of the report and reaches nothing
  • Your saved templates
  • Your patient's identity, insofar as the guidance above is followed
  • The overdose calculator's threshold comparison — that stays on screen
  • Anything from a report other than the one you are working on

What is kept afterwards​

KeptNot kept
Which feature you ranThe text you sent
Token counts and costThe response you got back
When it ran, against your account

The usage log exists for billing and abuse prevention. It contains no clinical content because none is written to it.

Where it goes​

To Google Gemini, via MedJot's server. The server checks your entitlement, applies redaction a second time, and forwards the request. Google may process it outside the UK and EEA under their own data protection commitments — see Subprocessors.

Queued requests​

If a request fails for lack of signal and you choose to queue it, the payload is stored on your device, already redacted — so a queued job holds nothing the network would not have seen. No credential is stored with it; a fresh token is minted when it actually runs, and if a different user has signed in by then the job is discarded rather than run. See Queued AI requests.

The one-line version​

Running an AI tool sends a redacted summary of your structured findings to Google Gemini. The content is not stored by us. Everything else about the report stays on the device.