Analytics
The campaign dies in the redirect. A first-party record keeps it.
The stack is recording the visit. It is not keeping the campaign.
Growth teams rarely have a tracking problem that is one missing pixel. They have five tools that each saw the landing, two of them sending a page view, and a signup path that forgets where the person came from. The report then says direct, unassigned, or a payment domain. The ads did not stop working. The campaign never left the address bar.
That is the decision the data is supposed to support: which channel produced the paid conversion, where the funnel leaked, and what triggered the upgrade. A pile of tags can fire on every page and still miss all three.
Where the source actually disappears
UTMs are easy to lose because most stacks treat the query string as the record. It is not. It is a hint that lasts until the next navigation.
- A cleaner script strips utm_ parameters a few seconds after analytics loads, so the bar looks tidy and the next click has nothing to copy.
- Signup, login, and trial buttons are hard-coded. They do not forward the query string onto the app.
- Google sign-in replaces the URL. The authorize request carries a small state payload, and the callback lands on your domain looking like a visit from Google.
- Stripe, PayPal, and other checkout returns do the same. The session comes back from the payment host.
- Campaign values stored in local storage on the marketing host are invisible on the app host. Subdomains do not share local storage.
- A form that reads the URL at submit time reads the cleaned URL. The hidden field stays blank, and the CRM contact has no source.
The other failures that get called “tracking is off”
Once the campaign is fragile, every extra tool makes the gap look mysterious. The causes are usually ordinary.
- Two tag managers, or one manager and a hard-coded tag, both send a page view to the same property. Channel reports double.
- An old analytics property is still firing years after it stopped accepting data.
- First touch is written once, including empty placeholders, and then never corrected. Last touch is parsed by a different tag, and the medium comes back glued to the source.
- Consent either lets every pixel run, or it blocks the one first-party cookie the signup needed.
- The same person is a different id in analytics, the product, the CRM, and the ad platforms. Anonymous history never joins the account.
What Intently keeps instead
Intently starts with one first-party snippet on the sites that matter: marketing, app, and the host that receives the sign-in callback. The landing URL is read immediately. Campaign parameters and paid click ids are stored for 90 days, including after something else strips them from the address bar.
With cross-domain tracking on, that store is a cookie on the parent domain, so www, the app, and the callback host share one visitor. SameSite is set so the cookie comes back on the top-level return from Google. The callback URL is not the source. The cookie written before the browser left is the source.
Consent is checked before a touchpoint is stored and before anything is sent to an ad platform. A denied visit does not become a modeled guess inside the product. You can see the block.
Channel credit follows a fixed order: the UTM you set, then a paid click id, then the referrer, then direct. A hop inside your own site does not steal last-touch from the ad that landed. Signup, form submit, and purchase events attach to that same visitor. Stripe payments join when checkout carries the visitor id in session metadata, or on a Payment Link as the client reference. Delivery to Meta, Google, and the rest is logged as accepted or failed, so “the tag fired” is not the definition of success.
First touch, last touch, last non-direct, linear, and the other models run on that stored journey. You can open the path. You do not average two disagreeing reports into a third number nobody owns.
What you still wire on purpose
A first-party record removes the pile of tags. A few edges are still your application, and they are small once the visitor id already exists.
- Google sign-in: install the snippet on the landing host and on the callback host, and turn on cross-domain tracking, before you care about state. If the account is created only on the server, pass the visitor id through the same way checkout passes it to Stripe.
- Demo and lead forms: send the submit as an event, or fill the hidden field from the stored campaign when the page loads. Do not read the address bar at click time.
- Links you control: tag them. A bare store listing, a partner page, or an email with no parameters has no campaign to remember. An extension or app can send a single installed event on first open and join it to the visitor when one exists.
- Shortener clicks and site sessions: keep both. Clicks count requests. Sessions count people who loaded the page. Bots, mail prefetch, and bounces before the tag explain the gap. Pick which number decides which question.
- Activation inside the product: first project, first invite, first template. The app sends each event once, on the user you already joined at signup.
One set of numbers
The audit is finished when the team can point at one record and answer the three questions: which channel produced the paid conversion, where the funnel leaked, and what triggered the upgrade. Intently is that record. Capture, consent, credit, Stripe, and delivery proof sit on the same visitor.
Add another tag only when a destination still needs an event Intently is not already delivering. The measurement stack gets smaller. The decisions get easier to trust.
Free playbook
The Attribution Audit Playbook
What to check before you pause or scale. Checklist, worksheet, and decision rules.
Download the playbook →