Tutorial: IP Anonymization in Conversions API: Meta, LinkedIn, and TikTok

Contents
Adherence to global privacy standards necessitates the anonymization of IP addresses before transmission to advertising platforms. This document outlines the procedure for masking IP addresses within the Server-Side Google Tag Manager (ssGTM) environment for Meta, LinkedIn, and TikTok Conversions API integrations.
Step 1: Implementing IP Masking Logic
The anonymization process involves stripping the last octet of the IPv4 address (or the equivalent segment of an IPv6 address). This is typically performed using a Custom Template in ssGTM. The transformation function replaces the last portion of the string with “0”.

function maskIP(ip) {
const octets = ip.split('.');
if (octets.length !== 4) {
return undefined;
}
return octets.slice(0, 3).join('.') + '.0';
}
Step 2: Applying Masking to Payload
Within the CAPI tag configuration, the client_ip_address field is mapped to a variable containing the result of the masking function, rather than the raw HTTP request IP.
Step 3: Platform Specifics
- Meta (Facebook): The
client_ip_addressparameter is masked before being sent within the event payload. - LinkedIn: The
user.ipfield is transformed. - TikTok: The
ipfield within theuserobject is masked.
Payload Example
Raw Payload (Before Masking):
{
"client_ip_address": "192.168.1.45",
"event_name": "Purchase"
}
Masked Payload (After Masking):
{
"client_ip_address": "192.168.1.0",
"event_name": "Purchase"
}
2 comments
Having the three platforms and their differing field names side by side is genuinely useful —
client_ip_address,user.ipand the nestedipare easy to mix up when the same masked value feeds all three.About the function itself: anything that is not four octets returns
undefined, so IPv6 traffic ends up with no IP at all. Is dropping the field the intended outcome, or should a masked IPv6 be sent instead?Dropping it is the safe outcome and the right default — an unmasked address is the one failure that cannot be corrected afterwards. It is not a free choice, though, and the cost is measurable.
All three platforms use the IP as one matching signal among several. Removing it for the IPv6 share lowers match quality for exactly that slice of traffic, and that slice is not small: on mobile networks it is frequently the majority. So the decision is between coverage and correctness, and it deserves to be made deliberately rather than inherited from a regular expression.
Both routes are defensible. Implementing the IPv6 branch — zeroing the trailing segments, the equivalent of dropping the last octet — keeps the signal. Accepting the drop is fine too, as long as its size is known: a daily count of events sent without a client IP turns an invisible design decision into a number, and that number is what a later conversation about match quality will need.