conversion tracking9 min readBy Phloz teamUpdated

LinkedIn Insight Tag + Conversions API: the B2B agency setup that actually attributes

The Insight Tag alone misses much of B2B conversion signal in 2026. The dual Insight Tag + Conversions API setup, deduplicated by event ID.

TL;DR

LinkedIn's Insight Tag has the same browser-erosion problem the Meta and TikTok pixels do — ad blockers, ITP, cross-domain attribution gaps — and B2B feels it harder, because B2B campaigns produce few conversions and each one is a large deal: every conversion the tag misses is signal the bidding can't spare. The fix is the same shape as Meta CAPI: ship Insight Tag + Conversions API together, deduplicate by eventId, fire the API call server-side from your CRM webhook (HubSpot / Salesforce / your backend). Below: the exact setup, the LinkedIn-specific dataset-quality gotchas, and the five places it breaks silently.


LinkedIn ads have a structural problem most B2B agencies don't talk about: the Insight Tag counts conversions in the browser, and the browser is where B2B signal gets lost — ad blockers, hardened browsers, some corporate networks' ad-tech filters, and buying journeys that cross devices and weeks. The pixel says your LinkedIn ads aren't working; the CRM says they are. The CRM saw the leads the pixel missed.

The Conversions API closes that gap. LinkedIn has offered it since 2023, the docs are reasonable, and the integration is easier than Meta's because you don't have to deduplicate against fbp cookies. But the dataset-quality bar LinkedIn enforces for the API is higher than Meta's, and the events the API accepts are narrower. This is the agency-shaped setup — what we ship to every B2B client — including the gotchas the official LinkedIn walkthrough leaves out.

Why Insight-Tag-only is broken for B2B

Three forces, stacked harder on B2B than B2C:

  1. Corporate browsers and VPNs — many B2B prospects browse from a managed device or corporate VPN that proxies traffic through a security layer (Zscaler, Netskope, Cloudflare Gateway). Many of these strip third-party trackers by policy. Pixel doesn't fire; the conversion is invisible to LinkedIn.
  2. Hardened consumer browsers — Firefox + Enhanced Tracking Protection, Brave, Safari + iCloud Private Relay all block or significantly degrade px.ads.linkedin.com requests; how many of a client's visitors run them depends on the audience.
  3. Multi-touch B2B journeys — a B2B buyer touches many brand surfaces over weeks or months before converting. The Insight Tag's 30-day cookie window catches the first touch but not the eventual form fill if the user cleared cookies, switched devices, or hit your site from an email campaign in week 6.

Stack these and the LinkedIn pixel observes only part of the qualified conversions LinkedIn ad spend actually drives — compare its conversions with the leads your client's CRM recorded from LinkedIn to see how much. The algorithm bids worse and worse over time because the feedback loop is starved.

The Conversions API fires from your server, against first-party identifiers (hashed email, phone, LinkedIn profile URL if you have it). It doesn't care about cookies, ad blockers, or VPNs. The events that go through it survive the same browser conditions that kill the pixel.

The setup that works (5 steps)

Step 1: Install the Insight Tag — but make every event carry an eventId

Standard GTM setup; LinkedIn provides the snippet. The non-default piece: every conversion event you fire must include an eventId parameter that exactly matches what the Conversions API call will send.

// In a Custom HTML tag fired on form-submit / book-meeting events:
window.lintrk('track', {
  conversion_id: 12345678,
  // Critical for dedup against the Conversions API call:
  eventId: 'lead_2026_07_abc123'
});

Generate eventId from your CRM lead ID, form submission ID, or any UUID — whatever you use as eventId in the API call must be the same string here. Without it, you'll double-count conversions that fire both Insight Tag and Conversions API.

LinkedIn's pixel lintrk function takes conversion_id (a number) and a metadata object. The eventId lives inside that object.

Step 2: Fire the Conversions API server-side

Trigger from your CRM webhook (HubSpot / Salesforce / Pardot fire on lead capture) or your backend's lead-creation handler. The call shape:

// Node.js, fired on lead-created webhook:
const response = await fetch(
  'https://api.linkedin.com/rest/conversionEvents',
  {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${LI_ACCESS_TOKEN}`,
      'LinkedIn-Version': '202401',
      'X-Restli-Protocol-Version': '2.0.0',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      conversion: 'urn:lla:llaPartnerConversion:12345678',
      conversionHappenedAt: Date.now(),
      conversionValue: {
        currencyCode: 'USD',
        amount: '0',  // B2B leads typically use 0 + value-tier metadata
      },
      eventId: 'lead_2026_07_abc123',  // MUST match the Insight Tag eventId
      user: {
        userIds: [
          { idType: 'SHA256_EMAIL', idValue: sha256(email.toLowerCase().trim()) },
        ],
        userInfo: {
          firstName: lead.firstName,
          lastName: lead.lastName,
          companyName: lead.company,
          title: lead.jobTitle,
        },
      },
    }),
  }
);

Three things B2B agencies often miss:

  • SHA256_EMAIL must be lowercase + trimmed before hashing. LinkedIn rejects mixed-case hashes silently (event accepted, match-quality score 0).
  • userInfo is optional but improves match quality dramatically. LinkedIn matches on email first, then falls back to first/last/company/title combo when the email doesn't match a known LinkedIn member.
  • conversionHappenedAt is milliseconds-since-epoch. LinkedIn rejects events older than 90 days (silently — the API returns 200 but the event won't appear in Campaign Manager).

Step 3: Match events in Campaign Manager

LinkedIn's Campaign Manager has a "Conversions" section where each conversion definition shows its Insight Tag firings, API events received, and deduplicated count. The deduplicated count is what counts for optimization.

For dedup to work, the eventId from the pixel and the API call must arrive within a 30-day window. Most B2B conversions happen in the same minute (form submit fires both client-side pixel and server-side webhook), so this is rarely the bottleneck — but if your CRM webhook is async with multi-hour lag, the pixel-side event can age out. Fire the API call within an hour of the pixel-side event when possible.

If you see Insight Tag firings >> API events received, it usually means the CRM webhook isn't firing or your access token expired. LinkedIn's access tokens last 60 days; rotate ahead of expiry.

Step 4: Verify match-quality score weekly

LinkedIn assigns a match-quality score 0-10 per conversion definition. A low one means LinkedIn can tie few of your conversions to its members, so bidding learns little from them. The score is driven by:

  • Email hash format (lowercase + trimmed before SHA256, no salt)
  • Coverage (% of API events that include userIds vs only userInfo)
  • Freshness (% of events fired within 1 hour of conversion vs days late)
  • Volume (LinkedIn needs 50+ events per definition per 30 days to confidently model)

For agency-managed accounts this becomes a weekly review item. In Phloz's tracking map, each client's LinkedIn Ads account node records the Insight Tag ID and whether the Conversions API is on, and the weekly audit flags an account with neither. The match-quality score itself lives in Campaign Manager — read it on the weekly review, and mark the node verified (or broken) when you do.

Step 5: Set up the partner script (if running enterprise volume)

If a client is spending >$50K/mo on LinkedIn ads, LinkedIn's partner team will provision a dedicated server-to-server integration with a service account, dataset-level access scopes, and webhook callbacks for delivery confirmations. This is over and above the standard Conversions API — it's how the Salesforces and Microsofts of the world ship 100K+ events/month reliably.

For most agency clients you don't need this. For 2-3 of your largest, it's worth asking the LinkedIn rep about. They won't volunteer it.

Five common breakage modes

These are the bugs we see at agency-takeover audits:

  1. Email not lowercased before hashing — match quality drops to near zero. The fix is one line of code, but the symptom looks like "LinkedIn ads aren't converting" so it can persist for months.

  2. eventId differs between pixel and API — the pixel fires eventId: 'lead-12345' and the API fires eventId: 'lead_12345'. Dedup fails; conversions double-count; spend optimization tanks. Always use the literal CRM lead ID, no transformations.

  3. Access token expired silently — LinkedIn doesn't email you when the 60-day token expires. The API starts returning 401. The Insight Tag still fires, so the dashboard looks normal until you notice the API-events count flatlined three weeks ago. Fix: monitor the API response code via your observability stack and alert on 401/403.

  4. CRM webhook payload missing companyName or title — match quality drops because LinkedIn's fallback matchers don't have enough signal. Most CRMs collect this on the form but don't pass it to the webhook by default. Audit the webhook payload, not the CRM record.

  5. Conversion definition pointed at the wrong campaign group — LinkedIn Campaign Manager has an inheritance model where conversion definitions can scope to specific campaigns, campaign groups, or ad accounts. If the definition is scoped to one group but the client's actual spending campaigns are in another, the API events arrive but optimization sees nothing. Check the scoping monthly.

Where this fits in an agency's tracking discipline

LinkedIn Conversions API is the third leg of the platform-tracking stool — alongside Meta Pixel + CAPI and TikTok Pixel + Events API. All three follow the same architectural pattern: client-side pixel for browser-observable events, server-side API for the events the browser misses, deduplicated by eventId. If you've built one well you can build the others quickly.

The piece B2B agencies often miss: B2B conversion volume per account is much lower than B2C. A typical B2C ecom account might fire 5,000 conversions/month; a B2B SaaS account might fire 50. LinkedIn's match-quality score gets unreliable below 50 events/month, which means small-account clients need either bigger conversion definitions (combine MQL and demo-request into one event), longer attribution windows, or more patience before optimization stabilises.

Phloz's tracking infrastructure map records each client's LinkedIn Ads account as a typed node — Insight Tag ID, whether the Conversions API is on, a health state and a last-verified date — and the weekly audit flags an account running neither. The match-quality score stays in Campaign Manager as a weekly recurring check per client, with the node marked verified (or broken) each time. That's how a small agency keeps signal quality high across 30+ B2B clients without one engineer babysitting Campaign Manager all day.

If you're picking a place to start: install the Conversions API on your highest-spend B2B account first. Track the match-quality score weekly for a month. Give the bidding a few weeks of API events before you judge the lift: B2B conversion volume is low, so it learns slowly.