Medical Clinic Technology

How to Attribute Patient Bookings to Ads Using UTM + DrChrono

Running ads for a clinic or medspa gets expensive fast. Google Search for aesthetic treatments, Meta campaigns for new-patient specials, local display — the cost-per-click on medical keywords is high enough that you can burn through a meaningful budget in a week and not know whether it worked.

The tool everyone has for tracking ad performance — UTM parameters on ad links — solves the problem in theory, as long as you can see UTMs on the other end of the funnel. That's where DrChrono practices hit a wall. There's no native way to get the UTM from an ad click onto the appointment record in DrChrono. And if you're using a third-party booking tool, attribution data often ends up in Google Analytics or a spreadsheet that never connects to the actual patient or the actual booked appointment.

We spent a while doing it wrong before we built something that works. Here's the right approach.

Why "I Can See Clicks in Analytics" Isn't Enough

Google Analytics — or Meta Events Manager — can tell you how many people clicked, how many reached the booking confirmation page, and how many conversions fired. What it can't tell you:

  • Whether the booked appointment actually showed up
  • Whether that patient became a repeat visitor
  • What they came in for versus what the ad said
  • Whether the $200 cost-per-acquisition on that campaign actually produced a profitable patient

Those answers live in DrChrono. The appointment record, the billing line items, the clinical notes — that's where the patient's real lifetime value is captured. Analytics can't see any of it, and DrChrono can't see the ad. UTM attribution is the bridge. But you have to build it carefully.

The Naive Approach and Where It Breaks

The intuitive solution is to pass UTM parameters through the booking form and write them somewhere you can read them. That part is correct. What breaks is where "somewhere" ends up being.

The most common failure mode: a clinic builds a booking form that captures UTMs and fires a conversion event to Google Analytics or the Meta Pixel containing the patient's name, appointment type, and UTM source together. That's a HIPAA violation — sending protected health information to a third-party analytics tool without a Business Associate Agreement is exactly the kind of data flow that creates liability.

The second failure mode: capturing UTMs in a Google Sheet or a standalone CRM without a BAA. The attribution data is accurate, but it's sitting in a non-covered system.

The third: not capturing UTMs at the server level at all, relying entirely on browser cookies that get wiped by iOS privacy changes, ad blockers, or the patient switching devices between clicking the ad and completing the booking.

The Architecture That Works

The principle is the same one that governs compliant booking generally: PHI and attribution data both land inside DrChrono — your BAA-covered system of record — and nowhere else.

Here is how we implement it.

Step 1: Capture UTMs at page load on the booking page

When a patient arrives at your booking page from an ad, the URL contains UTM parameters:

/book?utm_source=google&utm_medium=cpc&utm_campaign=botox-june&utm_content=ad-variant-a

JavaScript on the page reads these at load time and stores them in sessionStorage. If the patient navigates through multiple steps before submitting, sessionStorage keeps them. If no UTMs are in the URL (organic or direct traffic), the session values stay empty and we store the source as "direct."

Step 2: Pass UTMs to your HIPAA-eligible backend only

When the patient submits the booking form, everything — name, contact info, requested service, provider preference, appointment time, and UTMs — goes to a backend service you control. That backend is hosted on infrastructure with a BAA in place: Cloudflare Workers, AWS with their HIPAA eligibility program, or Google Cloud with a signed BAA.

No PHI or UTMs touch your public website server. No PHI or UTMs go to Google Analytics or the Meta Pixel at this step. The booking page itself stays dumb — it only shows availability and submits to the backend.

Step 3: Write the UTMs to the appointment in DrChrono

This is the key step. The DrChrono API lets you attach arbitrary data to appointments through custom appointment fields or custom_vitals. We write the UTM source, medium, campaign, and content variant directly onto the appointment record at the moment of creation.

The field mapping we use:

  • utm_source → custom field "Ad Source"
  • utm_medium → custom field "Ad Medium"
  • utm_campaign → custom field "Campaign Name"
  • utm_content → custom field "Ad Variant"

Once these fields are on the appointment in DrChrono, they travel with the patient's record. When you pull appointment data through the DrChrono API — into a revenue dashboard, a reporting view, or a patient-level report — the attribution data comes with it. The click and the patient are permanently joined inside the covered system.

Step 4: Fire your conversion event server-side, without PHI

After the appointment is created in DrChrono, the backend fires a server-side conversion event to Google Ads or Meta via their respective Conversions APIs. This event carries the UTM data and a hashed conversion identifier (the DrChrono appointment ID), but not the patient's name, date of birth, or treatment type. The ad platforms get the signal they need for bid optimization; PHI stays inside DrChrono.

The goal is not to avoid touching PHI — it's to make sure PHI only ever touches systems with a BAA in place. Server-side Conversions APIs exist precisely so you can send attribution signals without routing patient data through a browser-side tag.

What You Can Do With the Data

Once UTMs live on DrChrono appointment records, the reporting possibilities open up considerably. We surface these in the same operator dashboard layer we've built for daily revenue visibility and patient flow:

  • Cost per booked appointment by campaign — pull appointments with a given campaign UTM, count them, divide into ad spend for that period. Real CPAs, not modeled ones.
  • Show-up rate by ad source — compare no-show rates across campaigns. If one campaign drives bookings that no-show at twice the rate, the effective CPA doubles.
  • Revenue by campaign — join appointment records to billing line items through the DrChrono API. The same attribution chain that connects click to booking also connects it to collected payment.
  • Repeat visit attribution — track whether patients acquired through a specific campaign come back. The UTM on the first appointment is the anchor for the entire relationship.

None of these numbers are available from Google Analytics or the Meta dashboard alone. They require joining ad source data to clinical and billing records — which means they require UTMs to live in DrChrono.

Connecting the Dots

The point isn't only HIPAA compliance. It's that the metrics that actually matter — collected revenue per patient by acquisition source, show rate by campaign, patient lifetime value by channel — require attribution data and clinical data to be in the same place.

Analytics can tell you about clicks. DrChrono tells you about patients. The custom fields written at booking time are the bridge between the two. If you're currently measuring campaign success by Analytics conversions rather than by actual collected revenue per booked patient, you're making budget decisions with incomplete information.

This attribution layer is one of the higher-leverage things a growing clinic or medspa can build. It doesn't require changes to DrChrono, doesn't touch your existing billing workflow, and doesn't require a new analytics platform. It requires a correctly architected booking integration and a few custom fields on the appointment record. You can read more about how this fits into the broader booking and DrChrono integration work we do.

If you want to set this up or you've started and stalled — on the DrChrono custom field configuration, the OAuth flow, or the server-side conversion API — reach out and describe where you are. We can usually scope the build and identify the gaps in one conversation.

Want this built for your practice?

Tell us what DrChrono can't do for you yet — we'll come back with a concrete proposal.

Start a conversation →