Tracking & attribution
Measurement for an always-on performance stack: one first-party script ties site visits, conversions, and revenue back to your campaigns, with no per-channel pixels to configure.
Installing the tag
The Tracking page in the app gives you a personalized snippet with your site token. It goes in your site’s <head>:
<script async src="https://waverunner.adwave.com/t/YOUR_SITE_TOKEN"></script>
- One tag per website: each business in your account has its own snippet, conversion rules, webhook, and settings. Run more than one site? Use the switcher on the Tracking page to pick the right one.
- The tag is SPA-aware: it tracks route changes in single-page apps automatically.
- Recommended settings (per website, on by default): automatic capture of clicks and form submits, Form conversions (success-gated signup/lead/subscribe), and origin enforcement. Turning any of these off asks you to confirm the impact on Autopilot and tracking. You can restore all recommended settings in one click.
Step-by-step install guides, written for non-technical readers:
Defining conversions
The easiest way to set up conversions: on the Tracking page, describe what counts as a win in plain language (“a purchase: people land on an order confirmation page”). Waverunner analyzes your site’s recent traffic and proposes evidence-backed rules you approve with one click. It also watches for conversion-looking pages on its own and asks whether to track them. Nothing is ever tracked without your say-so.
Under the hood, conversions come from four places:
- Conversion rules: match a URL (or a phone-number tap) and Waverunner records the conversion, no code needed. Approving a suggestion creates one of these; you can also add them manually. Each rule has a trigger so a bare page visit is never mixed up with completing something:
- Page reach: someone lands on a confirmation page (classic thank-you URL).
- Form then page: someone submits a form and lands on the page within a minute (needs Autocapture on).
- Checkout return: someone comes back from a hosted checkout (Stripe, PayPal, and similar). Same-domain checkouts (for example many Shopify stores) still use a thank-you page rule or the purchase webhook.
- Phone tap: someone taps a
tel:link. That counts call intent, not a completed call.
/signup. For purchases, a server-side webhook remains the most reliable path when you can wire it. - Form conversions: with autocapture + Form conversions enabled, a successful marketing form submit (HTTP 2xx with success UI, or a thank-you navigation) records
signup,lead, orsubscribe, not every bare submit or form-page visit. No thank-you URL required. - The tag API: fire a conversion event from your frontend with a value, currency, and order ID (order IDs de-duplicate automatically).
- Server-side webhooks: a per-website webhook URL accepts conversions from your backend, with ready-made recipes for Shopify, Stripe, WooCommerce, and Zapier.
What a win is worth
Cost per conversion works as soon as conversions count. Return on ad spend (ROAS) needs a dollar value on those wins. We never invent a platform default: until you set a value, ROAS shows an honest dash, and Autopilot still optimizes for cost per conversion.
- Purchases: pass the real order amount in a
trackcall, or connect Shopify / WooCommerce / Stripe so the webhook carries exact totals. - Leads and signups: on Tracking, use Set what a win is worth on each goal (or on Form conversions: lead, signup, subscribe). Not selling directly? Estimate from close rate: if about one in ten signups becomes a $500 customer, a signup is worth roughly $50. Reports label that revenue as estimated. You can change or clear an estimate anytime.
- Real amounts win: if the same conversion name arrives with a value from
track, a webhook, or an order-grade page total, that number is used and the Tracking estimate is ignored for that event. Estimates only fill in when the event carries no value. Different names stay independent (purchasedoes not use asignupestimate).
The tag API
Once the snippet is installed, every page has a global waverunner() function with three commands:
// Record a conversion. Value is in dollars; the optional orderId
// makes the same purchase count once even if it is reported twice
// (for example by this call and your store's webhook).
waverunner("track", "purchase", { value: 129.99, orderId: "1001" });
// Tell us who the visitor is when you learn it (sign-in, checkout).
// This links the browser to that email, so conversions your backend
// sends later still connect to the ad that brought them, even from
// another device. Emails are stored only as salted one-way hashes.
waverunner("identify", "customer@example.com");
// Wire in your cookie banner: declined visitors get the same
// do-not-share treatment as Global Privacy Control.
waverunner("consent", { adSharing: userAcceptedAdCookies });- track accepts any conversion name you choose, plus optional
value,currency, andorderId. - identify takes an email string, or an object with
email,phone,firstName, andlastName. It is the glue between browser visits and server-side webhook conversions: without it, a backend-reported sale can only match through the same browser. - consent stores the visitor's choice for a year. Measurement for your own reports continues either way; declining stops all sharing with ad platforms.
How attribution works
- Last-touch: a conversion is credited to the most recent qualifying touch. That stamp drives billed results, wallet charges, and ROAS. All touches are still stored.
- Clicks beat views: ad clicks carry a first-party click ID (30-day window) and always win over view-through exposure.
- View-through: TV and web display impressions are recorded by a first-party pixel; the view-through window is configurable at 7, 14, or 30 days.
- Comparison models on Tracking: when someone sees more than one of your ads before converting, Tracking shows how first touch, last touch, linear, time decay, position, and data-driven models would split the same dollars. Those columns are for learning only. Money and ROAS stay on last touch.
- Assisted conversions: on a campaign's Performance tab, assists show when another channel touched someone earlier (click, household view, or person-resolved view) before a different channel got last-touch credit. Assists are reporting-only and never change wallet charges or ROAS. Details: Assisted conversions and Lift.
- Closed loop: attributed conversions are forwarded to Meta (Conversions API) and Google (offline click-conversion uploads). For Google, those offline uploads are the primary signal used for bidding. When Google Ads is connected, the tag also loads a sitewide Google tag (AW config) and may fire observation-only website conversion events that share the same transaction id — they do not double-count against the offline primary. Install our first-party tag; you do not need a separate Google conversion snippet on the page.