← All posts

Attribution Basics for Apps: First-Touch, Last-Touch, and UTM Hygiene

Attribution answers a deceptively simple question: which marketing effort gets credit for this user? Get it roughly right and you can stop pouring money into channels that don’t work. Get it wrong — or skip it — and you’re optimizing spend on vibes.

This is an intro, not a treatise on multi-touch modeling or SKAdNetwork privacy plumbing. The goal is to make you fluent in the two attribution models you’ll use 90% of the time, and to fix the boring data hygiene that quietly poisons most attribution reports.

First-touch vs last-touch: same data, different question

Imagine a user’s path before they convert:

  1. Sees your game in a YouTube ad
  2. A week later, clicks a Reddit post about it
  3. Searches your brand name and clicks a Google ad
  4. Installs and, three days later, fires purchase_complete

Who gets credit for that purchase? Both of the common answers are “correct” — they just answer different questions.

First-touch attribution gives 100% of the credit to the first interaction (the YouTube ad). It answers: what introduces people to us? Use it to evaluate awareness and top-of-funnel channels. First-touch over-credits discovery channels and ignores everything that closed the deal.

Last-touch attribution gives 100% of the credit to the last interaction before conversion (the Google brand-search ad). It answers: what closes the deal? It’s the default in most tools because it’s simple and maps cleanly to “the click right before the install.” Its blind spot is the mirror image of first-touch: it over-credits the closer (often brand search, which would’ve converted anyway) and ignores what created the demand.

Neither is “the truth.” A practical habit: report both side by side. When first-touch and last-touch disagree sharply about a channel, that gap is the insight. A channel that’s huge in first-touch but invisible in last-touch is doing awareness work that last-touch is stealing credit for — cut it based on last-touch alone and you’ll wonder why your “winning” channels dry up.

Capture attribution as event properties

Attribution isn’t a separate system — it’s properties you attach to the events you already track. The clean pattern: capture the acquisition source once, store it on the user, and stamp it onto the conversion events that matter.

Following a consistent snake_case taxonomy, an install event might carry:

event: app_install        # or first session_start
properties:
  utm_source:   "youtube"
  utm_medium:   "cpc"
  utm_campaign: "summer_launch_2026"
  utm_content:  "30s_trailer_a"
  referrer:     "youtube.com"
  landing_path: "/get"

Then, when the user converts, you don’t need to re-derive the source — you join the purchase_complete event back to the user’s first-touch (and last-touch) source on user_id. Because Keentics stores raw events in your own ClickHouse, first-touch is literally “the earliest source we saw for this user” and last-touch is “the latest source before the conversion” — both are a GROUP BY user_id away, not a black box:

-- first-touch source per user
SELECT user_id, argMin(utm_source, ts) AS first_touch_source
FROM events
WHERE utm_source != ''
GROUP BY user_id;

argMin(utm_source, ts) returns the utm_source from the user’s earliest row; swap to argMax and you have last-touch. Owning the raw events means you can switch attribution models after the fact instead of being locked into whatever your tool decided at collection time.

UTM hygiene: the boring part that decides everything

UTM parameters are the tags you append to your own outbound links — ?utm_source=...&utm_medium=...&utm_campaign=.... They’re how a click knows where it came from. They’re also where attribution data goes to die, because UTMs are free text and free text drifts.

Within a month of casual tagging you’ll have facebook, Facebook, FB, fb_ads, and facebook.com all meaning the same channel — and your channel report splits one source into five rows that each look small. Rules that prevent this:

  • Lowercase everything, always. utm_source=youtube, never YouTube. URLs are case-sensitive; analytics shouldn’t have to guess.
  • No spaces. Use summer_launch_2026, not Summer Launch 2026 (which becomes Summer%20Launch and a mess).
  • Fix a controlled vocabulary for utm_source and utm_medium. Source is the platform (youtube, reddit, google). Medium is the type (cpc, email, social, referral). Write the allowed values down and treat new ones as a deliberate decision.
  • Keep one campaign naming scheme — e.g. {objective}_{audience}_{yyyymm}. Consistency here is what makes “spend by campaign” a one-line query instead of a manual cleanup.
  • Never UTM-tag internal links. Tagging a link from your own homepage to your own pricing page overwrites the real acquisition source with utm_source=internal, erasing where the user actually came from. UTMs are for inbound links from outside your property only.

Standardize tags at creation time. A shared spreadsheet or a tiny UTM-builder is cheaper than retroactively CASE-statementing five spellings of “facebook” into one in every query forever.

Set realistic expectations

Two honesty checks before you over-trust any attribution number:

  • Mobile attribution is lossy by design. Privacy frameworks (ATT, SKAdNetwork, Privacy Sandbox) mean you often get aggregated or delayed install signals, not a clean click-to-install chain. Treat channel comparisons as directional, not accounting-grade.
  • There’s always an organic / unattributed bucket. Users who heard about you from a friend, a podcast, or a screenshot have no UTM. A large “direct / unknown” share isn’t a tracking failure to eliminate — it’s real word-of-mouth. Don’t redistribute it away just to make the chart tidy.

Attribution’s job isn’t a perfect ledger of credit. It’s to tell you, with enough confidence to move budget, which channels create demand and which close it. First-touch, last-touch, and clean UTMs get you there.

FAQ

Should I use first-touch or last-touch attribution? Report both. Last-touch tells you what closes; first-touch tells you what introduces. The disagreement between them is the useful signal — a channel that’s big in first-touch but small in last-touch is doing awareness work you’d lose if you judged it on last-touch alone.

Do UTM tags work for app installs from the app stores? Not directly — store install attribution uses platform mechanisms (install referrer on Android, SKAdNetwork on iOS) rather than raw UTMs. UTMs still tag the web links that lead to the store page, and you stitch the two together via your attribution setup. Treat store-side numbers as aggregated and lossy.

My attribution report has a huge “direct/unknown” bucket. Is something broken? Probably not. Some of it is fixable (missing UTMs on links you control), but much of it is genuine word-of-mouth and offline discovery that no tag can capture. Fix your own tagging first, then accept that a real organic share is normal and even healthy.