Campaigns

Multi-stage funnel tracking with source attribution, journey timelines, and conversion analytics

What Are Campaigns?

A Campaign in EziLinks is a multi-stage funnel where you tag each marketing channel as a source, each page in the customer journey as a stage, and the actions you care about (opt-in, purchase, attendance) as conversions. EziLinks then reconstructs each visitor's path, attributes their final action to the channel they originally came from, and shows you which sources are actually performing.

Typical use cases:

  • Tracking a paid-ad → landing page → opt-in → sales-page → purchase funnel
  • Comparing organic Instagram vs paid Facebook vs cold email for a workshop launch
  • Multi-step service funnels (lead magnet → nurture → discovery call booking)
  • Membership / course funnels with both opt-in and purchase goals
Plan requirement: Campaigns is available on the Pro Toolkit and Agency plans. Free plan users see an upgrade prompt when they open the Campaigns page.

How a Campaign Works

Three building blocks make up every campaign:

BlockWhat it isWhat you do with it
Sources The channels driving traffic into your funnel — paid ads, email, SMS, social posts. Each source becomes a short link you share on that channel. EziLinks tags every click with the source so you can attribute revenue back to it.
Stages The pages a visitor moves through after entering your funnel — landing page, opt-in form, sales page, checkout. Each stage is one URL on your funnel platform. EziLinks watches for pageviews on each URL via the tracking pixel.
Conversions The moments that matter — an opt-in submission, a sale, an attendance. Each conversion stage has a webhook URL. Your funnel platform (systeme.io, Zapier, etc.) calls that URL when the action happens so EziLinks records it.

The two signals that make this all work:

SignalWhat it capturesWhere it lives
EziLinks tracking pixel REQUIRED Every page-view by a real browser. Records visitor ID, IP, country, device, browser, the URL they're on, and ties it to their previous source click. A one-line <script> you paste into each funnel page.
Conversion webhook The fact that a sale / opt-in happened, plus the customer's email. A URL EziLinks generates for each goal stage. You paste it into your funnel platform's webhook / Zapier action.
You need both for Campaigns to work properly. Without the pixel, you'll see conversion counts but no journey timeline, no source attribution, no location/device data. Without the webhook, opt-ins and purchases will never register as goals. Setup time for both: about 10 minutes per campaign.

Installing the Tracking Pixel

This is the single most important step. The tracking pixel is one line of JavaScript that you paste into every funnel page once — landing page, opt-in form, sales page, checkout, thank-you page, every stage of your funnel.

<script src="https://app.ezilinks.com/c.js" async></script>

Where to put it

In the <head> section of every funnel page, ideally just before the closing </head> tag. Most funnel platforms (systeme.io, ClickFunnels, Kajabi, Kartra, LeadPages, etc.) have a per-page "Custom Header Code" or "Tracking Scripts" field for exactly this purpose.

Platform-specific notes

  • systeme.io: Funnel → Edit page → Settings (gear icon) → Custom code → paste in the Header field. Repeat for every page of the funnel.
  • ClickFunnels 2.0: Page settings → Tracking Code → Header tracking code.
  • Kajabi: Site settings → Site Details → Header Code — sets it for the whole site, no per-page needed.
  • WordPress: Use a plugin like Insert Headers and Footers, OR paste directly into your theme's header.php.
  • Custom HTML page: Just paste it in the <head> directly.
One pixel, every page. The same snippet works on every page — no per-page customisation needed. EziLinks figures out which campaign and which stage the URL belongs to automatically.

For example, here's what it looks like in systeme.io's per-page Custom code tab:

systeme.io 📊 Dashboard 📧 Email campaigns 📞 Contacts 🎯 Funnels 🛒 Products ⚙️ Settings Workshop Funnel → Order Form page General SEO Custom code Tracking HEADER CODE Code inserted just before </head> on this page <script src="https://app.ezilinks.com/c.js" async></script> Save

systeme.io — Funnel → page → Custom code tab → Header code field. Paste the snippet and click Save. Repeat for every page in the funnel.

How to verify the pixel is firing

🔍 Quick check — no campaign setup needed: Open app.ezilinks.com/pixel-test.html in a new tab. It runs three live checks (script loaded, visitor ID assigned, /api/track reachable) and tells you exactly which one fails if any. Use it from any browser to confirm your account can reach the pixel pipeline.

To verify the pixel on your own funnel page specifically:

  1. Open one of your funnel pages in your browser.
  2. Open the browser's developer tools (F12 on most browsers) and go to the Network tab. Type track in the filter box.
  3. Reload the page.
  4. Look for a POST request to app.ezilinks.com/api/track returning 200 OK:
Elements Console Network Sources Application track 1 request Name Status Type Initiator Size Time track 200 fetch c.js:127 312 B 142 ms ↑ Status 200 = pixel is firing.

DevTools Network tab filtered for track. The single POST to /api/track with status 200 confirms the pixel is firing on your funnel page.

What happens if the pixel is blocked

About 10–20% of real visitors have browser settings or extensions that block tracking scripts (uBlock Origin, Brave, strict ITP/Safari, etc.). For those visitors:

  • Their page-views don't appear in the journey timeline.
  • If they convert, the conversion webhook still fires — EziLinks records the sale but tags the visitor as Unknown Source because we couldn't see them earlier in the funnel.
  • The conversion count is still correct — you just can't trace where they came from.

This is unavoidable and applies to every analytics tool. The pixel still captures the vast majority of visitors.

Creating Your First Campaign

1 Open Campaigns from the sidebar

Click Campaigns in the left sidebar. If you're on the Free plan, you'll see an upgrade prompt — this feature requires Pro Toolkit or Agency.

2 Click "+ New Campaign"

Give it a memorable name (e.g. "Workshop Launch June 2026"), a start date, and an end date. The date range determines which clicks and conversions count in the analytics.

3 Add your funnel pages as Stages

Paste each funnel page URL and give it a friendly label (e.g. "Landing page", "Opt-In", "Order Form", "Thank-you"). For each stage you set:

  • Stage type — awareness, interest, consideration, conversion, retention. Used for funnel-step charts.
  • Branch — sub-funnel grouping (Opt-In, Purchase, Attendance, Other). Lets one campaign track multiple goals simultaneously.
  • Count as a conversion? — the key setting:
    • No - Just a step: visits aren't conversions. Use for transitional pages.
    • Yes - as soon as they visit: the page-view itself counts as the conversion. Use for "click as goal" use cases like calendar bookings.
    • Yes - once action confirmed (webhook): the conversion only counts when your funnel platform fires a webhook. This is what you want for opt-ins and purchases.

4 Add your traffic Sources

For each channel you'll use (Paid Ads, Email, Instagram bio, SMS, etc.), add a Source. EziLinks gives you a short link for each one. Share the source link in that channel — e.g. paste the "Paid Ads" link as your Facebook Ad's destination URL, paste the "Email" link in your newsletter.

Source labels also have a kind (paid, organic, email, referral, other) that drives the colour-coding in reports.

5 Install the EziLinks tracking pixel on every stage page

See Installing the Tracking Pixel above. Do this once per page.

6 Set up the conversion webhooks

For each stage you marked "Yes - once action confirmed", a green webhook URL appears underneath the stage row. It looks like this in the EziLinks campaign editor:

4 order-form → info.katmillar.com/wtc-workshop-order-form Stage: 🎯 Conversion Branch: 💰 Purchase Count as a conversion: 🔔 Yes - once action confirmed 💰 Conversion webhook: https://app.ezilinks.com/api/webhook/conv/cv_711efe40685ae4da Copy ↑ Paste this URL into your funnel platform's webhook for "on new sale" / "on form submitted".

A stage row in the campaign editor with Count as a conversion set to "Yes — once action confirmed". The green webhook URL box only appears when this option is selected. Click Copy and paste it into your funnel platform.

Paste the copied URL into your funnel platform's webhook output for the goal:

  • systeme.io: Order form → Settings → "On new sale" → Add webhook → paste URL. For opt-ins use "On form submission".
  • Zapier / Make / n8n: use a "Webhooks → POST" action after the trigger you care about (Stripe charge, Mailchimp subscriber, etc.).
  • Stripe direct: Stripe Dashboard → Webhooks → Add endpoint → paste URL, listen for checkout.session.completed.
Test before scaling: After setup, run one test purchase or one test opt-in through your funnel. Wait ~10 seconds, then refresh the Campaigns page. You should see your own journey appear with both pixel-tracked page-views AND the conversion event. If the webhook event doesn't appear, your funnel platform isn't firing it correctly — check the platform's webhook log.

Reading the Analytics

The campaign view is split into several sections:

Source Breakdown table

Each row is one of your sources. Columns show clicks, unique visitors, and conversions per branch (Opt-Ins / Purchases / etc.). The totals row aggregates across sources, with a separate "Direct" row for visitors who arrived with no recognisable source attribution.

Branch Performance cards

One card per branch (Opt-In, Purchase, Attendance, Other). Shows reach, conversions, and rate. For the Purchase branch, also shows total paid offers and distinct buyers.

Recovery analysis

For visitors who declined branch A but later converted on branch B, this section shows the recovery rate — e.g. "Of 100 who didn't opt in, 12 still bought downstream". Useful for understanding multi-step funnels.

Journey timeline

One row per visitor. Each row is a horizontal track of dots, one dot per page-view or conversion event, coloured by stage and branch. Hover any dot to see the exact page and time.

Direct purchasers (visitors whose pixel never fired but whose webhook did) appear with a ? Unknown Source marker followed by an inferred page-visit and the real conversion event. The inferred event uses a red ? indicator and an italic timestamp so you can tell it apart from a directly-recorded click. Hover for the full explanation.

Visitor filters

Filter the journey list by source, branch, conversion status, country, device, email, and more. Multiple filter chips are AND-joined — every chart and table on the page reflects the filtered cohort.

Troubleshooting

I'm getting conversions but no journey events

The pixel isn't installed on your funnel pages. Add the snippet from Installing the Tracking Pixel to every page in the funnel.

The journey shows page-views but no conversion

Your funnel platform isn't firing the conversion webhook. Check:

  1. The webhook URL is exactly what's shown in the campaign editor (not the public link).
  2. The webhook is configured to fire on the right event (e.g. "On new sale" not "On page load").
  3. The funnel platform's own webhook log shows the request being sent.
  4. Use a tool like webhook.site to temporarily replace the EziLinks URL and verify the funnel platform is actually firing the webhook with the right data.

My source attribution is missing for some buyers

This happens when the visitor's browser blocked the pixel (10–20% of real traffic), used an in-app browser like Instagram or Facebook Messenger (which strip cookies between sessions), or completed the purchase in a different browser session than their initial click. Those visitors are labelled Unknown Source in the journey and source breakdown.

I have multiple campaigns sharing the same page URL

Add the campaign slug as a query parameter to disambiguate — the pixel reads ?_camp=<slug> from the URL and routes the pageview to the right campaign. Your source links handle this automatically; the slug is included by default.

I want cross-device attribution (e.g. mobile click → desktop purchase)

Add ?_ezv_email=<the-customer's-email> to the links you send via email or SMS follow-ups. When the pixel fires and sees that parameter, it identifies the visitor by email and stitches the new session to any prior session with the same email.

Related Guides

  • Managing Your Links — how short links work, the foundation for source links
  • UTM Parameters — complement source attribution with Google Analytics tracking
  • Retargeting Pixels — the OTHER kind of pixel (Meta, Google, TikTok) for ad audiences. Different concept — don't confuse with the tracking pixel above.
  • Analytics — per-link analytics outside of campaigns
© 2026 EziLinks. All rights reserved.