Web Tracking & Lead Scoring

Drop a tiny script on your website and Pigeon Perch starts connecting the dots. Who's reading your emails? What pages are they visiting? How interested are they? You'll know.

How It Works

The tracking system ties together two worlds: your email campaigns and your website. When someone clicks a link in one of your emails and lands on your site, Pigeon Perch quietly links that visit to their contact record. From there, every page they view, every button they click, and every form they fill out gets logged against their profile.

That data does three things:

  1. Builds a picture of what each contact cares about (their activity timeline).
  2. Updates their engagement score so you know who's hot and who's gone cold.
  3. Feeds the product recommender so when you drop a recommended product block into an email, each contact gets something they're actually interested in.

Installing the Snippet

Step 1: Set Up Your Allowed Domains

Go to Settings → Tracking and add the domains where you'll install the snippet (like yoursite.com). You can use wildcards too:*.yoursite.com covers all subdomains.

This prevents anyone from spoofing events using your write key. Only requests from your allowed domains are accepted.

Step 2: Copy the Snippet

On the same settings page, you'll see your ready-to-use tracking snippet with your write key and CDN URL already filled in. Copy the whole thing and paste it into the <head> of every page on your site.

If you're using a CMS like WordPress, Webflow, or Squarespace, there's usually a "Custom Code" section in the site settings where you can drop it in once and it applies everywhere.

The snippet file loads from our global CDN for fast delivery worldwide. The data-api attribute tells the snippet where to send tracking data back to your Pigeon Perch account.

Step 3: You're Live

That's it for basic tracking. Page views are recorded automatically. If your site is a single-page app (React, Next.js, Vue), the snippet handles client-side navigation too. It hooks into pushState and popstate so route changes still get tracked.

Performance and Global Delivery

The tracking snippet is served from over 400 CloudFront edge locations worldwide. It is minified and compressed automatically, coming in at roughly 3 KB over the wire with brotli compression. For most visitors, the snippet loads in under 50 milliseconds regardless of where they are in the world. It uses HTTP/3 when available, so repeat visitors get zero round-trip connection setup.

The snippet uses the defer attribute, which means it never blocks your page from rendering. Your visitors will not notice any performance impact.


Tracking Custom Events

Page views are great, but the real magic is tracking what people do on your site. The snippet exposes a PigeonPerch object with two methods:

Conversions

// Track a conversion (sign-up, purchase, demo request, etc.)
PigeonPerch.conversion("signup");

// With extra metadata
PigeonPerch.conversion("purchase", {
  productId: "prod_123",
  amount: 49.99,
  currency: "USD"
});

Custom Events

// Track any action
PigeonPerch.track("button_click", { buttonId: "cta-hero" });
PigeonPerch.track("video_played", { videoId: "intro", duration: 45 });
PigeonPerch.track("pricing_viewed", { plan: "growth" });

Events show up in the contact's activity timeline and in your analytics dashboard.


Linking Visitors to Contacts

This is where things get interesting. When someone receives an email and clicks through to your website, Pigeon Perch automatically connects that website session to their contact record.

How the Link Happens

  1. You include a link in your email (to your website, a landing page, wherever).
  2. When the email sends, Pigeon Perch appends a ?hp_tk=... parameter to your links. This is an encrypted token that identifies the contact. It's unique per recipient and can't be forged or decoded by anyone else.
  3. The tracking snippet on your site reads the token from the URL and stores it in the browser's session. It also cleans the token from the URL bar so it doesn't look messy.
  4. Every event for that browser session is now tagged with the contact ID. Page views, clicks, conversions, everything.

What Happens Without a Token

Visitors who land on your site without clicking an email link (like from Google or a direct visit) are tracked anonymously. Their events are still recorded with session IDs, but they're not tied to a contact. If that visitor later clicks an email link, the token bridges the gap for that session going forward.


Identifying Visitors

Once a visitor has a tracking token, you can go further than just recording their activity. The Contact Identification API lets your frontend code look up the visitor's full contact profile in real time. Use it to personalize greetings, pre-fill forms, gate content, or alert your sales team when a high-value lead is browsing your site.

The simplest way to use it is through the PigeonPerch.identify() method, which is available anywhere the tracking snippet is installed. For full details, code examples, rate limits, and security information, see the Contact Identification docs.


Engagement Scoring

Every contact has an engagement score between 0 and 100. It updates automatically based on how they interact with your emails.

ActionScore Change
Email delivered+2
Email opened+2
Link clicked+5
Email bounced-10
Marked as spam-10
Unsubscribed-10

The score can't go below 0 or above 100. It's visible on every contact card in your dashboard, and you can build segments based on it (e.g., "all contacts with engagement above 70").

What Engagement Scores Are Good For

  • Spot your warmest leads. Sort or filter contacts by score to find who's most active right now.
  • Trigger automations. Use the "Engagement Drop" trigger to automatically re-engage contacts whose score falls below a threshold.
  • Focus your efforts. Instead of emailing everyone, send follow-ups to highly engaged contacts first.

Feeding the Product Recommender

All this tracking data feeds into the product recommender. When you add a "Recommended Product" block to an email template, Pigeon Perch looks at each contact's history to pick products they're most likely to care about.

The recommender considers:

  • Which emails they've opened and clicked
  • What pages they've visited on your site
  • Their tags and custom properties
  • Patterns from similar contacts

The more tracking data you collect, the smarter the recommendations get. Installing the tracking snippet and linking your product catalog are the two biggest things you can do to make the recommender work well.

Read more about product blocks in the Templates docs, and about syncing your catalog in the Products docs.


Security & Privacy

  • Write key is write-only. It can submit events but can't read any data from your account. Safe to include in client-side code.
  • Domain allowlist. Events are only accepted from the domains you configure. Everything else gets rejected.
  • Rate limited. 300 events per minute per write key. Enough for busy sites, tight enough to prevent abuse.
  • Tokens are encrypted. Contact identifiers in URLs use AES-256-GCM encryption. They can't be decoded, forged, or reused across organizations.
  • Rotate your key anytime. If your write key is compromised, rotate it from Settings. The old key stops working immediately.

Custom Domain Proxy (Advanced)

Some ad blockers maintain lists of known tracking domains. If you find that the snippet is being blocked on your visitors' browsers, you can proxy it through your own domain. This makes the script request look like any other first-party resource on your site.

The idea is simple: set up a URL on your domain (like yoursite.com/t/hp.js) that proxies the request to the CDN URL from your tracking snippet in Settings. Then update the src in your script tag to point to your proxy URL. The data-api attribute still points to your Pigeon Perch app URL so tracking data goes to the right place.

In the examples below, replace YOUR_CDN_URL with the CDN domain from your snippet in Settings → Tracking.

Nginx

location /t/hp.js {
  proxy_pass https://YOUR_CDN_URL/snippet/hp.min.js;
  proxy_set_header Host YOUR_CDN_URL;
  proxy_cache_valid 200 5m;
}

Cloudflare Workers

addEventListener('fetch', event => {
  const url = new URL(event.request.url);
  if (url.pathname === '/t/hp.js') {
    event.respondWith(fetch('https://YOUR_CDN_URL/snippet/hp.min.js'));
  }
});

Vercel Rewrites (next.config.js)

rewrites: () => [
  { source: '/t/hp.js', destination: 'https://YOUR_CDN_URL/snippet/hp.min.js' }
]

After setting up the proxy, update your snippet tag:

<script src="https://yoursite.com/t/hp.js?key=wk_your_write_key"
        data-api="https://yourapp.com" defer></script>

Quick Reference

Installation

Copy the snippet from Settings → Tracking

API Endpoint

POST /api/v1/events/web

JS Methods

PigeonPerch.track(eventType, metadata?)
PigeonPerch.conversion(name, metadata?)

Auto-Tracked Events

page_view (on every navigation)
Web Tracking & Lead Scoring — Pigeon Perch Docs