---
title: Identifying visitors
slug: identify-visitors
description: How Personizely identifies visitors: email= links, email-platform click IDs, Shopify customers, ply.identifyVisitor, forms, parsers and profile merging.
docTags: 
createdAt: 2026-10-17T09:54:25.539Z
---

Identifying a visitor means attaching known details, such as an email address, a name or a custom field, to the anonymous visitor in the current browser. Once identified, the visitor can be targeted with the [Visitor fields filter](docId:8O0nDK0HiHXgMjILAg_OC) and email-platform filters, greeted by name with [Dynamic text (personalization variables)](docId\:EEz3US75criNjfndB--uS), and synced to your integrations. If the email or phone matches a visitor Personizely already knows, for example from another device, the two profiles are merged.

**Available on:** all platforms. Shopify customer recognition needs the Shopify app; email-platform click IDs need the matching integration.

## Ways to identify a visitor

| Source                                                      | How it works                                            | Needs                                       |
| ----------------------------------------------------------- | ------------------------------------------------------- | ------------------------------------------- |
| [email=  in the URL](docId\:Q2m71k4qe54obA5WmAvBT)          | A valid email in an `email` parameter on any page       | Nothing                                     |
| [Email-platform click IDs](docId\:Q2m71k4qe54obA5WmAvBT)    | A subscriber ID your email platform adds to links       | The email integration connected and enabled |
| [Logged-in Shopify customers](docId\:Q2m71k4qe54obA5WmAvBT) | The customer's account is read when they're logged in   | Shopify                                     |
| [ply.identifyVisitor](docId\:Q2m71k4qe54obA5WmAvBT)         | Your code sends the fields                              | A developer                                 |
| [Widget forms](docId\:Q2m71k4qe54obA5WmAvBT)                | The visitor submits a form or survey in a widget        | A form element                              |
| [Parsers](docId\:Q2m71k4qe54obA5WmAvBT)                     | Values are read from your page, cookies, storage or URL | Parsers set up in **Settings → Parsers**    |

All sources update the same visitor profile. Identification from the URL and from Shopify happens before targets are evaluated on that page, so the page already sees the identified profile. Forms, `ply.identifyVisitor` and parsers that find their value late update the profile during the page view; see [How targeting works](docId\:pUBcmS1M98xB8Mg8L99D_) for what's re-checked then.

### Email in the URL

Add `email=` with the subscriber's address to any link to your site:

```javascript
https://example.com/collections/new?email=jane%40example.com
```

- The parameter name is exactly `email` (lowercase), and the value must be a valid email address. URL-encode the `@` as `%40` if your email platform doesn't do it for you; both forms work.
- It works on any page, alongside other parameters such as UTMs.
- Most email platforms can insert the subscriber's email with a merge tag, for example `?email={{ email }}` in Klaviyo or `?email=*|EMAIL|*` in Mailchimp.

:::hint{type="warning"}
An email in a URL ends up in browser history, server logs and analytics tools. Use an email-platform click ID instead where your platform supports it, and check your privacy policy before putting emails in links.
:::

### Email-platform click IDs

When one of these integrations is connected and enabled, a link that carries the platform's subscriber ID identifies the visitor. Personizely looks the contact up in your email platform, links the visitor to it and copies the contact's details, such as email and name, into the profile.

| Platform           | URL parameter       |
| ------------------ | ------------------- |
| ActiveCampaign     | `ac_cid`            |
| AWeber             | `aw_cid`            |
| Brevo (Sendinblue) | `sib_cid`           |
| CleverReach        | `crcustomer`        |
| Constant Contact   | `cc_cid`            |
| ConvertKit (Kit)   | `ck_subscriber_id`  |
| Dotdigital         | `dd_cid`            |
| GetResponse        | `gr_cid`            |
| HubSpot            | `hs_cid`            |
| Hyperise           | `utm_hyperef`       |
| iContact           | `ic_cid`            |
| Klaviyo            | `kl_pid`            |
| Mailchimp          | `mc_eid`            |
| MailerLite         | `ml_cid`            |
| Mailjet            | `mj_cid`            |
| Moosend            | `moo_sid`           |
| Omnisend           | `omnisendContactID` |
| Ometria            | `om_profile`        |
| Ontraport          | `on_cid`            |
| Sender             | `se_cid`            |
| SendGrid           | `sg_cid`            |
| Sendlane           | `sl_cid`            |
| SendPulse          | `sp_cid`            |
| SmartrMail         | `sm_cid`            |

The value must be the contact's ID in that platform. Some platforms add it to links automatically; for the others, add the parameter to your email links with the platform's merge tag for the contact ID. If the integration isn't enabled, the parameter is ignored.

### Logged-in Shopify customers

When a customer is logged in to their Shopify account, Personizely identifies the visitor as that customer once per session. The customer's email, first name, last name and phone are copied from Shopify into the profile, and the visitor is linked to any existing profile with the same email.

The [Customer filter (Shopify)](docId\:ytjG6yjMEqRctiOZie7Ow) and [Order history filter](docId\:bV0w3-JjkCkmH-za_dK3g) filters also read the logged-in customer's account directly, so they work on the first page after login.

### ply.identifyVisitor

Send profile fields from your own code, for example on a custom site with its own login:

```javascript
window.plyLayer = window.plyLayer || [];
window.plyLayer.push(['identifyVisitor', {
  email: 'jane@example.com',
  firstName: 'Jane',
  customFieldValues: { '42': 'wholesale' }
}]);
```

It accepts every [Visitor fields reference](docId\:imIYkGl2lTiSb6EhnikmB) that a form can collect, plus `customFieldValues` keyed by [Custom fields](docId\:km7iOXZLplGl8qZlK582W) ID. Unknown fields are ignored. Full parameter reference: [JavaScript API](docId\:d64TegyOiwNA2GFG1eXPm#plyidentifyvisitordata).

### Widget forms

When a visitor submits a [Form element](docId:_32XhaAm6KMwlL3_ZIH25) or [Survey element](docId\:iW9bvN8cm1r6HwAPlrhSh) in a widget, the values of its fields are saved to their profile: default fields such as email and phone, and any custom fields the form uses. The submission also appears in [Contacts and form submissions](docId\:r6fb_qyzgxzRzBTFzO5AX).

### Parsers

A [Parsers (data parsing engine)](docId\:n_O3ZB1_JFa-N-aEZ4u3U) with the **Visitor** destination reads a value from your page (a JavaScript variable, cookie, local storage key, URL parameter or element) and saves it to a profile field. Use it to identify customers when your platform already exposes their email or ID on the page and you can't add code.

## How profiles merge

When a source sets an **email** or **phone** that already belongs to another visitor profile on your website, Personizely merges the two:

1. The current, usually anonymous, visitor is merged **into the existing profile**. The existing profile receives the newly submitted fields.
2. The anonymous visitor's history (page views, events, goal hits, widget and campaign activity) is moved to the existing profile shortly afterwards, and the anonymous profile is removed.
3. The browser is linked to the existing profile from then on.

Email-platform click IDs merge the same way: a visitor already linked to that contact is reused, and otherwise the contact's email decides which profile to use.

| Before                                                                                  | After identifying with [jane@example.com](mailto\:jane@example.com) |
| --------------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
| Laptop: known visitor with email [jane@example.com](mailto\:jane@example.com), 3 orders | Unchanged                                                           |
| Phone: anonymous visitor, 5 page views                                                  | Merged into the laptop profile: one profile with both histories     |

What merging doesn't do:

- **It doesn't merge campaign assignments.** Each browser keeps the A/B test arms it was assigned. The phone can be in a different arm from the laptop. See [How visitors are assigned to variations](docId\:sAtUYHXtt2H5eBGuGVFDv).
- **It doesn't change the other browser.** The laptop keeps its own cookie and session.
- **It doesn't happen on name or custom fields.** Only email and phone (and email-platform contact IDs) identify the same person.

## Behavior details and limitations

- **Later values overwrite earlier ones.** If a visitor submits a form with a new first name, the profile's first name changes.
- **Anonymous visitors have empty fields.** Visitor fields filters and `{visitor.*}` dynamic text only have values after identification. Use a fallback in dynamic text, for example `{visitor.firstName or 'there'}`.
- **Identification can change targeting results.** After merging into a profile with an earlier first visit, "First visit is now" becomes false and history filters include the merged history.
- **Phone numbers** without a country code are converted to international format using the visitor's country.
- **Consent fields are just fields.** Setting `emailMarketingConsent` records the visitor's consent in Personizely and passes it to integrations; it doesn't change how the snippet stores data. See [Cookies and consent](docId:-HA6dgPmpYmb7x6UZQ_t2).

## Examples

- **Klaviyo campaign links:** with the Klaviyo integration enabled, links carrying `kl_pid` identify subscribers. Target "Visitor fields: Email is not empty" to hide the newsletter popup from them.
- **Personal greeting:** a personalization headline "Welcome back, \{visitor.firstName or 'friend'}" for visitors who arrive from an email.
- **Custom login:** a membership site pushes `identifyVisitor` with the member's email and a custom field "Plan", then targets a renewal widget at "Plan is Annual".

## Troubleshooting

- **Visitor isn't identified from the link** → the email isn't valid, the parameter name isn't exactly `email`, or the click-ID integration isn't enabled. Check the console with `?ply_debug=1`.
- **Fields appear on the next page, not this one** → the value came from a form, `identifyVisitor` or a late parser. Campaigns that already ran on this page aren't re-run with the new data in every case; widgets re-check when their trigger fires.
- **Two people merged into one profile** → they share an email or phone, for example a shared family inbox. Merging is by email and phone only.

## Related

- [Visitor identity, sessions and storage](docId\:pQ7hXClMZqGdoDSHsUCZ5)
- [Visitor fields reference](docId\:imIYkGl2lTiSb6EhnikmB)
- [Custom fields](docId\:km7iOXZLplGl8qZlK582W)
- [Parsers (data parsing engine)](docId\:n_O3ZB1_JFa-N-aEZ4u3U)
- [JavaScript API (window.ply)](docId\:d64TegyOiwNA2GFG1eXPm)
- [Contacts and form submissions](docId\:r6fb_qyzgxzRzBTFzO5AX)
