Trust centre

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.

  1. 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.
  2. 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.
  3. 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.
  4. 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.
Data flow of one patient submissionPatient’s browserwidget iframe on thepractice’s websiteCloudflare Turnstilebot check — device signals onlyAWS S3, Londonphoto via 120-second signed URLdeleted ~45 min after the jobAWS Lambdaenquiry: name, email, phoneGoogle Cloud Vertex AIface crop → image;simulated image → videoSupabase Postgres (EU)enquiry record, nulled at 30 daysThe practicedashboard + email(Resend, or AWS SES in HIPAA mode)
Solid arrows carry patient data. The dashed arrow is the simulated result, shown back to the patient and to the practice in its dashboard. The close-up in the practice’s email is cut from the patient’s original photo, not from the simulated result.

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.

ProviderWhat 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 ServicesS3 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.
SupabaseThe enquiry record (without the patient’s name, contact details or notes for HIPAA-mode practices) and job metadata; practice accounts and authentication.
VercelHosts the application and the widget; runs the rendering orchestration. Enquiry intake does not pass through it.
CloudflareContent delivery and DDoS protection for dentalreel.com; Turnstile bot check in the widget (visitor IP and browser signals only).
ResendTransactional 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 WorkspaceOur 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.
UpstashRate-limit counters, and a patient’s email address for up to 55 minutes when they ask for the video before it is ready.
TelegramOperational 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 GeminiBrand detection from a practice’s own website when its widget is set up. No patient data.
SentryError 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.
StripePractice 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

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.

PageConsentNon-dentalreel.com hosts contacted
The widget on a third-party test page (×3)coldchallenges.cloudflare.com (Turnstile) — nothing else
/embed/demo — the widget (×3)coldchallenges.cloudflare.com (Turnstile) — nothing else
/try — public demo, photo upload (×2)coldnone
/us/check — practice scan (×2)coldchallenges.cloudflare.com (Turnstile) — nothing else
/agencies — as an invited agency sees it (×2 + ×2)cold and acceptedour S3 bucket (demo media) — nothing else
/ and /us — home pages (×2 + ×1)acceptedour S3 bucket (demo media) — nothing else
/register/agency — agency enquiry formacceptednone
/register/clinic, /signup — sign-up formsacceptedour S3 bucket (demo media) — nothing else
/register/check-email — sign-up thank-you pageacceptednone
/welcome — checkout thank-you page (×2)acceptednone
/checkout — paymentacceptedstripe.com (payment form) — nothing else
/trust — this page (×1 + ×1)cold and acceptednone

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.