Open any top-ranking guide to setting up a referral program and most give the same instruction: tag your refer-a-friend links with utm_source=referral and utm_medium=referral, or some close variant. It reads like careful, UTM-literate advice. It is also the exact choice that guarantees you will never see referral program attribution as its own line in GA4's reporting.
- GA4's default channel group assigns the Referral channel using one rule: medium is one of
referral,app, orlink, with no distinction for who sent the link or why. - A referral app's own dashboard already knows exactly which advocate referred which friend. GA4 does not, unless you deliberately build a channel definition or custom dimension that tells it.
- Even a perfectly labeled link only gets you halfway, because most referral platforms attribute through a device-locked cookie that breaks the moment a friend switches devices between clicking and buying.
- The fix is a custom channel group keyed on a program-specific source, not a cleverer medium value, plus a direct reconciliation against the referral app's own ledger.
Why "referral" is exactly the wrong word to use
GA4 does not evaluate referral programs as a concept. It evaluates traffic sources against a fixed set of pattern-matching rules, and Google's own default channel group documentation spells out the Referral rule in full: a session lands in that channel when its medium is one of referral, app, or link. No source check, no campaign check, nothing that looks for a referral program specifically.
That rule exists because "referral" was never meant to describe refer-a-friend marketing. It is GA4's generic bucket for any inbound hyperlink traffic that does not carry a recognized organic search, paid, or email medium, which includes directory listings, forum posts, press mentions, and, if your referral app's default link uses utm_medium=referral, your own advocate program too. All of it lands in the same undifferentiated channel.
Most referral platforms ship with exactly that default, because utm_medium=referral is technically accurate in the plain-English sense: a friend was, in fact, referred. The label is honest. It is also indistinguishable, inside GA4, from a stranger finding your site through an unrelated backlink.
What the referral app already knows that GA4 never will
This is the part a channel-grouping fix alone cannot solve. A dedicated referral platform runs its own closed-loop ledger. ReferralCandy's own documentation describes the mechanism directly: each advocate gets a unique referral link, a cookie is set the moment a friend opens it, and a successful referral is logged when that friend completes a purchase while the cookie is still active, typically for up to a year.
Friendbuy's own glossary defines the same concept with more redundancy built in, combining a cookie, a coupon code, and a referral code so that attribution can survive more scenarios than a cookie alone, plus an explicit "attribution window," the number of days an offer stays valid once that connection is made.
Either way, the referral app knows precisely which advocate drove which friend's order, because that relationship is the entire product. GA4 knows none of it by default. It sees a session, a source, a medium, and a purchase event. The advocate identity, the referral code, the reward status: none of that reaches GA4 unless you explicitly push it as a custom dimension on the purchase event, the same way an order's coupon code has to be explicitly sent for discount code attribution to work at all.
The two ways this quietly breaks, and they point in opposite directions
Keep the default medium=referral. Every refer-a-friend click matches GA4's built-in Referral rule and gets grouped with any other inbound link traffic. You can see total Referral channel revenue. You cannot isolate what the program itself produced without a secondary filter on source, and if your referral app shares a generic domain-based source value with other referral traffic, even that filter will not cleanly separate it.
Invent a custom medium instead, something like referral_program or refer_a_friend, hoping GA4 will treat it as its own category automatically. It will not. A medium value that matches none of the default channel rules typically falls through to Unassigned or gets grouped by whatever rule it does happen to match, which is rarely the one you intended. You have traded one invisibility problem for a different one.
Both paths produce the same underlying failure: a founder or marketing lead looking at the channels report with no honest way to answer "how much revenue did the referral program actually drive this month," which is the exact question the program exists to answer.
The fix that actually separates the signal
GA4's custom channel groups exist for exactly this situation: traffic that the default rules would otherwise collapse into one bucket, but that your business needs to see as its own category. Google's own documentation demonstrates the same mechanism with a different example, carving a specific kind of traffic out of the default Referral channel by reordering a custom rule ahead of it, rather than accepting whatever the default happened to produce.
The practical setup for a referral program:
- Keep (or set) a consistent, program-specific
sourcevalue on every referral link, something distinctive likereferralcandyorfriendbuy, never the bare domain or a value shared with other traffic. - Build a custom channel group with a rule keyed on that source, not on medium alone, since medium is the overloaded field every other kind of referral-style traffic is also competing for.
- Name the resulting channel something explicit, "Referral Program" or the app's name, so nobody on the team has to remember which rule produced it.
- Reorder the custom rule ahead of the default Referral rule in the channel group, so matching traffic resolves to the specific channel first.
That step alone fixes the labeling problem. It does not fix the device gap underneath it.
The gap a channel fix cannot close
Even with a clean custom channel in place, a referral program's attribution still depends on whatever mechanism the app uses to connect click to purchase, and for most platforms that mechanism is a cookie tied to one device and browser. ReferralCandy's own troubleshooting documentation is explicit that a match is most reliable when the friend buys soon after opening the link on the same device, and recommends opening the link again if the customer has switched devices or cleared cookies in between.
That is not a GA4 problem. It is a structural limit of cookie-based attribution that affects the referral app's own ledger just as much as GA4's session data. A friend who taps a referral link in a text message on their phone, closes it, and completes the purchase on a laptop two days later can be a real, happily rewarded referral that both systems undercount, because neither one ever sees the two visits as connected.
Friendbuy's multi-signal approach, combining cookie, coupon code, and referral code rather than relying on one, is a direct response to that exact weakness. If your referral platform supports an equivalent fallback (a referral code typed in at checkout, not just a cookie), turning it on recovers some of the cross-device loss that cookie-only tracking cannot catch.
What to actually check on your own setup
- Open your referral app's dashboard and pull revenue and order count for a fixed date range. That number is your source of truth for what the program produced.
- Check what
sourceandmediumyour referral links actually carry today, not what the setup guide said to use a year ago. Defaults change between app versions. - Confirm whether a custom channel group already separates this traffic, or whether it is sitting inside the generic Referral or Unassigned bucket with everything else.
- Compare the app's reported revenue against whatever GA4 channel the links resolve to for the same window. A large gap points at the labeling problem above. A small, persistent gap after fixing that points at the device-locked cookie limitation instead.
- If the app supports a secondary attribution signal (a referral code entered at checkout, not just a cookie), confirm it is actually enabled, not just available on your plan.
Running that check honestly usually takes less time than the setup guide that told you to use utm_medium=referral in the first place.
A referral program that nobody can measure accurately is still spending money on rewards every time it converts. If your marketing analytics setup already struggles to reconcile paid and email channels against GA4, a referral program with its own silent attribution gap is rarely an isolated issue. It is usually one more symptom of the same underlying measurement gaps a focused audit would catch across every channel at once.
Keeping channel groupings, UTM conventions, and app integrations correct only gets harder as a referral program and the rest of the ad stack keep changing. An ongoing growth partner retainer is built to catch exactly that kind of configuration drift before it creeps back in every time an app updates its defaults.

