Contact Identification API

Know who's on your website, right now. The Contact Identification API lets your frontend code look up the visitor's contact profile so you can personalize their experience the moment they arrive.

Overview

When a contact clicks a link in one of your Pigeon Perch emails and lands on your website, the tracking snippet stores an encrypted token in the browser. The identify endpoint decrypts that token and returns the contact's profile data, giving you instant access to their name, email, tags, and custom properties.

This opens the door to a whole range of personalization. Greet returning contacts by name, pre-fill your forms with their details, show different content based on their tags, or notify your sales team the moment a high-value lead visits your pricing page. All of it happens in real time, without any server-side code on your end.


How It Works

The identification flow has three parts, and most of it happens automatically:

  1. Token creation. When Pigeon Perch sends an email, it appends an encrypted hp_tk parameter to every link pointing to your website. Each token is unique to the recipient and encrypted with AES-256-GCM, so it cannot be forged, decoded, or reused by anyone else.
  2. Token capture. When the contact clicks through and your page loads, the tracking snippet (the same hp.js snippet from Web Tracking) reads the hp_tk parameter from the URL, stores it in sessionStorage, and cleans the parameter from the address bar so the URL stays tidy.
  3. Identification. Your code calls PigeonPerch.identify() (or hits the REST endpoint directly). The token is sent to the Pigeon Perch API, which decrypts it, looks up the contact, and returns their profile.

If the visitor hasn't clicked an email link (no token in the session), the identify call simply returns null. No errors, no interruptions.


Using PigeonPerch.identify()

The simplest way to identify a visitor is through the PigeonPerch.identify() method, which is available anywhere the tracking snippet is installed. Pass it a callback function, and it will be called with the contact object (or null if the visitor is anonymous).

PigeonPerch.identify(function(contact) {
  if (contact) {
    document.getElementById("greeting").textContent =
      "Welcome back, " + contact.firstName + "!";
  }
});

The callback fires once the API responds. If the visitor is identified, you get a contact object with fields like email, firstName, lastName, tags, and any custom properties you've stored on the contact. If they're anonymous, the callback receives null.

You can use the result any way you like: update the DOM, gate content behind a check, fire an event to your analytics tool, or send a webhook to your team's Slack channel.


Direct API Usage

If you'd rather call the API directly (for example, from a server-side application or a custom integration), you can make a GET request to the identify endpoint:

GET /api/v1/identify?writeKey=YOUR_WRITE_KEY&token=HP_TK_TOKEN

The writeKey is the same key you use for the tracking snippet (found in Settings → Tracking). The token is the encrypted hp_tk value from the visitor's session.

Example Response

{
  "identified": true,
  "contact": {
    "email": "sarah@example.com",
    "firstName": "Sarah",
    "lastName": "Chen",
    "tags": ["customer", "newsletter"],
    "engagementScore": 82,
    "properties": {
      "company": "Acme Co",
      "plan": "growth"
    }
  }
}

If the token is missing, expired, or invalid, the response returns { "identified": false, "contact": null } with a 200 status. You won't get an error, just a clear signal that the visitor couldn't be matched.


Filtering Fields

By default, the identify endpoint returns the full contact profile. If you only need a few fields (to reduce payload size or limit what's exposed in client-side code), use the optional fields query parameter:

GET /api/v1/identify?writeKey=YOUR_KEY&token=TOKEN&fields=email,firstName,tags

Pass a comma-separated list of field names. The response will include only those fields on the contact object. Available fields include email, firstName, lastName, tags, engagementScore, and properties.


Rate Limits

The identify endpoint is rate-limited per write key to prevent abuse. Limits vary by plan:

PlanRequests per Minute
Free60
Starter300
Growth1,000
Scale5,000

Every response includes rate-limit headers so you can monitor your usage:

  • X-RateLimit-Limit - your plan's per-minute limit
  • X-RateLimit-Remaining - requests remaining in the current window
  • X-RateLimit-Reset - seconds until the window resets

If you exceed the limit, you'll receive a 429 Too Many Requests response. Back off and retry after the reset window.


Common Use Cases

Personalized Greetings

Show a "Welcome back, Sarah!" message in your site header or hero section. It's a small touch, but it signals to the visitor that your site knows who they are and remembers their history. This builds familiarity and can noticeably increase time on site.

Pre-Filled Forms

When a known contact lands on a demo request form or checkout page, pre-fill their name and email so they don't have to type it again. Reducing form friction even by two fields can improve conversion rates significantly, especially on mobile devices where typing is slower.

Sales Team Alerts

If a contact tagged as "enterprise" or with a high engagement score visits your pricing page, fire a webhook or push notification to your sales team. They can reach out while the lead is still actively browsing, turning a warm visit into a real conversation.

Gated Content Bypass

You have an ebook or resource that normally sits behind a signup form. When a contact who's already in your system visits the page, skip the gate and show the content directly. They've already given you their info through your email list, so there's no need to ask again. This creates a smoother experience and avoids annoying your most engaged readers.


Security

The identification system is designed to keep your contact data safe while still being easy to use from client-side code.

  • AES-256-GCM encryption. The tracking token is encrypted with AES-256-GCM, the same encryption standard used by banks and government systems. Tokens cannot be decoded, tampered with, or reused across organizations.
  • CORS validation. The identify endpoint validates the request's origin against the domains you've configured in Settings → Tracking. Requests from unauthorized domains are rejected, so someone can't just grab your write key and call the endpoint from their own site.
  • Write key = read-only access. Despite the name, the write key only grants read access when used with the identify endpoint. It can look up a contact's profile given a valid token, but it cannot modify data, list contacts, or access any other part of your account. It's safe to include in client-side JavaScript.
  • Token expiration. Tokens are scoped to browser sessions. Once the session ends (the tab or browser is closed), the token in sessionStorage is automatically cleared.

Quick Reference

API Endpoint

GET /api/v1/identify?writeKey=KEY&token=TOKEN

JS Method

PigeonPerch.identify(callback)

Optional Parameters

fields - comma-separated list of fields to return
Contact Identification API — Pigeon Perch Docs