Required Fields
- Persist event-specific parameters: product_id, product_name, product_category, product_price, product_quantity, currency, value for e-commerce events.
- Include user matching data (hashed email, phone, external_id) for improved Enhanced Match coverage.
- Capture _epik (Pinterest click ID cookie) from the browser to pass to Conversions API.
- Normalize e-commerce objects: currency (ISO 4217 code), value (decimal), product_quantity (integer), and order_id.
- Attach campaign attribution data (utm_source, utm_medium, utm_campaign, epik parameter) for proper ad performance tracking.
- Include event_id and event_time for deduplication between tag and Conversions API events.
Data Layer Structure for GTM
Use a standard dataLayer push format to trigger Pinterest Tag events in Google Tag Manager:
dataLayer.push({
'event': 'pinterest_checkout',
'ecommerce': {
'currency': 'USD',
'value': 79.99,
'order_id': 'ORDER_12345',
'items': [
{
'item_id': 'SKU_12345',
'item_name': 'Organic Cotton T-Shirt',
'item_category': 'Apparel/Shirts',
'quantity': 2,
'price': 39.99
}
]
},
'user_data': {
'email_hash': 'hashed_email_sha256',
'phone_hash': 'hashed_phone_sha256',
'external_id': 'user_12345'
}
});
Map dataLayer variables to Pinterest Tag event parameters in GTM:
- ecommerce.currency → currency
- ecommerce.value → value
- ecommerce.order_id → order_id and event_id
- ecommerce.items[].item_id → product_id (for single product) or product_ids (for multiple)
- ecommerce.items[].item_name → product_name
- ecommerce.items[].item_category → product_category
- ecommerce.items[].quantity → product_quantity
- ecommerce.items[].price → product_price
- user_data.email_hash → em (Enhanced Match, array format)
- user_data.phone_hash → ph (Enhanced Match, array format)
User Data Hashing
Hash personally identifiable information (PII) before adding to the dataLayer or sending to Conversions API. Use SHA-256 hashing and normalize data before hashing:
- Email: Lowercase, trim whitespace, hash with SHA-256.
- Phone: Remove spaces, dashes, parentheses; use E.164 format (+1234567890); hash with SHA-256.
- Name fields: Lowercase, remove special characters, trim whitespace, hash with SHA-256.
- Geographic fields: Lowercase, use standard 2-letter codes for state/country, hash with SHA-256.
Example hashing function (JavaScript):
async function hashSHA256(value) {
const normalized = value.toLowerCase().trim();
const encoder = new TextEncoder();
const data = encoder.encode(normalized);
const hashBuffer = await crypto.subtle.digest('SHA-256', data);
const hashArray = Array.from(new Uint8Array(hashBuffer));
return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
}
// Pinterest requires Enhanced Match in array format
async function prepareEnhancedMatch(email, phone) {
return {
em: [await hashSHA256(email)],
ph: [await hashSHA256(phone)]
};
}
Conversions API Server-Side Data
When sending events from your server to Conversions API, structure the payload to include:
- event_name: Standard or custom event name (e.g., "checkout", "signup", "lead").
- event_time: Unix timestamp in seconds when the event occurred.
- event_id: Unique identifier matching the tag event for deduplication.
- event_source_url: Full URL where the event occurred.
- action_source: "web", "app_ios", "app_android", "offline", etc.
- user_data: Object containing hashed user information and browser data.
- em, ph, ge, db, ln, fn, ct, st, zp, country (all hashed, array format)
- client_ip_address, client_user_agent (not hashed, string format)
- click_id (_epik cookie value, not hashed, string format)
- partner_id (optional, for agencies)
- custom_data: Event-specific parameters (currency, value, product_id, order_id, etc.).
Example Conversions API payload:
{
"data": [
{
"event_name": "checkout",
"action_source": "web",
"event_time": 1640000000,
"event_id": "order_12345",
"event_source_url": "https://example.com/checkout",
"user_data": {
"em": ["a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3"],
"ph": ["+12125551234"],
"client_ip_address": "192.0.2.1",
"client_user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
"click_id": "epik.dj0yJnU9cEFxOTdBMGNlRnBSMHRBQWF5"
},
"custom_data": {
"currency": "USD",
"value": "79.99",
"order_id": "order_12345",
"order_quantity": 2,
"product_ids": ["SKU_12345", "SKU_67890"]
}
}
]
}
Pinterest Click ID (_epik) Handling
Pinterest uses the _epik cookie to track ad clicks and improve attribution. When implementing Conversions API:
- Client-Side: Pinterest Tag automatically sets the _epik cookie when users click Pinterest ads.
- Server-Side: Read the _epik cookie value from the user's browser and pass it in the click_id field of your Conversions API payload.
- Cookie Lifetime: The _epik cookie has a 30-day lifetime and should be included in all server-side events for proper attribution.
Example of reading _epik cookie (JavaScript):
function getCookie(name) {
const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);
if (parts.length === 2) return parts.pop().split(';').shift();
}
const epikValue = getCookie('_epik');
// Send epikValue to your server for inclusion in Conversions API calls
Governance Notes
- Document how consent modifies the dataLayer structure (e.g., do not send hashed PII if user rejects marketing cookies).
- Version the dataLayer schema to keep GTM variables, tag events, and API payloads aligned after code releases.
- Maintain a mapping document between your internal dataLayer and Pinterest's required parameters.
- Establish data retention policies for event_id and event_time to support deduplication lookups.
- Store _epik cookie values securely when passing from client to server for API calls.
Validation Steps
- Check Pinterest Tag Helper to confirm parameters are populated correctly for each event.
- Review Ads Manager Event History for both tag and API events to verify parameter completeness and accuracy.
- Validate Enhanced Match coverage percentage by checking Ads Manager diagnostics.
- Use GTM Preview mode to inspect dataLayer contents before and after event triggers.
- Screenshot dataLayer snapshots and Event History payloads for compliance and audit documentation.
- Test hashing functions with known inputs to confirm SHA-256 output matches expected values.
- Verify _epik cookie is being captured and sent correctly in Conversions API payloads.
- Confirm all Enhanced Match fields are sent as arrays, even for single values.