Vendor · engineers · marketers
Pinterest Tag plus Conversions API
Retail catalogs punish mismatched ids more than social clicks do. The pixel can be working while dynamic ads show the wrong SKU.
Tag (browser)
ct.pinterest.com, including the noscript image. tid is the tag ID (required). event, when present, is one of the documented names (pagevisit, checkout, addtocart, and the rest); custom names warn. noscript is 0 or 1. AddToCart and Checkout need the same product ids the catalog feed uses. A conversion with empty content ids still counts, then catalog ads have nothing to hang the creative on.
Dedup against CAPI only works if the tag and the server send the same event_id. A random UUID in the tag and a second UUID in the shop backend is two checkouts. Generate it on the order, pass it to the page, or mint on the page and POST it with the order. Network filter: ct.pinterest.com. Two base codes are two pagevisits. Pack page /packs/pinterest/. Raw email in the query is still a leak.
pixellint validate url @pin-tag.txt --rulepack vendor/pinterest
CAPI: web lowercase, event_id required, seconds
POST api.pinterest.com/v5/ad_accounts/{ad_account_id}/events. Per event in data: event_name required (custom allowed, so no enum error). action_source required: web, app_android, app_ios, or offline. Pinterest spells web in lower case. event_id is required for tag dedup (Meta only recommends it; omitting it here is an error). event_time is Unix seconds, 10 digits. A 13-digit value is milliseconds and invalid.
user_data required, with at least em, hashed_maids, or client_ip_address (with user agent). em, ph, external_id, hashed_maids are SHA-256 hex. IP and UA must not be digests (hashed_plaintext_field). Unhashed email is flagged. event_source_url is the page, not your API host. Pack page: /packs/pinterest-conversions-api/.
{
"data": [{
"event_name": "checkout",
"action_source": "web",
"event_id": "T12345",
"event_time": 1770000000,
"event_source_url": "https://shop.example/thank-you",
"user_data": {
"em": ["64CHARHEXDIGEST"],
"client_ip_address": "203.0.113.10",
"client_user_agent": "Mozilla/5.0"
}
}]
}
action_source spelling and event_id
Snap writes WEB. Meta writes website. Pinterest writes web. A bare JSON body has no host, so the packs tell each other apart by that field. Misspell it and more than one pack reports, or the wrong pack stays quiet. Copying a Meta payload and changing the host is how you fail action_source.
Mint event_id once, send on the tag and on CAPI, persist for retries. Custom event names are allowed (up to 100 characters). Misspelling checkout as Checkout is still a name; map it in Ads Manager or use the documented lowercase names.
Clock, hashing, catalog ids
Seconds, like Meta, unlike LinkedIn and Amplitude. Math.floor(Date.now() / 1000). SHA-256 hex after lowercase email. Do not hash IP or UA. Content ids must match the product feed, not the URL slug, not a Shopify numeric id unless that is what the feed uses. A working conversion count with the wrong SKU is a creative problem you will debug as a pixel problem.
Retail catalogs punish mismatched ids more than social clicks do. Put the feed id on both the tag event and the CAPI payload. Empty content ids still count as a conversion and then leave catalog ads with nothing to hang the creative on.
pixellint validate json @pin-capi.json --rulepack vendor/pinterest-conversions-api
Independence
Pixellint is not affiliated with Pinterest. Tag IDs and access tokens stay in your secret store. Both pipes: tag plus CAPI, shared event_id (required on the server), seconds, lowercase web, hashed PII, plaintext IP and UA. This playbook does not replace the pack pages; it is how to run both pipes without copying Meta's field names.
You can launch tag-only. You cannot call it the recommended Conversions API setup until diagnostics show the server event with the same event_id the tag sent. pixellint validate json --rulepack vendor/pinterest-conversions-api.
Check the artifact
Paste the pixel URL or JSON body into the
playground. Same engine as
pixellint validate. Nothing leaves the tab.