Playbook: Segment and Mixpanel Identity Resolution via Edge User ID

Version: 0.1
Last updated: 2026-04-27
Audience: LLM agents and humans implementing identity stitching between Edge-to-Activation, Segment, and Mixpanel.


Purpose

This playbook details how to resolve anonymous and known user identities across three systems: Edge (CDN/Edge layer), Segment (CDP/identity graph), and Mixpanel (product analytics). Specifically, it covers how to make Segment and Mixpanel recognize that an edge_user_id created at the Edge layer belongs to the same person who later logs in or registers, so that pre-login events (clicks, intake, purchases) and post-login traits (email, phone) are stitched into a single unified profile.

This exists because Edge-to-Activation recovers attribution signals that client-side pixels miss, but those signals are only valuable if they can be tied back to the real person in downstream tools.


When to use

Use this playbook when:

  • Edge-to-Activation is already capturing traffic and you need to activate that data in Segment and Mixpanel
  • A client’s Segment to Mixpanel pipeline shows broken identity stitching (e.g. anonymous events never merge into known profiles)
  • You are wiring edge_user_id into website analytics.identify() calls on login or registration
  • You need to reconcile Edge-derived events with Segment’s identity graph and Mixpanel’s user profiles

Do not use this playbook when:

  • The client does not use Segment or Mixpanel (use the generic Edge-to-Activation Implementation Playbook instead)
  • You are only doing a gap analysis or discrepancy report without fixing identity resolution (use the SOP: Edge-to-Activation Phase 0 instead)
  • The identity stitching problem is purely within Mixpanel (no Segment in the path)

Service line / subservice

FieldValue
Service lineData Platform & Analytics → data-infrastructure
Primary subserviceActivation & Attribution → activation-attribution
NotesThis playbook is a Phase 1–2 add-on to the core Edge-to-Activation engagement. Requires Edge layer already deployed.

Approval-before-execution pipeline

GateWhen to stop for approval
1. Segment destination auditBefore enabling any new or existing Mixpanel destinations in Segment. Verify there is exactly one active destination per Mixpanel project to avoid duplicate identify calls.
2. Traits and PII mappingBefore sending email, phone, or other PII traits through Segment. Confirm with the client which traits are allowed and whether consent has been captured.
3. Production identity syncBefore enabling Segment’s Profile Sync (Unify) or warehouse-to-Segment reverse ETL in production. Validate in Segment’s debugger that edge_user_id appears on events and that the identity graph resolves correctly.

Scope

In scope

  • Instrumenting edge_user_id into website interactions (clicks, intake, login/register, purchase, abandonment)
  • Sending analytics.identify() with edge_user_id, email, and phone on login/register
  • Configuring Segment to bridge edge_user_id with Segment anonymous_id and user_id
  • Mapping Segment identity resolution to Mixpanel user profiles
  • Validating that pre-login Edge events stitch to post-login known profiles in Mixpanel
  • Troubleshooting duplicate profiles, disabled destinations, and staging table misrouting

Out of scope

  • Deploying or configuring the Edge layer itself (see Edge-to-Activation Implementation Playbook)
  • Configuring the warehouse schema or BigQuery/Snowflake ingestion (see SOP)
  • Building custom Mixpanel reports or dashboards
  • GDPR/consent platform configuration (see SOP Compliance Controls add-on)

Prerequisites

RequirementNotes
Edge layer deployed and streaming events to warehouseUsually Cloudflare Workers → BigQuery/Snowflake
edge_user_id available in browser contextTypically set as a first-party cookie or returned from an Edge session-start API
Segment source configured for the websiteJavaScript source or GTM-managed source with analytics.js loaded
Mixpanel destination configured in SegmentAt least one Mixpanel destination exists in the Segment workspace
Access to Segment workspaceDebugger, Sources, Destinations, and Unify/Profiles access
Access to Mixpanel projectUser profiles, event stream, and identity merge tooling

Inputs

InputExampleNotes
edge_user_idedge_abc123def456UUID or stable string created at Edge Session Start; persisted in cookie/localStorage
segment_anonymous_idanon_xyz789Auto-generated by analytics.js on first page load
user_idu_987654321Client’s internal user ID, created on login/registration
transaction_idtxn_555444333Order/transaction identifier from Edge ‘thank you’ visit or backend
Customer traits{ email: "user@example.com", phone: "+1-555-0100", first_name: "Jane" }Sent in analytics.identify() at login/register

Workflow

Step 1 — Verify Edge ID collection and propagation

Confirm that edge_user_id is created at Edge Session Start and is accessible to the website JavaScript.

  • Check the Edge Worker response sets a first-party cookie (e.g. __edge_uid) or returns edge_user_id in a JSON payload.
  • Confirm the website reads this cookie and makes it available to the tracking layer.
  • Test: In browser dev tools, verify document.cookie contains __edge_uid on the first request.

Step 2 — Decorate website interactions with edge_user_id (inline approach)

Ensure every analytics.track() call on the website includes edge_user_id in the event properties.

  • Add edge_user_id as a super-property or include it explicitly on every track call:
    analytics.track('Button Clicked', {
      button_id: 'cta-pricing',
      edge_user_id: getEdgeUserId(), // from cookie or localStorage
    });
  • Cover all event types: click events, intake events, login/register events, purchase events, abandonment events.
  • Test: Use Segment Debugger to confirm edge_user_id appears on every event payload.

Step 2a — Decorate website interactions via Google Tag Manager (GTM variant)

If the client manages Segment through GTM rather than inline analytics.js, push edge_user_id through the data layer and wire it into the Segment tag.

  • On page load, push edge_user_id to the data layer:
    window.dataLayer = window.dataLayer || [];
    window.dataLayer.push({
      edge_user_id: getEdgeUserId(),
      event: 'edge_id_ready'
    });
  • In GTM, create a Data Layer Variable named dlv - edge_user_id that reads edge_user_id from the data layer.
  • In the Segment tag configuration, add a custom field or event parameter that maps dlv - edge_user_id to the edge_user_id property on every track call.
  • For identify calls, map the same variable into the traits object.
  • Test: Use GTM Preview mode to confirm the variable populates, then check Segment Debugger for the property.

Step 3 — Configure Segment identity resolution

Tell Segment how to treat edge_user_id as an identifier.

  • In Segment, go to Unify → Identity Resolution (or legacy Profiles settings).
  • Add edge_user_id as an external ID type if it is not already present.
  • Ensure the identity priority order makes sense for the client. Typical order:
    1. user_id (most authoritative)
    2. edge_user_id (stable cross-session)
    3. anonymous_id (least authoritative, session-scoped)
  • Caution: Do not treat edge_user_id as equivalent to device_id unless you have confirmed with the client that the Edge cookie is device-scoped. In many Edge deployments, edge_user_id is a stable browser cookie, so it behaves like a device identifier.

Step 4 — Send analytics.identify() on login and registration

This is the critical stitching moment. When the user logs in or registers, send an identify call that links the anonymous edge_user_id to the known user.

  • On successful login or registration:
    analytics.identify(userId, {
      email: user.email,
      phone: user.phone,
      first_name: user.firstName,
      last_name: user.lastName,
      edge_user_id: getEdgeUserId(), // propagate the same Edge ID
    });
  • If the client uses a custom login flow (e.g. OAuth redirect), ensure the identify call fires after the session is established and the edge_user_id cookie is still readable.
  • Include edge_user_id in the identify traits so Segment can bridge it explicitly. Segment will merge the anonymous profile (with pre-login events) into the known profile.

Step 5 — Map Edge ‘thank you’ and transaction events

Edge captures conversions (e.g. ‘thank you’ page visits) that may not fire client-side pixels due to ad blockers. Ensure these reach Segment.

  • Option A (recommended): Stream Edge events from the warehouse to Segment via a warehouse source or reverse ETL. Include edge_user_id and transaction_id in the mapped payload.
  • Option B: If the website’s purchase confirmation page is reachable, fire a client-side analytics.track('Order Completed', { ... }) with the same transaction_id and edge_user_id.
  • Whichever option you choose, the transaction_id must match between Edge and Segment so that downstream attribution models do not double-count.

Step 6 — Configure Mixpanel destination in Segment

Route the unified profiles to Mixpanel with correct ID mapping.

  • In Segment, open the Mixpanel destination settings.
  • Under Identify, ensure:
    • “Use user_id” is enabled (or the client’s chosen ID)
    • “Map Segment anonymous_id to Mixpanel device_id” is enabled if you want pre-login events to appear as anonymous in Mixpanel
    • “Send identify events” is enabled
  • Under Group User Profile by, select the primary identifier that matches the client’s data model (typically user_id).
  • Critical: Verify there is only one active Mixpanel destination per Mixpanel project. Multiple destinations with identify calls enabled will create duplicate profiles and event streams. If you find multiple destinations, disable or consolidate them.

Step 7 — Validate identity stitching end-to-end

Use a test user to walk through the full journey and confirm stitching.

  1. Open an incognito browser. Clear cookies.
  2. Visit the site. Confirm Edge sets edge_user_id.
  3. Trigger a few tracked events (click, scroll). Confirm they appear in Segment Debugger with anonymous_id and edge_user_id.
  4. Log in or register. Confirm analytics.identify() fires with user_id, email, phone, and edge_user_id.
  5. In Segment’s Profile Explorer (or Unify), verify the anonymous profile now links to the known profile.
  6. In Mixpanel, verify:
    • The user profile shows pre-login events
    • The profile contains email, phone, and edge_user_id traits
    • There are not two profiles for the same person

Visual reference — Segment Debugger: The debugger shows a live event stream in a chronological list. Clicking any event expands a JSON payload panel on the right. Look for properties.edge_user_id and context.traits.edge_user_id in the expanded JSON. A green checkmark next to the event means Segment received it; a red X means it was rejected by a destination or filter.

Visual reference — Event Delivery tab: Open the Mixpanel destination and click the Event Delivery tab. A bar chart appears at the top showing successful vs. dropped events over the selected time range. Below the chart, a Mapping Errors panel lists specific field-level failures (for example, “user_id: invalid format” or “traits.phone: type mismatch”). Green bars = events delivered; red bars = events dropped. Hover over a red bar to see the error count and category.

Step 8 — Reconcile and monitor

Set up ongoing checks to catch identity drift.

  • Weekly check: In Mixpanel, query for profiles where edge_user_id exists but email does not. These are anonymous users who have not yet converted. A sudden spike means the identify call is failing.
  • Weekly check: In Segment, check the Event Delivery tab for the Mixpanel destination. Look for dropped identify events or mapping errors.
  • Monthly check: Compare Edge transaction volume in the warehouse against Mixpanel Order Completed events by transaction_id. Flag discrepancies >5%.
  • Escalation: If identity merge fails for a specific user segment (e.g. OAuth users, mobile app users), open a Linear blocker ticket and tag the engagement lead.

Failure modes / gotchas

  • Duplicate Mixpanel destinations in Segment. Multiple destinations receiving from different sources with identify calls enabled will fork profiles and inflate event counts. Audit destinations before enabling anything.
  • Segment Profile Sync to the wrong warehouse table. If Segment’s Unify/Profile Sync is configured to sync to a staging table rather than the production table that feeds Mixpanel, profiles will look correct in Segment but never reach Mixpanel. Verify the connection table name in Segment → Destinations → Mixpanel → Connection.
  • Disabled Segment to Mixpanel sync. In the Segment destination settings, the toggle or specific event filters may be off. Check the Event Delivery tab and confirm “Enabled” is active. Historical gaps cannot be backfilled automatically.
  • edge_user_id cookie lost on login. If the login flow redirects across domains or clears cookies, the edge_user_id may not be available for the identify call. Ensure the cookie is SameSite=None; Secure if cross-domain, or read it before the redirect and pass it through.
  • Phone number formatting. If phone is sent as a trait, standardize format (E.164) before sending to Segment, or Mixpanel may treat +1-555-0100 and 5550100 as different values.
  • Segment anonymous_id regeneration. If analytics.js is re-initialized or cookies are cleared, a new anonymous_id is created. The edge_user_id is the stable bridge that allows Segment to merge these sessions anyway, but only if edge_user_id is configured as an external ID in Segment.
  • GTM data layer race condition. If the Segment tag fires before the edge_id_ready event pushes to dataLayer, the edge_user_id variable will be undefined. Use a trigger that waits for the edge_id_ready event before firing the Segment tag.
  • Mixpanel device_id confusion. Mixpanel uses device_id for anonymous users. If Segment maps anonymous_id to device_id and the client also sends a native mobile app device_id, Mixpanel may merge unrelated users. Confirm ID sources before enabling the mapping.

Example implementation

Below is a condensed client-agnostic implementation pattern. Client-specific code belongs in the client repo.

Edge Session Start (Cloudflare Worker snippet)

// In the Edge Worker, on first visit
const edgeUserId = crypto.randomUUID();
// Set first-party cookie
response.headers.append('Set-Cookie', `__edge_uid=${edgeUserId}; Path=/; Max-Age=31536000; SameSite=Lax`);
// Stream to warehouse
await streamToWarehouse({ edge_user_id: edgeUserId, session_id: crypto.randomUUID(), timestamp: Date.now() });

Website tracking layer (inline)

function getEdgeUserId() {
  // Read from cookie set by Edge Worker
  const match = document.cookie.match(/__edge_uid=([^;]+)/);
  return match ? match[1] : null;
}
 
// On every track call
analytics.track('Intake Form Submitted', {
  form_id: 'contact-us',
  edge_user_id: getEdgeUserId(),
});
 
// On login success
analytics.identify(user.id, {
  email: user.email,
  phone: user.phone, // E.164 recommended
  first_name: user.firstName,
  last_name: user.lastName,
  edge_user_id: getEdgeUserId(),
});

Website tracking layer (GTM variant)

// Push edge_user_id to data layer on page load
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
  edge_user_id: getEdgeUserId(),
  event: 'edge_id_ready'
});
 
// GTM Configuration Summary:
// 1. Variable: Data Layer Variable "dlv - edge_user_id" → Data Layer Key: edge_user_id
// 2. Trigger: Custom Event "edge_id_ready"
// 3. Tag: Segment - Track Event → Map "dlv - edge_user_id" into event properties
// 4. Tag: Segment - Identify → Map "dlv - edge_user_id" into traits on login/register

Segment destination audit checklist

- [ ] Exactly one Mixpanel destination per Mixpanel project
- [ ] Identify calls enabled and not filtered out
- [ ] `user_id` mapped correctly in destination settings
- [ ] Event Delivery tab shows green for the last 7 days
- [ ] No staging or non-production source accidentally connected to production Mixpanel


Changelog

DateChangeAuthor
2026-04-27Initial draftOpenCode