Attribution without Illusions: analytics from a practitioner�s perspective with lessons that do not age.
\n\n\n\nThe room was warm and the whiteboard already packed with arrows. Someone had written EMAIL WINS in giant letters. We had a spike in sales after the newsletter, so the story wrote itself. The intern looked proud. The paid search manager looked annoyed. The merchandiser just wanted inventory numbers by morning.
\n\n\n\nI asked a simple question. How many of these buyers found us the first time through email. Silence. A few knew us from last week�s comparison shopping. A chunk had clicked a display banner during lunch. Some typed our brand tonight after chatting with a friend. Our last click report gave a tidy answer that felt right. It also missed the plot.
\n\n\n\nRight now everyone wants marketing attribution that explains the spike. There is a new ad network launch every week. Google keeps nudging us toward better tagging. Facebook is selling clicks. The iPad is still novelty and we have no idea how to measure that traffic. In the middle, your analytics platform tries to make sense of touchpoints that do not behave like a tidy funnel. If we are going to spend next month�s budget with a straight face, we need attribution without illusions.
\n\n\n\nLast click is convenient. It is not the whole story.
\n\n\n\nMost teams I meet still report on last click attribution. Google Analytics reports conversions based on the last non direct click. That little rule matters. If a user first arrived from a display ad, then returned direct and bought, GA credits the display touch not the direct one. If a user arrives from paid search today then from email next week and buys, email gets the win. That is better than pure last click of the final session, but it hides a lot of assists.
\n\n\n\nUnder the hood, classic GA writes campaign info into the __utmz cookie. That cookie stores the source, medium, and campaign values you pass through UTM parameters or AdWords auto tagging. If you do not tag your links, or you mix styles, your reports will lie. Not on purpose. Just from bad inputs.
\n\n\n\nCampaign tagging that does not lie
\n\n\n\n- \n
- Pick a controlled taxonomy. For source, use domains or platforms like google, yahoo, facebook, newsletter. For medium, use paid, cpc, email, display, referral, social, affiliate. For campaign, use a readable scheme like 2010q2_sale or brand_exact. \n
- Use AdWords auto tagging with gclid and let GA map it. Do not tag AdWords manually and auto tag at the same time. \n
- Tag every email including transactional nudges with utm_source=newsletter and utm_medium=email. Un tagged email looks like direct and eats credit it did not earn. \n
- Exclude payment gateways like paypal.com or secure.authorize.net in referral exclusions so your orders are not credited to your gateway. \n
- Set a sensible campaign timeout. In GA settings, the default is six months. If you run flash sales, consider a shorter window for certain mediums to reduce halo effects. If your sales cycle is long, keep the default. \n
These basics create cleaner data and bring your e commerce analytics closer to reality. Still, they do not show the full path. GA does not show multi touch conversion paths yet. Omniture SiteCatalyst and Coremetrics give you more toys if your wallet can take it, but you still face the same core problem. The model decides the story.
\n\n\n\nBuild a simple path memory you can trust
\n\n\n\nWe can track a channel stack with plain JavaScript and a GA Custom Variable. The idea is simple. Detect the channel on each visit, append it to a first party cookie, and send that stack into GA on important pages. You will not get pretty path reports out of the box, but you can export the data and run a quick model in Excel.
\n\n\n\n<script>\n// Simple channel detection\nfunction getParam(name) {\n var m = new RegExp('[?&]' + name + '=([^&#]+)').exec(location.search);\n return m && decodeURIComponent(m[1].replace(/\\+/g, ' ')) || '';\n}\nfunction detectChannel() {\n var src = getParam('utm_source');\n var med = getParam('utm_medium');\n if (getParam('gclid')) return 'google cpc';\n if (med && src) return src + ' ' + med;\n if (document.referrer && document.referrer.indexOf(location.hostname) === -1) {\n try {\n var a = document.createElement('a');\n a.href = document.referrer;\n return a.hostname.replace(/^www\\./, '') + ' referral';\n } catch(e) {}\n }\n return 'direct';\n}\n// Cookie helpers\nfunction readCookie(name) {\n var m = document.cookie.match('(?:^|; )' + name + '=([^;]*)');\n return m ? decodeURIComponent(m[1]) : '';\n}\nfunction writeCookie(name, value, days) {\n var d = new Date();\n d.setTime(d.getTime() + (days*24*60*60*1000));\n document.cookie = name + '=' + encodeURIComponent(value) + '; path=/; expires=' + d.toUTCString();\n}\n// Update channel stack\nvar ch = detectChannel();\nvar stack = readCookie('ch_stack');\nvar parts = stack ? stack.split('>') : [];\nif (parts[parts.length - 1] !== ch) {\n parts.push(ch);\n if (parts.length > 5) parts.shift(); // keep last 5 touches\n writeCookie('ch_stack', parts.join('>'), 180);\n}\n// Send to GA as visitor level custom var\nwindow._gaq = window._gaq || [];\n_gaq.push(['_setAccount', 'UA-XXXXXX-1']);\n_gaq.push(['_setCustomVar', 1, 'ChannelStack', readCookie('ch_stack') || ch, 1]); // 1 = visitor scope\n_gaq.push(['_trackPageview']);\n// e commerce example with transaction id to avoid duplicates\n// _gaq.push(['_addTrans', 'T12345', 'My Store', '19.99', '0', '5.00', 'Austin', 'TX', 'USA']);\n// _gaq.push(['_addItem', 'T12345', 'SKU-1', 'T Shirt', 'Apparel', '19.99', '1']);\n// _gaq.push(['_trackTrans']);\n(function() {\n var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;\n ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';\n var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);\n})();\n</script>\n\n\n\nNow you have a compact path like google cpc>direct>newsletter email stored against the visitor. Export your orders with this variable and make a quick model.
\n\n\n\nA light model you can run before lunch
\n\n\n\nPick three simple attribution views to compare. You do not need fancy math to get value.
\n\n\n\n- \n
- Last non direct. Baseline that matches GA. \n
- First touch. Credit the first channel in the stack. Reveals who fills the top of the funnel. \n
- Position based. Give 40 percent to first, 40 percent to last, and spread 20 percent across the middle touches. This respects intro and closing work. \n
# Pseudo Excel formula for position based credit\n# Assume A2 has a stack like "google cpc>direct>newsletter email"\n# and B2 has revenue\n=LET(\n stack, TEXTSPLIT(A2, ">"),\n n, ROWS(stack),\n credits, IF(n=1, 1, IF({1}, 0.4, IF({n}, 0.4, 0.2/(n-2)))),\n # Apply credits per position and return a table or use a simple split per channel\n)\n\n\n\nIn plain terms, group your orders by channel, multiply revenue by the credit weight, and sum. You will likely see email shrink and prospecting grow. Paid search brand terms usually lose credit when you stop letting them close everything they did not open.
\n\n\n\nCommon data traps that bite attribution
\n\n\n\n- \n
- Un tagged social and PR. A front page mention sends a tidal wave that shows up as direct. Tag your outreach links when you can. Create a short URL with UTM for your press kit and share that with reporters. \n
- Coupon code filters. If you hand out codes to affiliates, make sure your checkout does not overwrite source at the last second. Credit should follow touchpoints, not the final text field used. \n
- Cross domain leakage. If you send users to a booking engine on another domain, carry the GA cookies across or you will treat that engine as a referral and hand it the sale. \n
- Internal redirects. Meta refresh and weird redirects wipe referrers. Use server side 301 where possible. \n
- Sampling. Large date ranges in GA may sample. Pull smaller windows or use profiles with unsampled exports if you can. You do not want to model on sand. \n
Manager playbook: use numbers without getting used by them
\n\n\n\nYou do not need a PhD or a new vendor to make better calls next quarter. You need guardrails, tests, and incentives that do not fight each other.
\n\n\n\n- \n
- Pick a default model and stick with it for budgeting. Last non direct for reporting, position based for planning is a sane combo. Declare it. Document it. No fishing expeditions on bad weeks. \n
- Tie channel owners to shared profit not just last click revenue. Give email credit on first touch when it recruits new buyers, not just repeat buyers it already owns. \n
- Run small holdout tests. Pause remarketing in two cities for a week. Or cap frequency hard on display for half the audience. Compare revenue per visitor. If the delta is tiny, you just found budget. \n
- Use matched dates for comparisons. Holidays and merch changes swamp models. Keep a calendar of events and annotate your analytics so your team remembers why a line jumped. \n
- Keep a tidy UTM dictionary. One spreadsheet. One owner. New staff start there on day one. Dirty taxonomy becomes a tax you pay every day. \n
- Audit your checkout monthly. Confirm transaction IDs are unique. Confirm your referral exclusions work. Confirm cross domain linking still passes cookies. \n
You will hear pitches from attribution vendors. Some are sharp. Some are magic tricks. Ask for a holdout result and a plan to prove incremental lift. If they cannot measure lift now, they will not be able to next quarter either. Do not outsource your skepticism.
\n\n\n\nSearch people and email people can be friends
\n\n\n\nPaid search wants budget. Email wants calendar slots. Display wants reach. Affiliates want a bigger cut. Everyone can win if you split credit in a way that maps to how buyers behave. Your numbers will get cleaner each month if your team shares a scoreboard and a language. Start with a simple multi touch attribution view that feels fair, and keep testing it with real control groups.
\n\n\n\nYour turn: run the no illusions audit this week
\n\n\n\n- \n
- Tag check. Pick five live campaigns and click through with UTM. Make sure source, medium, and campaign land in GA exactly as intended. \n
- Gateway check. Place a test order with PayPal or your processor. Confirm the conversion is not credited to the gateway. \n
- Path memory. Implement the channel stack snippet on a staging page. Verify a path like google cpc then direct then email shows up as expected. \n
- Mini model. Export last 30 days of orders with ChannelStack and revenue. Compute first touch and position based totals per channel. Compare to last non direct. \n
- One holdout. Pick a small region. Cut one channel by half for 7 days. Watch revenue per visitor relative to a similar region. If your CFO asks why, say you are buying confidence. \n
- Name your model. Write your default model in a one liner on your wall. For example: Planning uses position based 40 20 40. Reporting uses last non direct. \n
Attribution without illusions is not a tool. It is a habit. Clean inputs. Simple rules. Real tests. Next time the whiteboard says EMAIL WINS, you will have a better answer. And maybe a bigger budget that actually grows the pie.
\n