Attribution for medical device and DME revenue

A UTM schema for manufacturers selling through distributors

Build 7 min read

A manufacturer’s marketing team builds a campaign. The distributor puts it in its portal, forwards it in its own newsletter, and its reps paste the link into emails to clinics. Some of the budget came from a co-op agreement. A month later the analytics report shows traffic from Distributor, distributor, dist-portal, (not set) and the name of one rep who rebuilt the link by hand.

Nobody did anything wrong. Standard UTM parameters were designed for one advertiser buying media, and a distributor channel has at least three parties touching every link. The fields run out before the questions do.

What does this schema fix?

It stops the partner, the rep, the territory and the funding source competing for the same five UTM fields. utm_source becomes a closed list of platforms, never a partner name. Six added channel parameters carry the partner registry ID, the link’s position in the channel, the sharing rep, that rep’s territory, who paid, and the audience it was aimed at.

The result is that two questions channel teams actually get asked become answerable from the link alone. Which distributor’s promotion of this campaign produced engaged traffic? And what did the co-op money buy, separately from the manufacturer’s own spend?

The schema

Copy it whole. Every value list is closed, so a value not on the list is a tagging error that needs correcting.

UTM SCHEMA · MANUFACTURER → DISTRIBUTOR → PROVIDER
all values lowercase, [a-z0-9_-] only, no spaces, no partner or person names

── standard parameters ────────────────────────────────────────────────
utm_source           the property that delivered the click (closed list)
                     google | bing | linkedin | meta | youtube
                     mfr_email | mfr_site | dist_portal | dist_email
                     dist_site | rep_direct | print_qr | event_badge
utm_medium           how it was delivered (closed list)
                     cpc | paid_social | display | organic_social
                     email | partner_portal | partner_email
                     rep_link | print | event
utm_campaign         <fy>_<program>_<productline>
                     e.g. fy27_resupply-reminder_pap
utm_id               campaign id from the budget system; for co-op spend,
                     the co-op agreement id (never a free-text label)
utm_content          asset id from the asset library, e.g. a0417-v2
utm_term             paid search keyword only; empty everywhere else
utm_source_platform  who set the budget and targeting
                     mfr | dist | agency

── channel parameters (custom; capture on landing) ────────────────────
ch_partner           partner registry id, e.g. p00412
                     "none" when no partner touched the link
                     "unreg" when a partner is known but not registered
ch_tier              the link's position in the channel
                     mfr    manufacturer-owned asset, manufacturer-sent
                     dist   distributor-owned asset or send
                     prov   forwarded by a distributor to a provider
ch_rep               id of the person who shared it, prefixed by employer
                     mr_0231 manufacturer rep | dr_p00412_017 distributor rep
                     "none" for untargeted sends
ch_terr              territory of the rep in ch_rep, from the sales
                     territory table (never inferred from ch_partner)
ch_fund              who paid for the media or the send
                     mfr | dist | coop | mdf | none
ch_aud               who the link was aimed at
                     referrer   clinician who orders or recommends
                     supplier   distributor or DME supplier staff
                     facility   clinic, hospital or IDN buyer
                     patient    end user or carer

── worked example ─────────────────────────────────────────────────────
distributor rep emails a clinic a co-op funded resupply page:
https://example.com/pap-resupply
  ?utm_source=dist_email&utm_medium=rep_link
  &utm_campaign=fy27_resupply-reminder_pap&utm_id=coop-2027-014
  &utm_content=a0417-v2&utm_source_platform=dist
  &ch_partner=p00412&ch_tier=prov&ch_rep=dr_p00412_017
  &ch_terr=se-04&ch_fund=coop&ch_aud=referrer

── hand-off to the CRM (lead-source schema) ───────────────────────────
utm_medium  cpc                       → demand_channel paid_search
            paid_social|display       → demand_channel paid_social
            email                     → demand_channel email_outbound
            partner_portal|partner_email|rep_link
                                      → demand_channel referral_partner
            event                     → demand_channel event
            organic_social|print      → demand_channel unknown, until the
                                        CRM list gains a matching value
ch_aud      referrer → clinician_referrer   supplier → distributor_rep
            facility → provider_org         patient  → end_user
ch_partner  stored on the demand record as the promoting partner;
            it never writes transaction_partner

Why can’t the partner name go in the source field?

Because there are too many partners and their names are not stable strings. In 2024 Medicare data, 4454 suppliers filled CPAP rental orders nationally. Free text across that many values fragments on spelling and case, and analytics tools treat differently-cased values as distinct. A registry ID has one spelling.

Google’s own guidance is explicit about the case problem: “Keywords with different capitalization, such as Meta and meta, are treated as different values.” In a direct business that is a hygiene issue. In a channel business with thousands of possible partners, typed by dozens of people who do not work for the manufacturer, it guarantees a long tail of near-duplicate sources that no one will ever reconcile.

Putting the partner in its own parameter also frees utm_source to answer the question it was built for: which property delivered the click. A distributor’s portal and a distributor’s newsletter behave differently, and dist_portal versus dist_email keeps that difference visible across every partner at once, without a pivot table.

The partner ID must come from a registry the manufacturer owns: the same partner table the CRM uses. A partner who is known but not yet registered gets unreg rather than an improvised value. Counting unreg monthly shows how far the registry lags the channel.

Why is territory a separate parameter from partner?

Because a partner’s orders do not stay in one territory. Summing state-level supplier counts in the same CMS file and dividing by the national count shows the average CPAP rental supplier drew orders from 4.04 states. For heated tubing the figure was 5.95; for oxygen concentrators, 7.65.

Those ratios come from the dataset behind this piece, and they break a common shortcut: deriving territory from the partner’s address. If a partner in one state routinely fills orders from clinicians in four or more, the partner’s home state says little about where the demand sits. Of the 12 product codes checked, 8 had suppliers averaging two or more states.

So ch_terr records the territory of the person in ch_rep. That is the one fact about geography the link can know with certainty at the moment it is shared. Territory credit for the resulting demand is then a reporting decision, made with the rep, the partner and the eventual order in view, rather than a guess baked into the URL.

The exception is fitted products. The lumbar-sacral orthosis in the same data averaged 1.35 states per supplier, which is close to local. A manufacturer selling only products like that could defensibly infer territory from partner. One selling a mixed portfolio should not, because the rule has to hold for the widest-reaching line.

How does the co-op field work?

ch_fund separates who paid from who sent. A distributor can send a link the manufacturer funded, or promote on its own budget. Co-op and market development funds get their own values, and utm_id carries the co-op agreement ID, so spend under each agreement joins to its traffic without a spreadsheet.

This is the field finance will ask about first. Co-op money is usually committed against an agreement and reconciled against proof of performance. Tagging each co-op funded link with the agreement ID at build time means the proof is a filter on the report, with no quarterly scramble through a distributor’s screenshots.

utm_source_platform complements it. Google describes that parameter as “The platform responsible for directing traffic to a given Analytics property”. Here it records whose hands were on the budget and targeting: the manufacturer, the distributor, or an agency acting for either. Funding and control are different questions. A co-op campaign can be distributor-controlled and jointly funded, and keeping the two apart is what lets both be reported honestly.

How is channel tier different from medium?

utm_medium records the delivery mechanism. ch_tier records how far down the channel the link had travelled when it was clicked. A partner email is one medium, but it matters whether the distributor sent it to its own customer list (dist) or a distributor rep forwarded it to a clinic (prov).

The prov tier is the one most manufacturers cannot see today. It is the point at which the manufacturer’s content reaches the provider through someone else’s relationship, and it is often where the conversion actually happens. Without a tier value it reports as ordinary partner email and blends into the distributor’s bulk sends.

Where does it break?

In four places, all predictable. Portals that strip query strings, links rebuilt by hand, custom parameters no analytics tool reports by default, and print. Each has a fix, and every fix works the same way: it takes the typing out of human hands.

Partner portals and email platforms that rewrite links. Some portals wrap outbound links in their own redirect, and some strip parameters they do not recognise. Test every partner’s portal once with a live link before a campaign depends on it. Where parameters are stripped, use a manufacturer-owned short link that expands to the full URL, so the parameters live on the manufacturer’s side of the redirect.

Hand-built links. Any link a rep types will eventually be wrong. Links should come from a builder that offers only the closed lists and the partner registry, and reps should share links, not build them. Google’s guidance notes that “Missing UTM parameters will result in (not set) values being present in reporting”. A missing field is visible, which is better than a wrong one.

Custom parameters are not UTM parameters. Analytics platforms report the standard fields automatically. The six ch_ parameters need capturing on landing, into first-party storage and hidden form fields, or they vanish at the first page view. This is the one piece of engineering the schema requires, and it is usually a day of work.

Print and events. A QR code on a leave-behind cannot know which rep handed it over unless it was printed per rep. Either print per rep, which is cheap at small volumes, or accept ch_rep=none for print and measure it at the campaign level.

What the schema does not do. It records the path a link took. It does not record the order. Which partner eventually booked the sale is a separate fact, written by the order process, and the lead-source schema for distributor channels is where that belongs. The mapping block at the bottom of the spec is the join between the two: this schema tells the CRM how demand was created, and the CRM keeps it from being overwritten when someone else writes the order.

How does it connect to the rest of the funnel?

The link is where demand is first captured, so it feeds the demand record directly. utm_medium maps to the demand channel, ch_aud to the demand actor, and ch_partner is stored as the promoting partner. The booking partner is written later, by the order process, and never taken from the link.

That separation is deliberate. The partner who promoted a link and the partner who booked the order are often different companies, and in categories where suppliers reach across many states they are different more often than a territory map suggests. A link-level schema that tried to record the booking partner would be guessing. More on how this fits the wider attribution picture sits in the attribution pillar.

What is the smallest first step?

Close the utm_source and utm_medium lists and add ch_partner from the partner registry the CRM already holds. Those three changes remove most of the fragmentation in channel reporting on their own, and none needs engineering. Then add ch_fund before the next co-op cycle, and the remaining channel parameters when the landing-page capture is built.

The order matters. Closing the lists costs nothing and immediately stops new fragments appearing. ch_partner needs a registry, which most manufacturers already have in the CRM under another name. ch_fund pays for itself the first time a co-op reconciliation takes an afternoon instead of a week.

The rest (tier, rep, territory, audience) earns its place once a link builder exists, because by then adding a parameter costs nothing to the person sharing the link. A team that tries to roll out all six channel parameters to distributor reps before a builder exists will get six new ways to be wrong.

To test whether it is working, filter a month of traffic to ch_partner values and check that no partner appears under more than one spelling, that unreg is shrinking, and that every co-op funded session carries an agreement ID. If those three hold, the channel has become measurable. If they do not, look at the builder before changing the schema.

Want this kind of rigor pointed at your pipeline?

Book a Call