Pinterest Conversions API
Datafly Signal delivers events to Pinterest server-to-server using the Conversions API (CAPI). This provides reliable conversion tracking for Pinterest ad campaigns without relying on the Pinterest Tag client-side script, improving measurement accuracy and ad performance optimisation.
Prerequisites
Before configuring Pinterest CAPI in Signal, you need a Pinterest Business account, an Ads Manager account with a Pinterest Tag, and API credentials. Follow the steps below to set everything up.
Step 1: Create a Pinterest Business Account
- Go to pinterest.com/business/create and click Create Account.
- Enter your email, password, business name, and website URL.
- Complete the business profile by selecting your business type and industry.
- If you already have a personal Pinterest account, convert it to a business account at Settings > Account management > Convert to business account.
Step 2: Set Up Pinterest Ads Manager
- Navigate to ads.pinterest.com and sign in with your business account.
- If prompted, complete the billing setup by adding a payment method under Billing > Payment method.
- Note your Ad Account ID — a numeric ID (e.g.
549764982399) visible in the URL bar or under Ads > Overview > Account Settings.
Your Ad Account ID is different from your profile ID. It is a numeric string found in the Ads Manager URL: https://ads.pinterest.com/advertiser/549764982399/...
Step 3: Create a Pinterest Tag
The Pinterest Tag is required even when using the Conversions API — it defines the container for your conversion events.
- In Ads Manager, go to Conversions (left sidebar) > Set up the Pinterest tag.
- Choose Conversions API as your setup method.
- Note the Tag ID displayed on the setup page.
- Under Conversion Access Token, click Generate New Token.
- Copy the Conversion Access Token immediately — you will need this for Signal configuration.
Store the Conversion Access Token securely. You can regenerate it at any time, but doing so will invalidate the previous token and require updating your Signal configuration.
Step 4: Generate an API Access Token
The API access token authenticates server-to-server requests to the Pinterest Conversions API.
- Go to developers.pinterest.com and sign in with your Pinterest business account.
- Click My apps > Create app (or select an existing app).
- Enter an app name (e.g. “Datafly Signal”) and a description.
- Once the app is created, go to the OAuth section.
- Generate a token with the
ads:writescope. This scope is required for sending conversion events. - Copy the access token — it typically starts with
pina_.
Pinterest API tokens can expire depending on how they are generated. For production use, set up token refresh via the OAuth flow or generate a long-lived token through the Pinterest developer portal. Check the token expiry in your app settings.
Configure in Signal
Now that you have your Ad Account ID, API access token, and Conversion Access Token, configure the integration in Signal.
Configuration Fields
| Field | Required | Description |
|---|---|---|
ad_account_id | Yes | Your Pinterest Ad Account ID (numeric). Found in Pinterest Ads Manager under Account Settings. |
access_token | Yes | Pinterest API access token with ads:write scope. Generated via the Pinterest developer portal. Typically starts with pina_. |
conversion_token | Yes | Conversion access token for the Pinterest Tag. Found in Ads Manager under Conversions > Conversion Access Token. Typically starts with ct_. |
Management UI Setup
- Go to Integrations > Add Integration > Pinterest Conversions API.
- Choose a variant:
- Default — standard event tracking and campaign optimisation
- Retail — e-commerce focused with checkout, add-to-cart, and product catalog events for Shopping campaigns
- Travel — search, booking, and destination events for travel-related campaigns
- Media — sign-up, lead, and content engagement events for awareness campaigns
- Enter your
ad_account_id,access_token, andconversion_token. - Select consent categories (typically
advertising). - Click Save.
Management API Setup
curl -X POST http://localhost:8084/v1/admin/integrations \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"source_id": "src_abc123",
"vendor": "pinterest",
"name": "Pinterest Conversions API",
"enabled": true,
"config": {
"ad_account_id": "549764982399",
"access_token": "pina_ABC123...",
"conversion_token": "ct_ABC123..."
},
"consent_categories": ["advertising"]
}'API Endpoint
POST https://api.pinterest.com/v5/ad_accounts/{ad_account_id}/eventsEvents are sent as a JSON array in the data field, with authentication via the Authorization: Bearer header.
Variants
Pinterest CAPI supports four configuration variants, each pre-configured with appropriate event priorities and data enrichment for different business types.
| Variant | Use Case | Priority Events |
|---|---|---|
| Default | General event tracking | All standard events |
| Retail | E-commerce / Shopping campaigns | checkout, add_to_cart, page_visit, search, view_category |
| Travel | Travel and hospitality | search, page_visit, checkout, lead, custom |
| Media | Media, publishing, subscriptions | signup, lead, page_visit, watch_video, custom |
All variants use server-side delivery, API v5, automatic PII hashing, and include IP address and User-Agent forwarding by default.
Identity Signals
Pinterest uses identity signals to match server events to Pinterest user profiles. The more signals you provide, the better your event match rate.
Automatic Signals
These are sent automatically by Signal — no configuration needed:
| Signal | Pinterest Field | Description |
|---|---|---|
epik | user_data.partner_id | Pinterest click ID. Automatically extracted from the epik URL parameter when a user clicks a Pinterest ad. This is the most important signal for click-based attribution. |
pin_unauth | user_data.click_id | Pinterest unauthenticated browser ID. Signal self-generates this as a UUID and stores it as a first-party cookie (_pin_unauth). Provides cross-session identity without login. |
client_ip_address | user_data.client_ip_address | Visitor’s IP address, forwarded from the original request. |
client_user_agent | user_data.client_user_agent | Visitor’s User-Agent string, forwarded from the original request. |
User-Provided Signals (Hashed)
When a user is identified via _df.identify() with traits, the following fields are SHA-256 hashed before sending to Pinterest:
| Signal | Hashing | Description |
|---|---|---|
em (email) | SHA-256, lowercase, trimmed | User’s email address |
ph (phone) | SHA-256, digits only, with country code | User’s phone number |
hashed_maids | SHA-256 | Mobile advertising IDs (IDFA/GAID), if available |
All PII hashing is performed server-side by the Delivery Worker before the data leaves your infrastructure. Raw PII is never sent to Pinterest.
How to Send User Data
Call _df.identify() when a user logs in, registers, or submits a form:
_df.identify("user-123", {
email: "[email protected]",
phone: "+44 7700 900123"
});Signal normalises and hashes these fields automatically before sending to Pinterest.
Event Mapping
| Datafly Event | Pinterest Event | Notes |
|---|---|---|
page (page view) | page_visit | Sent for every page view |
Product Added | add_to_cart | Includes product details in custom_data |
Order Completed / Product Purchased | checkout | Requires value, order_quantity |
Checkout Started | checkout | Initial checkout step |
Product Viewed | view_category | Includes product details |
Products Searched | search | Includes search_query in custom_data |
Signed Up | signup | User registration |
Lead Generated | lead | Lead form submission |
Product Added to Wishlist | add_to_cart | Mapped to add-to-cart as Pinterest has no wishlist event |
| Custom events | custom | Sent with custom_event_name field |
Example: Purchase Event
Datafly.js call:
_df.track("Order Completed", {
order_id: "ORD-001",
total: 129.99,
currency: "USD",
products: [
{ product_id: "SKU-A", name: "Widget", price: 49.99, quantity: 2 },
{ product_id: "SKU-B", name: "Gadget", price: 30.01, quantity: 1 }
]
});Pinterest Conversions API payload sent by Signal:
{
"data": [
{
"event_name": "checkout",
"action_source": "web",
"event_time": 1706540000,
"event_id": "evt_abc123def456",
"event_source_url": "https://example.com/checkout/confirmation",
"user_data": {
"client_ip_address": "203.0.113.50",
"client_user_agent": "Mozilla/5.0 ...",
"em": ["836f82db99121b3481011f16b49dfa5fbc714a0d1b1b9f784a1ebbbf5b39577f"],
"click_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"partner_id": "epik_abc123def456"
},
"custom_data": {
"currency": "USD",
"value": "129.99",
"order_id": "ORD-001",
"num_items": 3,
"content_ids": ["SKU-A", "SKU-B"],
"contents": [
{ "id": "SKU-A", "item_price": "49.99", "quantity": 2 },
{ "id": "SKU-B", "item_price": "30.01", "quantity": 1 }
]
}
}
]
}Example: Page Visit
Datafly.js call:
// Automatic — every page load sends a page visit event
_df.page();Pinterest Conversions API payload sent by Signal:
{
"data": [
{
"event_name": "page_visit",
"action_source": "web",
"event_time": 1706539000,
"event_id": "evt_789ghi012jkl",
"event_source_url": "https://example.com/products/widgets",
"user_data": {
"client_ip_address": "203.0.113.50",
"client_user_agent": "Mozilla/5.0 ...",
"click_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
}
]
}Action Source
The action_source field indicates where the event originated. For all browser-originated events collected by Datafly.js, this is always set to web.
Testing Your Integration
Step 1: Send Test Events
- Add the Pinterest integration in Signal with your credentials.
- Trigger events on your website (page views, add-to-cart, purchase).
- Check the Signal event debugger to confirm events are being delivered successfully.
Step 2: Verify in Pinterest Ads Manager
- In Pinterest Ads Manager, go to Conversions > Events tab.
- You should see server events arriving with an “API” source indicator.
- Events typically appear within 1-2 minutes of being sent.
- Click on individual events to inspect the payload and parameter details.
Step 3: Check Event Match Rate
- In the Conversions dashboard, review the Event Match Rate metric.
- A higher match rate means Pinterest can attribute more events to user profiles.
- If the rate is low, ensure
epikclick IDs andpin_unauthcookies are being captured, and add user identity signals via_df.identify().
Pinterest’s Event Match Rate is the equivalent of Meta’s EMQ score. Sending both epik (click ID) and pin_unauth (browser ID) alongside hashed email significantly improves match rates.
Deduplication
If you are running both Signal server-side delivery and the Pinterest Tag client-side (during a migration period), you must deduplicate events to prevent double-counting.
Signal includes a unique event_id with every event. To deduplicate:
- Pass the same
event_idto both the client-side Pinterest Tag and Datafly.js. - Pinterest will automatically deduplicate events with matching
event_nameandevent_id.
// Generate a shared event ID
const eventId = crypto.randomUUID();
// Send via Pinterest Tag (client-side)
pintrk('track', 'checkout', {
event_id: eventId,
value: 129.99,
currency: 'USD'
});
// Send via Datafly.js (server-side)
_df.track("Order Completed", {
event_id: eventId,
total: 129.99,
currency: "USD"
});Once you have validated that server-side events are arriving correctly and your match rate is healthy, you can remove the client-side Pinterest Tag entirely. This eliminates the client-side script, improves page performance, and removes the deduplication requirement.
Troubleshooting
| Problem | Solution |
|---|---|
| Events not appearing in Ads Manager | Verify all three credentials are correct: ad_account_id, access_token, and conversion_token. Check that the access token has ads:write scope. |
401 Unauthorized errors | The access token has expired or been revoked. Generate a new token in the Pinterest developer portal. |
403 Forbidden errors | The access token does not have ads:write scope, or the token’s app does not have access to the specified ad account. |
Invalid ad_account_id error | The ad account ID is incorrect or does not belong to the authenticated user. Verify the ID in Ads Manager. |
| Low Event Match Rate | Add user identity signals via _df.identify(). Ensure epik click IDs are being captured from Pinterest ad URLs and _pin_unauth cookies are being set. |
| Duplicate events in reporting | If running both client-side and server-side, ensure matching event_id values for deduplication. |
Events showing as custom | The event name may not be mapping to a standard Pinterest event. Check the event mapping table above and ensure your Datafly.js calls use the expected event names. |
conversion_token errors | The conversion token may be invalid or regenerated. Generate a new token in Ads Manager under Conversions > Conversion Access Token. |
Rate Limits
| Limit | Value |
|---|---|
| Events per API call | 1,000 (batched) |
| Default rate limit (Signal) | 100 requests/second |
| Default burst limit (Signal) | 200 requests/second |
Pinterest allows up to 1,000 events per batch request. Signal batches events automatically when throughput is high to maximise efficiency. For most deployments, the default rate limit settings are sufficient.