Why Pinterest CAPI
Pinterest is unusually sensitive to browser-side signal loss because its buying journey is slow and discovery-led. A person may save an idea, compare products, leave the site, return from a board days later, and purchase after another visit. Pinterest attribution commonly uses a 30-day click window and a 1-day view window, which means the platform needs durable links between the ad interaction and the eventual conversion. Safari ITP, short cookie lifetimes, ad blockers, checkout redirects, and consent changes all make that link weaker when you rely on the browser Tag alone. CAPI restores part of the path by sending the final conversion from your server with the original browser context, hashed first-party identifiers, and the epik click identifier when it exists.
Prerequisites
Pinterest Business account with access to the ad account that owns the conversion source.
ad_account_id for the production Pinterest Ads account, not a test or agency-only account.
conversion_access_token generated from Business Manager with permission to send conversion events.
Claimed domain for the shop, landing pages, and checkout domain used by paid Pinterest traffic.
Step-by-step setup
Confirm the event source and ad account
Start in Pinterest Ads Manager and verify that the Pinterest Tag, claimed domain, catalog, and ad account are all tied to the same business. The API endpoint is scoped by ad_account_id, so a valid token can still send unusable events if it belongs to the wrong business or conversion source.
POST https://api.pinterest.com/v5/ad_accounts/{ad_account_id}/events
Authorization: Bearer conversion_access_token
Content-Type: application/json
{
"data": []
}Capture browser context before checkout
The server needs values that only the browser sees at landing or interaction time. Capture epik, event_id, IP address, user agent, consent state, and product context before payment redirects or embedded checkout pages can strip query parameters and cookies.
{
"data": [
{
"event_name": "add_to_cart",
"action_source": "web",
"event_time": 1776943226,
"event_id": "cart_10492_add_1",
"user_data": {
"epik": "dj0yJnU9YzJ...",
"client_ip_address": "203.0.113.42",
"client_user_agent": "Mozilla/5.0..."
},
"custom_data": {
"value": 89.95,
"currency": "EUR",
"content_ids": ["SKU-481"]
}
}
]
}Normalize and hash identifiers
Pinterest accepts deterministic match keys, but they should be normalized before hashing. Lowercase and trim email, format phone numbers consistently, then SHA-256 hash those values unless your tracking layer performs the transformation. Never hash epik, IP address, or user agent.
{
"data": [
{
"event_name": "checkout",
"action_source": "web",
"event_time": 1776943312,
"event_id": "chk_10492_start",
"user_data": {
"em": ["sha256_lowercase_email"],
"ph": ["sha256_e164_phone"],
"epik": "dj0yJnU9YzJ...",
"client_ip_address": "203.0.113.42",
"client_user_agent": "Mozilla/5.0..."
}
}
]
}Send purchase truth from the backend
For checkout_complete or custom purchase events, use the order system as the source of truth. Send value as a number, currency as a three-letter ISO code, and content_ids that match your catalog feed. Keep refund, tax, shipping, and discount policy aligned with how your media team reports revenue.
{
"data": [
{
"event_name": "checkout_complete",
"action_source": "web",
"event_time": 1776943380,
"event_id": "ord_10492_purchase",
"user_data": {
"em": ["sha256_lowercase_email"],
"ph": ["sha256_e164_phone"],
"epik": "dj0yJnU9YzJ...",
"client_ip_address": "203.0.113.42",
"client_user_agent": "Mozilla/5.0..."
},
"custom_data": {
"value": 129.95,
"currency": "EUR",
"content_ids": ["SKU-481", "SKU-812"]
}
}
]
}Log responses and retry safely
Pinterest CAPI should be operated like other revenue infrastructure. Store request IDs, event IDs, consent decisions, match keys present, response status, and retry count. Retry network failures with backoff, but avoid replaying accepted purchases with a new event_id because that can create duplicate conversion candidates.
{
"data": [
{
"event_name": "lead",
"action_source": "web",
"event_time": 1776943445,
"event_id": "lead_77821_submit",
"user_data": {
"em": ["sha256_lowercase_email"],
"epik": "dj0yJnU9YzJ...",
"client_ip_address": "203.0.113.42",
"client_user_agent": "Mozilla/5.0..."
}
}
]
}Required fields
Pinterest will process some sparse events, but sparse payloads give the platform little to match or optimize. Use this table as the production contract for web commerce, lead, and checkout events. The important rule is consistency: event names, IDs, timestamps, and value fields should mean the same thing in the Pinterest Tag, CAPI, analytics, and your backend logs.
| Field | Type | Required | Purpose | Example |
|---|---|---|---|---|
| event_name | string | Yes | Names the conversion action Pinterest should process. | checkout_complete |
| action_source | string | Yes | Identifies where the action happened. | web |
| event_time | integer | Yes | Unix timestamp in seconds from the actual event moment. | 1776943380 |
| event_id | string | Recommended | Deduplicates matching Pinterest Tag and CAPI events. | ord_10492_purchase |
| user_data.em | sha256 string array | Recommended | Hashed normalized email for deterministic matching. | ["6b3a55e0261b..."] |
| user_data.ph | sha256 string array | Recommended | Hashed normalized phone number. | ["b49f9168e8a8..."] |
| user_data.epik | string | Recommended | Pinterest first-party click identifier from paid sessions. | dj0yJnU9YzJ... |
| user_data.client_ip_address | string | Recommended | Client IP address from the shopper request. | 203.0.113.42 |
| user_data.client_user_agent | string | Recommended | Browser and device context for matching and validation. | Mozilla/5.0... |
| custom_data.value | number | For purchases | Revenue value used for reporting and optimization. | 129.95 |
| custom_data.currency | string | For purchases | ISO 4217 currency code for the value field. | EUR |
| custom_data.content_ids | string array | Recommended | Catalog or SKU IDs associated with the conversion. | ["SKU-481"] |
The epik cookie
epik is Pinterest's first-party click identifier. When a user lands from a Pinterest ad, Pinterest can append an epik value to the URL and the Pinterest Tag can preserve that value in browser storage. For CAPI, the job is simple — read epik as early as possible, store it on the session or cart, and forward the same value with later server events. If the purchase happens after a payment redirect, your order webhook will not be able to recover the original ad click unless you already attached epik to the checkout state.
The closest Meta comparison is fbp, but the roles are not identical. fbp is a browser identifier created by Meta Pixel to recognize the browser over time; epik is closer to a Pinterest click identifier that proves the session came from a Pinterest ad. Both are sent raw, not hashed. Both should be captured before the browser context changes. Neither replaces deterministic user_data such as hashed email or phone.
function readPinterestEpik() {
const params = new URLSearchParams(window.location.search);
const fromUrl = params.get("epik");
const fromCookie = document.cookie
.split("; ")
.find((part) => part.startsWith("_epik="))
?.split("=")[1];
return fromUrl || fromCookie || null;
}
await fetch("/api/cart/context", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({
epik: readPinterestEpik(),
user_agent: navigator.userAgent
})
});Dedup with Pixel
Deduplication prevents the Pinterest Tag and CAPI from turning one user action into two conversion candidates. Generate one event_id for each meaningful action, pass it to the browser Tag, and send the same value in the server payload. A useful convention is source_entity_action: cart_10492_add, chk_10492_start, or ord_10492_purchase. The ID should be unique per action, readable in diagnostics, and stable across retries.
const eventId = "ord_10492_purchase";
pintrk("track", "checkout_complete", {
event_id: eventId,
value: 129.95,
currency: "EUR",
order_id: "10492"
});
await fetch("/api/tracklayer/pinterest-capi", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({
event_name: "checkout_complete",
action_source: "web",
event_time: Math.floor(Date.now() / 1000),
event_id: eventId,
user_data: {
em: [sha256(normalizeEmail(customer.email))],
epik: readPinterestEpik(),
client_user_agent: navigator.userAgent
},
custom_data: {
value: 129.95,
currency: "EUR",
content_ids: ["SKU-481"]
}
})
});Testing with Events Manager
Use a real browser journey
Open a paid-traffic-style landing URL, confirm epik is present, then trigger page visit, add_to_cart, checkout, and checkout_complete from the same session.
Compare browser and server events
In Events Manager, verify that Pinterest receives Tag and CAPI events with the same event_name and event_id. Dedup warnings usually mean the ID was generated twice or lost during checkout.
Review diagnostics after processing
Wait for the Events Manager diagnostics window to populate, then check rejected fields, stale timestamps, missing user_data, domain issues, and token authorization errors.
Enhanced Match
Pinterest's equivalent to Meta Event Match Quality is the Pinterest Match Rate score. It reflects whether the platform has enough permitted identifiers and context to connect server events with Pinterest users and ad interactions. A higher score does not guarantee more revenue, but it usually means your payloads are less anonymous and easier to use for attribution and optimization.
Capture email at login, newsletter signup, lead forms, and checkout, then normalize and hash it consistently.
Normalize phone numbers to a single international format before hashing.
Persist epik from the first landing request through cart, checkout, payment, and order creation.
Forward raw client_ip_address and client_user_agent from the browser request, not your server or queue worker.
Keep content_ids aligned with the product catalog so Pinterest can connect events to shopping ads and product groups.
Consent Mode handling
Pinterest cannot treat user-denied consent as a technical detail. If advertising storage, ad measurement, or sale or sharing choices are denied under your regional policy, your server pipeline should either suppress the Pinterest event or remove identifiers that are no longer eligible. The important part is symmetry: the browser Tag and CAPI destination must respect the same CMP decision.
A durable pattern is to capture consent at the event edge, attach it to the event envelope, and evaluate destination rules just before dispatch. With denied ad consent, TrackLayer-style routing can keep the internal order event for analytics or operations while withholding Pinterest user_data, epik, or the full event according to your legal basis and platform configuration.
Troubleshooting
Invalid or unauthorized token
Regenerate the conversion_access_token from the correct Pinterest Business account and confirm the token can access the target ad_account_id.
Events accepted but not attributed
Check epik capture, claimed domain status, event_time freshness, and whether campaigns actually drove the session within Pinterest attribution windows.
Duplicate purchase diagnostics
Generate event_id once per action and reuse it for both the Pinterest Tag and CAPI payload. Do not mint a second server ID.
Low Pinterest Match Rate score
Add hashed email or phone where consent allows, preserve epik, and forward client IP plus user agent from the original browser request.
Invalid custom_data or catalog mismatch
Send value as a number, currency as an ISO code, and content_ids that exactly match the IDs in your Pinterest catalog feed.
Common questions
Can Pinterest CAPI replace the Pinterest Tag?
Usually no. The Tag still captures page context, browser identifiers, and immediate interaction signals. CAPI strengthens conversion delivery, especially after checkout redirects and browser loss, but the best setup runs both together.
Do I need epik for every event?
No, organic and direct sessions may not have epik. For paid Pinterest traffic, preserving epik is one of the highest-value improvements because it keeps the server event tied to the ad click.
Should I hash epik?
No. Hash personal identifiers such as email and phone after normalization. Send epik, client_ip_address, and client_user_agent in the raw format Pinterest expects.
How quickly will diagnostics update?
Test events can appear quickly, while production diagnostics and match rate trends often need several hours and enough conversion volume to become meaningful.
What is the safest rollout plan?
Start with page_visit, add_to_cart, checkout, lead, and checkout_complete in a staging or limited production mode. Confirm deduplication and consent behavior before routing all purchase volume.
Related implementation guides
Meta CAPI setup guide
Compare Pinterest CAPI with Meta CAPI, including deduplication, user_data, and Events Manager diagnostics.
Read guide →TikTok Events API guide
Build TikTok server events with ttclid, ttp, event_id, and consent-aware forwarding.
Read guide →Deduplication explained
How browser and server events become one conversion across paid media platforms.
Read guide →