How the smile simulator handles patient data, and why it is built this way
Written for the person at an agency or a dental group whose job is to check this before anyone signs. The first part explains why the simulator is built the way it is. The second describes what happens to one patient submission, in the order the patient experiences it. The third is our own tracker scan applied to our own site. It is not a legal notice — the contractual documents are the Data Processing Agreement, the sub-processor list and the privacy notice.
Last reviewed 10 September 2026. Security or privacy questions: privacy@dentalreel.com. Operated by Implants Local Ltd (company number 16197776), trading as Dentalreel.
Why it is built this way
A smile simulator sits at the most sensitive moment on a dental website. A patient uploads a photograph of their face and then, if they like what they see, hands over their name and phone number. On most practice websites the page around that moment is also running advertising and analytics tags.
Those tags have become the subject of litigation and regulatory attention in US healthcare. The best-known example in dentistry is Donnelly v. Aspen Dental Management, a class action alleging that tracking tools on the company’s website passed information about visitors, including what they typed into forms, to Meta and Google between 2022 and 2025. It settled in 2025 for about $18.5 million; the company denied the allegations and settled to avoid the cost of litigation. Regulators have been there too: the US health-privacy regulator issued guidance on website tracking technologies in December 2022 (revised in March 2024, and partly set aside by a federal court that June), and the Federal Trade Commission took action in 2023 against GoodRx and BetterHelp over advertising pixels on health websites. Whether any of this matters for a particular practice is a question for the practice and its own advisers; we do not make that call, and nothing on this site does. What we could do was build ours so that the question does not arise inside the simulator.
The simulator is an iframe served from our domain, not code that runs on the practice’s page.Tags on the practice’s site cannot see inside it: not the photo, not the form, not the result. Our one-line loader does nothing on the practice’s page beyond placing the frame and announcing a single named event, carrying no data, when an enquiry completes.
Everything the simulator sends goes to our own servers.Face landmarks are computed in the browser. The photo goes straight to our storage bucket. Enquiries go to our intake function. The one outside party the frame contacts is Cloudflare’s bot check, which sees device signals and nothing the patient typed or uploaded.
We run no marketing tags on dentalreel.com.No advertising pixel, no analytics tag, in any consent state. A company that audits other people’s tags should not be asking its own visitors to weigh a consent banner.
The scanner we point at practice websites is pointed at us as well. It runs against dentalreel.com nightly, with an allow-list rather than a block-list: a request to any host we have not named fails that nightly audit of production. The output is published below.
This page describes; it does not promise. You will not find absolute claims here. Whether a system is compliant or secure enough for your purposes is a conclusion for you to reach, not a claim for us to make. The commitments we do sign are in the documents linked above.
One patient submission, end to end
The simulator runs as an iframeserved from dentalreel.com, placed on the practice’s own website by a one-line loader. Everything the practice’s page loads around it — its own analytics, its own pixels — is the practice’s configuration and never enters the iframe. The iframe itself contacts one third party: Cloudflare Turnstile, the bot check that protects the rendering quota. It receives browser and device signals for that purpose only — no photo, no form field.
- The photo. The patient takes or uploads a selfie inside the widget. Face landmarks are computed in the browser, in a Web Worker; nothing about the face is sent anywhere for that step. The photo is then uploaded by the browser directly to an AWS S3 bucket in London (eu-west-2) using a signed URL that is valid for 120 seconds and usable once. That bucket sits under our AWS Business Associate Agreement.
- The simulation.Our rendering service reads the photo from that bucket and sends a crop of it around the patient’s face (or, if no face was detected, the whole photo, resized) to Google Cloud Vertex AI, which returns the simulated image. For the short video, the simulated image (not the original photo) is sent to Vertex AI’s Veo model. Outputs are stored in S3 and shown to the patient in the widget over signed links.
- The enquiry.If the patient chooses to contact the practice, the widget collects name, email, phone and any notes, and posts them to our lead-intake function on AWS Lambda. The record is stored in our Supabase Postgres database (EU); for a practice in HIPAA mode the patient’s name, contact details and notes are stored only in AWS DynamoDB in London under our AWS Business Associate Agreement, and the Supabase record holds the enquiry without them. The practice receives the enquiry in its dashboard and by email — name, contact details and, unless the patient unticks it, a close-up of the mouth cut from their original photo — sent through Resend, or through AWS SES with TLS required for practices running in HIPAA mode. A copy of that email goes to our own team’s mailboxes on Google Workspace. If the patient asks for the video by email before it has finished rendering, their email address is held in Upstash Redis for up to 55 minutes so the link can be sent, then expires.
- What we keep, and for how long.The photo and the landmark file are queued for deletion about 45 minutes after the job completes, with a one-day lifecycle rule on the bucket as a backstop. Rendered outputs are removed on the same queue, with an eight-day lifecycle backstop. The enquiry record (name, email, phone, notes) is nulled after 30 days by a scheduled job; the practice keeps its own copy from the email and dashboard. Our team’s copies of enquiry emails sit in our Google Workspace mailboxes and are not on that 30-day schedule. Operational alerts to our team carry the practice name and a job identifier, not the patient’s details.
What the simulator sends to us, besides the submission
So that a practice can see how its simulator is used, the widget reports usage events to our own server (and nowhere else): which step the visitor reached, whether the slider was moved, whether an enquiry was completed. Each batch carries the practice’s embed key, a random session identifier, the surface (embedded or hosted), a device class (mobile or desktop), and the address of the practice page the frame is on — not the visitor’s photo, not anything they typed. Automated browsers are not counted.
When an enquiry is submitted, the widget also records where the visitor came from: the referring page, the landing page, any UTM parameters on it, and any advertising click identifier in the URL (Google’s gclid, gbraid and wbraid, Meta’s fbclid, Microsoft’s msclkid and TikTok’s ttclid). The practice sees this against the enquiry in its dashboard. The referrer, landing page and UTM values are nulled with the rest of the enquiry at 30 days; click identifiers are held for 90 days, the window in which an advertising platform will accept an offline conversion. The practice can download its click identifiers with the enquiry time as a file in Google Ads’ offline-conversion format, or receive each one by signed webhook to an endpoint it controls. We do not upload anything to any advertising platform ourselves; what a practice does with its own file, from its own advertising account, is the practice’s decision. Where an agency introduced the practice, the agency can receive that export for a practice outside the UK only once the practice has authorised it — a tick-box on the data-protection agreement the practice accepts itself, or a switch on its own dashboard, which can also withdraw it.
Sub-processors, and what each one touches
The contractual list, with locations and transfer mechanisms, is at /legal/sub-processors. The table below describes what reaches each provider.
| Provider | What it processes |
|---|---|
| Google Cloud (Vertex AI) | A crop of the patient’s photo around the face (the whole photo, resized, if no face was detected), for the simulated image; the simulated image, for the video. Not the enquiry. |
| Amazon Web Services | S3 in London: the photo, the landmark file, the rendered outputs. Lambda: the enquiry intake and rendering. SES: enquiry email for HIPAA-mode practices. DynamoDB in London: the patient’s name, contact details and notes for HIPAA-mode practices; a mirror of the same for others. |
| Supabase | The enquiry record (without the patient’s name, contact details or notes for HIPAA-mode practices) and job metadata; practice accounts and authentication. |
| Vercel | Hosts the application and the widget; runs the rendering orchestration. Enquiry intake does not pass through it. |
| Cloudflare | Content delivery and DDoS protection for dentalreel.com; Turnstile bot check in the widget (visitor IP and browser signals only). |
| Resend | Transactional email: the enquiry to the practice (name, contact details, and the close-up of the mouth cut from the patient’s original photo); the patient’s own video link if requested. |
| Google Workspace | Our team’s copies of the enquiry emails sent to practices (the same content as above). For HIPAA-mode practices the copy goes only to dentalimplantslocal.com mailboxes, which our Google Workspace Business Associate Agreement covers. |
| Upstash | Rate-limit counters, and a patient’s email address for up to 55 minutes when they ask for the video before it is ready. |
| Telegram | Operational alerts to our team: the practice name and a job identifier, no patient details. Separately, the dentist demo on /try (a dentist trying the simulator on their own photo) posts that visitor’s preview with their form details to the same private channel; an hourly job deletes that message once it is an hour old. If the preview cannot be attached, a text-only message with the form details is sent instead and is not deleted automatically. |
| Google Gemini | Brand detection from a practice’s own website when its widget is set up. No patient data. |
| Sentry | Error reports from our servers, with email addresses, phone numbers and signed links removed before they are sent. In the browser it runs only on our signed-in operator screens (dashboard, agency console, admin, onboarding, internal tools), not on public pages or in the widget. |
| Stripe | Practice billing only. Never patient data. |
The HIPAA position
A US practice can run the simulator in HIPAA mode and sign a Business Associate Agreement with us. In that mode the patient’s name, contact details and notes are stored only in AWS DynamoDB under our AWS agreement (our team’s copy of the enquiry email goes only to mailboxes under our Google Workspace agreement), the face landmarks never touch our Postgres database, the enquiry email goes through AWS SES with TLS required, and the rendering code refuses any AI provider that is not covered by an agreement. Where a practice is introduced by an agency, the practice accepts that agreement itself; the agency cannot accept it on the practice’s behalf, and the practice runs in demo mode until it has.
Our AWS Business Associate Agreement was executed on 14 July 2026 and covers the S3 bucket that holds patient photos, SES, DynamoDB and Lambda. Our Google Workspace Business Associate Agreement was executed the same day and covers the dentalimplantslocal.com mailboxes our team’s copies of HIPAA-mode enquiry emails go to. Our Google Cloud Business Associate Agreement was executed on 12 August 2026 and covers the Vertex AI models we use for HIPAA-mode practices: gemini-3-pro-image for the image and the generally-available Veo 3.1 models for the video. The rendering code is pinned to those for HIPAA-mode practices and refuses anything else.
Visitors whose connection locates them in Illinois cannot run a simulation: the biometric parts of the product are blocked for them because of that state’s biometric privacy law. The block follows the visitor’s location, not the practice’s.
What we do not do
- No advertising pixel or analytics tag loads anywhere on dentalreel.com, in any cookie-consent state.
- No conversion event is sent to any advertising platform when a patient submits an enquiry — from the widget, from our pages, or from our servers. The practice’s own export of its click identifiers, described above, is the practice’s action from its own account.
- No third-party analytics, error monitoring or session replay runs in the browser on any public page of dentalreel.com, or inside the widget on a practice’s site. The widget contacts dentalreel.com and Cloudflare Turnstile, nothing else. Browser error monitoring (Sentry) runs only on our signed-in operator screens; server-side error reporting never touches a visitor’s browser.
- No patient data is sold or shared for advertising. Sub-processors receive only what the table above says, to deliver the service.
- Patient photos are not used to train models — ours or Google’s, under the Vertex AI terms we operate on.
- One thing the widget does announce: when an enquiry is completed it posts a JavaScript event named
dentalreel_leadto the practice’s own page, carrying no patient data. Whether the practice’s own tags react to that event is the practice’s configuration on its own site.
The scan output
The scanner we point at practice websites, pointed at us: every public page, the enquiry and sign-up forms and their thank-you pages, the widget on our demo page, and the widget placed on a third-party test page — each loaded cold with no interaction, or with the cookie banner accepted. The list below is every non-dentalreel.com host contacted.
Scan run 10 September 2026, 14:46–14:50 UTC, against the production build deployed that afternoon (commit 9ad15b5), headless Chromium, no cookies, no prior visit. “Accepted” means the cookie banner’s “Accept all” was clicked before waiting. Hosts ending inamazonaws.com are our own storage bucket serving demo media.
| Page | Consent | Non-dentalreel.com hosts contacted |
|---|---|---|
| The widget on a third-party test page (×3) | cold | challenges.cloudflare.com (Turnstile) — nothing else |
| /embed/demo — the widget (×3) | cold | challenges.cloudflare.com (Turnstile) — nothing else |
| /try — public demo, photo upload (×2) | cold | none |
| /us/check — practice scan (×2) | cold | challenges.cloudflare.com (Turnstile) — nothing else |
| /agencies — as an invited agency sees it (×2 + ×2) | cold and accepted | our S3 bucket (demo media) — nothing else |
| / and /us — home pages (×2 + ×1) | accepted | our S3 bucket (demo media) — nothing else |
| /register/agency — agency enquiry form | accepted | none |
| /register/clinic, /signup — sign-up forms | accepted | our S3 bucket (demo media) — nothing else |
| /register/check-email — sign-up thank-you page | accepted | none |
| /welcome — checkout thank-you page (×2) | accepted | none |
| /checkout — payment | accepted | stripe.com (payment form) — nothing else |
| /trust — this page (×1 + ×1) | cold and accepted | none |
Nothing on any page contacted an advertising platform or an analytics service, before or after consent, and no request carried a form field.
The nightly audit (scripts/assert-no-third-party.mjs in our repository) runs the same check against production with an allow-list, not a block-list: a request to any host not named in it fails the run. It is a scheduled audit of the live site, not a gate on deploys.
The study this site cites
In August 2026 we read the public Google Tag Manager containers of 52,267 US dental practice websites; 44,849 were reachable. We classified what each container is configured to do — we did not submit any form, and a configuration is not proof that anything was sent. Of the reachable sites, 9.7% (4,349) are configured to send an advertising-platform conversion on the enquiry path: on the form-submit trigger, or on the page a patient reaches after submitting. That figure is a floor: server-side conversion traffic is invisible to any external read, and every correction we have applied since the first count has lowered the number, not raised it. The count regenerates from the study files with a script kept alongside them; that is the only figure we publish. A practice can read its own configuration at /us/check.
Last reviewed 10 September 2026. Questions to privacy@dentalreel.com.