LinkedIn Conversions API in n8n: measuring B2B conversions beyond the click
Published 11 August 2026 · 6 min read
A click on a LinkedIn ad and the contract signature that follows it are rarely minutes apart: in a typical B2B sale, several weeks or even months pass between the two — well beyond the window the LinkedIn Insight Tag can track in a browser. The problem isn't unique to LinkedIn — a study by Guy Aridor, Yeon-Koo Che, Brett Hollenbeck, Daniel McCarthy, and Maximilian Kaiser published in Management Science (2025) showed that after Apple's App Tracking Transparency rolled out, conversion-optimized Meta ads saw their click-through rate drop by 37%, an effect directly tied to the advertiser-side loss of measurement signal. Any ad platform whose attribution depends on browser-side tracking faces the same erosion — and on the B2B side, LinkedIn addresses this with its own Conversions API, which lets you import conversions observed in your CRM long after the initial click. This guide walks through building that pipeline in n8n, from the CRM status change to the API call.
Why the Conversions API matters especially in B2B
The LinkedIn Insight Tag, like any browser-installed tag, measures what happens in a short window around a click or visit: a demo request, a whitepaper download. But the action that actually matters for a B2B ad budget — an accepted quote, a signed contract, an activated subscription — typically happens in the CRM weeks later, after several sales back-and-forths invisible to LinkedIn. Without an explicit report-back, Campaign Manager optimizes bids on micro-conversions (clicks, form fills) that don't always reflect the real quality of leads each campaign generates.
The Conversions API closes that gap by accepting offline conversions: your CRM (HubSpot, Pipedrive, Salesforce) notifies n8n as soon as a deal changes status, and the workflow forwards the event to LinkedIn with the real conversion date and the contact's identifiers. LinkedIn can then match this delayed conversion back to the campaign and the member who clicked, and re-optimize bidding based on actual business value instead of a bare click.
How the LinkedIn Conversions API works
Two prerequisites before any API call:
- Create the conversion rule in Campaign Manager (Data → Conversion tracking), which generates a URN of the form
urn:lla:llaPartnerConversion:{id}— every event references this identifier. - Generate an access token from Data → Signals manager → Direct API → Generate access token. This token, scoped to your ad account, requires no developer application and never expires — store it as a dedicated n8n credential, the same way you would any other sensitive API key.
The endpoint is a POST to https://api.linkedin.com/rest/conversionEvents, with the headers Authorization: Bearer {token}, LinkedIn-Version (the current API version), and X-Restli-Protocol-Version: 2.0.0. The expected body for one event:
{
"conversion": "urn:lla:llaPartnerConversion:123456789",
"conversionHappenedAt": 1754812800000,
"conversionValue": {
"currencyCode": "EUR",
"amount": "1490.00"
},
"user": {
"userIds": [
{ "idType": "SHA256_EMAIL", "idValue": "{{ $json.email_hash }}" }
],
"userInfo": {
"firstName": "{{ $json.first_name }}",
"lastName": "{{ $json.last_name }}",
"companyName": "{{ $json.company_name }}",
"countryCode": "{{ $json.country_code }}"
}
},
"eventId": "{{ $json.deal_id }}"
}
conversionHappenedAt is an epoch timestamp in milliseconds for the actual conversion date (the deal's signature), not the moment the API call is sent. eventId handles deduplication: reusing the CRM deal's identifier guarantees that an accidental resend of the same event isn't counted twice.
Building the workflow in n8n
Step 1 — Trigger on the real business event
The trigger isn't the ad click (already measured by the Insight Tag) but the CRM status change: a deal marked "Closed Won" in HubSpot or Pipedrive, captured via a native outgoing webhook or regular polling — see our guide on syncing HubSpot/Pipedrive CRM data and our article on Salesforce and n8n for setting up this trigger depending on your CRM. An upstream filter (a Filter or IF node) only lets through deals whose stage genuinely corresponds to a billable conversion, not just an intermediate pipeline step.
Step 2 — Normalize and hash the email
Only the email needs to be SHA-256 hashed before sending; the other userInfo fields (first name, last name, company, country) stay in plain text, since they serve as a fallback matching method when LinkedIn can't match the hashed email. A Code node placed after the trigger prepares these fields:
const crypto = require('crypto');
const hash = (value) =>
crypto.createHash('sha256').update(value.trim().toLowerCase()).digest('hex');
return [{
json: {
...$json,
email_hash: hash($json.contact_email),
},
}];
The Crypto node in Hash mode (SHA256, HEX output) — see our Crypto node guide — does the exact same computation without code, if you'd rather stick to standard nodes.
Step 3 — Build the payload and call the API
A Set node assembles the JSON in the conversionEvents format shown above, then an HTTP Request node does a POST to https://api.linkedin.com/rest/conversionEvents, with the token stored as a credential — the same discipline detailed in our guide on securing credentials and API keys. For an initial import (a history of already-signed deals), the API accepts an array of multiple events in a single request, up to 5,000 per batch — plenty to catch up on several months of CRM history in a handful of calls instead of one call per deal.
Step 4 — Filter out duplicate sends
A CRM webhook that fires twice for the same status update (a network redelivery, a redundant sync) would otherwise send the same conversion to LinkedIn twice. The principle is identical to the one described in our article on webhook idempotency: check in a Supabase table whether the eventId (the deal's identifier) has already been sent before triggering the API call, rather than relying solely on LinkedIn's own deduplication.
Step 5 — Verify in Campaign Manager
Under Analyze → Conversion tracking, the conversion rule shows the number of events received per source (Insight Tag vs. Conversions API), with a delay of a few minutes to a few hours depending on volume. This is the point to confirm that amounts (conversionValue) and dates line up with the real deals before rolling the send out across the whole sales pipeline.
Best practices and common pitfalls
- Respect the 90-day window:
conversionHappenedAtmust fall within the 90 days before the request is sent — not 90 days after the ad click. A CRM that marks a deal signed with a delay of several months should trigger the send promptly once the status updates. - Never hash the
userInfofields — unlike the email, they need to stay in plain text to serve as an alternate matching method. - Reuse the CRM deal's identifier as
eventId, never a randomly generated one per attempt, so that LinkedIn's deduplication and your own idempotency check point to the same key. - Watch the rate limits (600 requests/minute, 500,000/day per token) if several workflows share the same ad account — batching sends once volume exceeds a few dozen deals a day keeps you well clear of those thresholds.
- The same overall pattern — CRM trigger, email hashing, structured payload, deduplication by a shared identifier — shows up almost identically in our guide on Meta's Conversions API and on the GA4 Measurement Protocol: once you've built the first pipeline in n8n, the next ones reuse the same node structure with a different endpoint and payload shape.
Wrapping up
Building a LinkedIn Conversions API pipeline in n8n comes down to five pieces: a trigger on the real business event (a CRM status change, not the click), SHA-256 hashing of the email alone, a structured call to conversionEvents with a shared eventId for deduplication, an idempotency check on the n8n side, and a verification pass in Campaign Manager before rolling it out further. If your n8n instance already orchestrates qualifying your inbound leads or enriching them automatically, adding this send only takes one more node at the end of the existing pipeline. And if you want to log every send to keep a full audit trail of data shared with an advertising third party, the Supabase logging workflows in the Compliance & Audit Pack (€149) follow exactly the same logging principle described in our article on GDPR audit trails with Supabase, applied here to a conversion feed instead of an internal personal-data flow.
FAQ
Frequently asked questions
Should you remove the LinkedIn Insight Tag once the Conversions API is wired up?
No, the two are complementary rather than redundant. The Insight Tag captures what happens in the browser's short window (a page visit, a form click), while the Conversions API captures events that arrive much later on the CRM side — often weeks after the ad click in a B2B sales cycle. Sharing the same `eventId` between the two prevents the same conversion from being counted twice in Campaign Manager.
Which fields need to be hashed before sending them to the API?
Only the primary identifier — the email, via `idType: SHA256_EMAIL` — needs to be SHA-256 hashed, after lowercasing. The other possible matching fields (first name, last name, job title, company, country, grouped under `userInfo`) travel in plain text: they serve as a fallback matching method when no hashed identifier or LinkedIn UUID is available, and hashing them would make them unusable for LinkedIn.
Can you report a deal signed six months after the ad click?
The API accepts an event whose `conversionHappenedAt` is up to 90 days before the request is sent — not 90 days after the initial ad click. In practice, you need to send the event to LinkedIn within 90 days of the actual conversion date (the deal's signature), regardless of how long ago the ad click happened. A CRM that marks a deal 'Closed Won' with a delay should therefore trigger the send promptly once the status updates, not months later.
What rate limits should you know about before sending a large volume of deals?
A Campaign Manager access token is capped at 600 requests per minute and 500,000 per day. For a large volume (an initial import of CRM history, for example), the endpoint accepts batches of up to 5,000 events in a single `conversionEvents` request, which keeps the vast majority of B2B accounts comfortably under those caps.
Bundle FlowKit Complet
€269