Pixels
LinkedIn Insight Tag Setup for South Africa.
LinkedIn Insight Tag is the B2B measurement layer most South African agencies and SaaS teams need but skip. It powers Matched Audiences, conversion tracking, and demographic reports for SA decision-makers (IT procurement, finance, fintech). This guide installs the tag, fires a purchase or lead conversion in ZAR, configures the Conversions API for server-side reliability, and handles POPIA consent for LinkedIn's EU processor stack.
Prerequisites
- A LinkedIn Campaign Manager account with billing in ZAR
- Insight Tag Partner ID (6 to 8 digit number in Account Assets > Insight Tag)
- Admin access to your CMS, Shopify theme, or GTM container
- POPIA consent banner wired for marketing consent
Step 1. Generate the Insight Tag and grab the Partner ID
Campaign Manager > Account Assets > Insight Tag > Install manually. Copy the snippet and note your Partner ID (e.g. 1234567). LinkedIn only issues one tag per account — domain-level filtering happens inside Matched Audiences.
Step 2. Install the base tag
Paste the snippet into <head> of every page. Put it below any consent-gating script so you can hold it until the visitor opts in.
<script type="text/javascript">
_linkedin_partner_id = "YOUR_PARTNER_ID";
window._linkedin_data_partner_ids = window._linkedin_data_partner_ids || [];
window._linkedin_data_partner_ids.push(_linkedin_partner_id);
</script>
<script type="text/javascript">
(function(l) {
if (!l){window.lintrk = function(a,b){window.lintrk.q.push([a,b])};
window.lintrk.q=[]}
var s = document.getElementsByTagName("script")[0];
var b = document.createElement("script");
b.type = "text/javascript";b.async = true;
b.src = "https://snap.licdn.com/li.lms-analytics/insight.min.js";
s.parentNode.insertBefore(b, s);})(window.lintrk);
</script>
<noscript>
<img height="1" width="1" style="display:none;" alt="" src="https://px.ads.linkedin.com/collect/?pid=YOUR_PARTNER_ID&fmt=gif" />
</noscript> Step 3. Gate behind POPIA marketing consent
LinkedIn drops the bcookie and lidc cookies. Under POPIA that is marketing-category processing. Delay loading until consent lands — simplest is to inject the script tags dynamically on the consent:accepted event.
function loadLinkedInInsight(partnerId) {
if (window.lintrk || document.querySelector('script[src*="li.lms-analytics"]')) return;
window._linkedin_partner_id = partnerId;
window._linkedin_data_partner_ids = window._linkedin_data_partner_ids || [];
window._linkedin_data_partner_ids.push(partnerId);
window.lintrk = function(a, b) { window.lintrk.q.push([a, b]); };
window.lintrk.q = [];
const s = document.createElement('script');
s.async = true;
s.src = 'https://snap.licdn.com/li.lms-analytics/insight.min.js';
document.head.appendChild(s);
}
document.addEventListener('popia:consent:accepted', (e) => {
if (e.detail.categories.includes('marketing')) {
loadLinkedInInsight('YOUR_PARTNER_ID');
}
}); Step 4. Create conversion actions in Campaign Manager
Account Assets > Conversions > Create conversion. For a Shopify B2B store, create "Purchase" with a Rand value. For a SaaS demo flow, create "Lead - Demo requested". Use "Event-specific" with a JavaScript trigger.
Step 5. Fire conversions with lintrk
Each conversion has a Conversion ID you call lintrk("track", ...) with. Include the Rand value and the conversion ID. LinkedIn does not accept a currency field in the tag — it picks up your Campaign Manager account currency.
analytics.subscribe('checkout_completed', (event) => {
const c = event.data.checkout;
window.lintrk && window.lintrk('track', {
conversion_id: 'YOUR_CONVERSION_ID',
// value is in account currency (set account to ZAR)
value: Number(c.totalPrice.amount)
});
});
// Lead form example
document.querySelector('#demo-form')?.addEventListener('submit', () => {
window.lintrk && window.lintrk('track', { conversion_id: 'LEAD_CONVERSION_ID' });
}); Step 6. Add LinkedIn Conversions API for server-side
For iOS and consent-gated traffic, LinkedIn now supports a Conversions API. Send a POST to the REST endpoint with hashed email or LinkedIn first-party ID. Use this for lead-gen flows where the shopper filled a form — email is the strongest matcher on LinkedIn. Check current LinkedIn Marketing API docs for the correct LinkedIn-Version header value.
export interface Env { LI_ACCESS_TOKEN: string; LI_CONVERSION_RULE_URN: string; }
async function sha256(v: string) {
const buf = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(v.trim().toLowerCase()));
return [...new Uint8Array(buf)].map(b => b.toString(16).padStart(2, '0')).join('');
}
export default {
async fetch(req: Request, env: Env): Promise<Response> {
const ev = await req.json<any>();
const body = {
conversion: env.LI_CONVERSION_RULE_URN, // e.g. 'urn:lla:llaPartnerConversion:1234567'
conversionHappenedAt: Date.now(),
conversionValue: {
currencyCode: 'ZAR',
amount: String(ev.value),
},
user: {
userIds: [{
idType: 'SHA256_EMAIL',
idValue: await sha256(ev.email),
}],
},
};
const res = await fetch('https://api.linkedin.com/rest/conversionEvents', {
method: 'POST',
headers: {
'Authorization': `Bearer ${env.LI_ACCESS_TOKEN}`,
'LinkedIn-Version': '202404',
'Content-Type': 'application/json',
'X-RestLi-Protocol-Version': '2.0.0',
},
body: JSON.stringify(body),
});
return new Response(await res.text(), { status: res.status });
}
}; Step 7. Verify with the Insight Tag Helper
Install the "LinkedIn Insight Tag Helper" Chrome extension. Load your site after accepting consent. The extension should show "Active" with your Partner ID. Fire a test conversion — check Campaign Manager > Conversions within 2 hours for it to appear.
Step 8. Build a SA-targeted Matched Audience
In Campaign Manager > Account Assets > Matched Audiences > Create audience > Website audience. Filter by URL contains "/za/" or your SA-specific path. 300 members minimum before it activates. Pair with seniority and job function filters for B2B targeting.
SA gotchas
- LinkedIn conversion value currency is pulled from your Campaign Manager account, not from the lintrk call. Make sure the account is ZAR before sending value.
- LinkedIn's Insight Tag is a single shared tag per ad account — if an agency manages multiple SA clients on one account, conversions blur. Use separate ad accounts per brand.
- lintrk("track", { conversion_id }) fails silently if the Insight Tag script has not loaded yet. Queue the call via _linkedin_data_partner_ids.push and let lintrk consume it.
- LinkedIn drops its own consent banner on EU IPs due to GDPR. SA IPs currently do not trigger that, so you are responsible for your own POPIA banner.
- The Conversions API expects LinkedIn-Version header in YYYYMM format. Omitting it returns a 400 with an opaque error.
Frequently asked questions
Is LinkedIn Insight Tag POPIA compliant?
With marketing consent, yes. LinkedIn Ireland acts as a processor for EU ingestion; data is transferred to the US under Standard Contractual Clauses. Disclose this in your privacy policy.
Do I need LinkedIn Insight Tag if I only run B2C ecommerce?
Probably not — LinkedIn is a B2B channel. For DTC Shopify stores, skip it. For SA SaaS, agencies, or wholesale ecom targeting procurement managers, it earns its keep.
How long does Matched Audiences take to build?
It needs 300 members minimum. For a moderately-trafficked SA B2B site (around 5,000 visits per month), expect 2 to 4 weeks.
Will LinkedIn Insight Tag work after the third-party cookie sunset?
LinkedIn is already shifting to first-party bcookie and the Conversions API. Retargeting audiences will shrink but conversion tracking survives.