Pinterest Ads
Authorise on the platform, nothing to type. Two warnings first: the permission screen asks for a lot more than ads, and daily performance only goes back 90 days.
Start
Connectauthorise on the platform
Under Sources · Connect new source · Pinterest Ads, the card opens the authorisation with the permission list. There is no form. The window only closes after caOS has fetched the accounts.
Then tick the workspace accounts. Pinterest supplies the identifier, the name and the currency.
Warn them the screen asks for more than ads. caOS requests, in one go: read and write on ads, on boards and on pins, plus account read. This is not decorative excess: without the boards and pins permissions Pinterest later refuses to renew access, and the connection stops. The write scopes are what let caOS products pause a campaign and publish a pin. Whoever authorises has to accept the whole list.
Allow pop-ups in the browser before you start.
Your credential, and what happens to it
Connect once and you are connected. The credential renews itself, indefinitely. You do not need a date in the calendar and you do not need to reconnect periodically.
There is only one way the connection drops: someone revokes access on the platform side (password changed, person removed from the account, authorisation cancelled). The account then shows up under Lost connections and reconnecting fixes it, keeping the tags it already had.
Your credential is encrypted end to end. It is encrypted before it is stored, and the key does not live in the database, so even database access does not reveal it. Nobody at caOS, and not you either, can read the credential back after it is saved. The screen only shows that it exists and is valid.
Only the metrics you asked for are read. caOS does not write to your ad account in order to extract data, and it stores no personal data about who saw the ad. Processing follows Brazilian data protection law (LGPD), and deletion is yours: revoking the connection erases the stored credential.
Reference
Metrics and dimensionswhat each field means
Pinterest names fields in capitals, and offers variants of the same metric with suffix 1 and 2 (different attribution windows). Stay within one family across the whole report.
Core metrics10 of 104
| API field | What it is | Where it shows up |
|---|---|---|
| SPEND_IN_DOLLAR | Spend. Despite the name, it arrives in the account currency. | Spend in Pacer. |
| IMPRESSION_1 | How many times the ad was shown. | Impressions. |
| CLICKTHROUGH_1 | Clicks through to the destination. | Clicks. |
| TOTAL_IMPRESSION_USER | Distinct people who saw the ad. | Reach. Do not sum it across days, accounts or campaigns. |
| ENGAGEMENT_1 | Paid engagement, analogous to Meta and TikTok. | Engagement. |
| OUTBOUND_CLICK_1 | Clicks leaving Pinterest for the site. | Smaller than total clicks, and usually what the client actually wants. |
| TOTAL_VIDEO_MRC_VIEWS | A valid video view, on the industry standard. | This is the video metric that compares across platforms. |
| TOTAL_VIDEO_3SEC_VIEWS | Watched 3 seconds. | Average watch time is available too. |
| TOTAL_VIDEO_P100_COMPLETE | Watched to the end. Also 25, 50, 75 and 95. | Use it for a retention curve. |
| CPM_IN_DOLLAR | Cost per thousand impressions. | CPM. Pacer recomputes it from the sums. |
Dimensions3
| API field | What it is | Where it shows up |
|---|---|---|
| DATE | The day of the row. | Performance always comes daily. |
| AD_ID | The ad. | The performance table is one row per ad per day. |
| CAMPAIGN_ID | The campaign. | There is no per-campaign performance table: the campaign id comes inside the analytics table. |
Report parameters
The fields above say what comes back. These parameters say how: they decide the grain of the row, the period it covers and what counts as a conversion. Two reports from the same account showing different numbers almost always differ here.
| Parameter | What it changes | Values |
|---|---|---|
| granularity | The aggregation of each row. | caOS asks for DAY. The API also accepts hour, week, month and the whole period. |
| columns | The metrics requested. | You pick from the list. Asking for a metric the account does not generate returns a zeroed column, not an error. |
| 90 day window | A hard platform limit. | Daily performance does not exist before that. Campaigns, ads and pins have no such restriction. |
| suffix 1 and 2 | Which attribution window the metric uses. | IMPRESSION_1 and IMPRESSION_2 are the same metric on different windows. Stay in one family across the whole report. |
Everything you can pull
The tables above are what most reports use, but you are not stuck with them. The full Pinterest catalogue has 7 tables and 286 fields, and you choose what goes in when you build the source. What is marked used by default is what the example source uses; the rest is available just the same.
The list below comes from the Xtractor catalogue itself, the same one the new source screen reads. If a field is here, the screen offers it.
ad_analytics used by default104 fields
AD_ID, DATE, AD_ACCOUNT_ID, AD_GROUP_ENTITY_STATUS, AD_GROUP_ID, CAMPAIGN_DAILY_SPEND_CAP, CAMPAIGN_ENTITY_STATUS, CAMPAIGN_ID, CAMPAIGN_LIFETIME_SPEND_CAP, CHECKOUT_ROAS, CLICKTHROUGH_1, CLICKTHROUGH_1_GROSS, CLICKTHROUGH_2, CPC_IN_MICRO_DOLLAR, CPM_IN_DOLLAR, CPM_IN_MICRO_DOLLAR, CTR, CTR_2, ECPCV_IN_DOLLAR, ECPCV_P95_IN_DOLLAR, ECPC_IN_DOLLAR, ECPC_IN_MICRO_DOLLAR, ECPE_IN_DOLLAR, ECPM_IN_MICRO_DOLLAR, ECPV_IN_DOLLAR, ECTR, EENGAGEMENT_RATE, ENGAGEMENT_1, ENGAGEMENT_2, ENGAGEMENT_RATE, IDEA_PIN_PRODUCT_TAG_VISIT_1, IDEA_PIN_PRODUCT_TAG_VISIT_2, IMPRESSION_1, IMPRESSION_1_GROSS, IMPRESSION_2, INAPP_CHECKOUT_COST_PER_ACTION, OUTBOUND_CLICK_1, OUTBOUND_CLICK_2, PAGE_VISIT_COST_PER_ACTION, PAGE_VISIT_ROAS, PAID_IMPRESSION, PIN_ID, REPIN_1, REPIN_2, REPIN_RATE, SPEND_IN_DOLLAR, SPEND_IN_MICRO_DOLLAR, TOTAL_CHECKOUT, TOTAL_CHECKOUT_VALUE_IN_MICRO_DOLLAR, TOTAL_CLICKTHROUGH, TOTAL_CLICK_CHECKOUT, TOTAL_CLICK_CHECKOUT_VALUE_IN_MICRO_DOLLAR, TOTAL_CLICK_LEAD, TOTAL_CLICK_SIGNUP, TOTAL_CLICK_SIGNUP_VALUE_IN_MICRO_DOLLAR, TOTAL_CONVERSIONS, TOTAL_CUSTOM, TOTAL_ENGAGEMENT, TOTAL_ENGAGEMENT_CHECKOUT, TOTAL_ENGAGEMENT_CHECKOUT_VALUE_IN_MICRO_DOLLAR, TOTAL_ENGAGEMENT_LEAD, TOTAL_ENGAGEMENT_SIGNUP, TOTAL_ENGAGEMENT_SIGNUP_VALUE_IN_MICRO_DOLLAR, TOTAL_IDEA_PIN_PRODUCT_TAG_VISIT, TOTAL_IMPRESSION_FREQUENCY, TOTAL_IMPRESSION_USER, TOTAL_LEAD, TOTAL_PAGE_VISIT, TOTAL_REPIN_RATE, TOTAL_SIGNUP, TOTAL_SIGNUP_VALUE_IN_MICRO_DOLLAR, TOTAL_VIDEO_3SEC_VIEWS, TOTAL_VIDEO_AVG_WATCHTIME_IN_SECOND, TOTAL_VIDEO_MRC_VIEWS, TOTAL_VIDEO_P0_COMBINED, TOTAL_VIDEO_P100_COMPLETE, TOTAL_VIDEO_P25_COMBINED, TOTAL_VIDEO_P50_COMBINED, TOTAL_VIDEO_P75_COMBINED, TOTAL_VIDEO_P95_COMBINED, TOTAL_VIEW_CHECKOUT, TOTAL_VIEW_CHECKOUT_VALUE_IN_MICRO_DOLLAR, TOTAL_VIEW_LEAD, TOTAL_VIEW_SIGNUP, TOTAL_VIEW_SIGNUP_VALUE_IN_MICRO_DOLLAR, TOTAL_WEB_CHECKOUT, TOTAL_WEB_CHECKOUT_VALUE_IN_MICRO_DOLLAR, TOTAL_WEB_CLICK_CHECKOUT, TOTAL_WEB_CLICK_CHECKOUT_VALUE_IN_MICRO_DOLLAR, TOTAL_WEB_ENGAGEMENT_CHECKOUT, TOTAL_WEB_ENGAGEMENT_CHECKOUT_VALUE_IN_MICRO_DOLLAR, TOTAL_WEB_VIEW_CHECKOUT, TOTAL_WEB_VIEW_CHECKOUT_VALUE_IN_MICRO_DOLLAR, VIDEO_3SEC_VIEWS_2, VIDEO_LENGTH, VIDEO_MRC_VIEWS_2, VIDEO_P0_COMBINED_2, VIDEO_P100_COMPLETE_2, VIDEO_P25_COMBINED_2, VIDEO_P50_COMBINED_2, VIDEO_P75_COMBINED_2, VIDEO_P95_COMBINED_2, WEB_CHECKOUT_COST_PER_ACTION, WEB_CHECKOUT_ROAS
account_analytics100 fields
AD_ACCOUNT_ID, DATE, AD_GROUP_ENTITY_STATUS, CAMPAIGN_DAILY_SPEND_CAP, CAMPAIGN_ENTITY_STATUS, CAMPAIGN_ID, CAMPAIGN_LIFETIME_SPEND_CAP, CAMPAIGN_NAME, CHECKOUT_ROAS, CLICKTHROUGH_1, CLICKTHROUGH_1_GROSS, CLICKTHROUGH_2, CPC_IN_MICRO_DOLLAR, CPM_IN_DOLLAR, CPM_IN_MICRO_DOLLAR, CTR, CTR_2, ECPCV_IN_DOLLAR, ECPCV_P95_IN_DOLLAR, ECPC_IN_DOLLAR, ECPC_IN_MICRO_DOLLAR, ECPE_IN_DOLLAR, ECPM_IN_MICRO_DOLLAR, ECPV_IN_DOLLAR, ECTR, EENGAGEMENT_RATE, ENGAGEMENT_1, ENGAGEMENT_2, ENGAGEMENT_RATE, IDEA_PIN_PRODUCT_TAG_VISIT_1, IDEA_PIN_PRODUCT_TAG_VISIT_2, IMPRESSION_1, IMPRESSION_1_GROSS, IMPRESSION_2, INAPP_CHECKOUT_COST_PER_ACTION, OUTBOUND_CLICK_1, OUTBOUND_CLICK_2, PAGE_VISIT_COST_PER_ACTION, PAGE_VISIT_ROAS, PAID_IMPRESSION, PIN_ID, REPIN_1, REPIN_2, REPIN_RATE, SPEND_IN_DOLLAR, SPEND_IN_MICRO_DOLLAR, TOTAL_CHECKOUT, TOTAL_CHECKOUT_VALUE_IN_MICRO_DOLLAR, TOTAL_CLICKTHROUGH, TOTAL_CLICK_CHECKOUT, TOTAL_CLICK_CHECKOUT_VALUE_IN_MICRO_DOLLAR, TOTAL_CLICK_SIGNUP, TOTAL_CLICK_SIGNUP_VALUE_IN_MICRO_DOLLAR, TOTAL_CONVERSIONS, TOTAL_CUSTOM, TOTAL_ENGAGEMENT, TOTAL_ENGAGEMENT_CHECKOUT, TOTAL_ENGAGEMENT_CHECKOUT_VALUE_IN_MICRO_DOLLAR, TOTAL_ENGAGEMENT_SIGNUP, TOTAL_ENGAGEMENT_SIGNUP_VALUE_IN_MICRO_DOLLAR, TOTAL_IDEA_PIN_PRODUCT_TAG_VISIT, TOTAL_IMPRESSION_FREQUENCY, TOTAL_IMPRESSION_USER, TOTAL_LEAD, TOTAL_PAGE_VISIT, TOTAL_REPIN_RATE, TOTAL_SIGNUP, TOTAL_SIGNUP_VALUE_IN_MICRO_DOLLAR, TOTAL_VIDEO_3SEC_VIEWS, TOTAL_VIDEO_AVG_WATCHTIME_IN_SECOND, TOTAL_VIDEO_MRC_VIEWS, TOTAL_VIDEO_P0_COMBINED, TOTAL_VIDEO_P100_COMPLETE, TOTAL_VIDEO_P25_COMBINED, TOTAL_VIDEO_P50_COMBINED, TOTAL_VIDEO_P75_COMBINED, TOTAL_VIDEO_P95_COMBINED, TOTAL_VIEW_CHECKOUT, TOTAL_VIEW_CHECKOUT_VALUE_IN_MICRO_DOLLAR, TOTAL_VIEW_SIGNUP, TOTAL_VIEW_SIGNUP_VALUE_IN_MICRO_DOLLAR, TOTAL_WEB_CHECKOUT, TOTAL_WEB_CHECKOUT_VALUE_IN_MICRO_DOLLAR, TOTAL_WEB_CLICK_CHECKOUT, TOTAL_WEB_CLICK_CHECKOUT_VALUE_IN_MICRO_DOLLAR, TOTAL_WEB_ENGAGEMENT_CHECKOUT, TOTAL_WEB_ENGAGEMENT_CHECKOUT_VALUE_IN_MICRO_DOLLAR, TOTAL_WEB_VIEW_CHECKOUT, TOTAL_WEB_VIEW_CHECKOUT_VALUE_IN_MICRO_DOLLAR, VIDEO_3SEC_VIEWS_2, VIDEO_LENGTH, VIDEO_MRC_VIEWS_2, VIDEO_P0_COMBINED_2, VIDEO_P100_COMPLETE_2, VIDEO_P25_COMBINED_2, VIDEO_P50_COMBINED_2, VIDEO_P75_COMBINED_2, VIDEO_P95_COMBINED_2, WEB_CHECKOUT_COST_PER_ACTION, WEB_CHECKOUT_ROAS
ads27 fields
ad_group_id, android_deep_link, carousel_android_deep_links, carousel_destination_urls, carousel_ios_deep_links, click_tracking_url, creative_type, destination_url, ios_deep_link, is_pin_deleted, is_removable, name, pin_id, status, tracking_urls, view_tracking_url, ad_account_id, campaign_id, collection_items_destination_url_template, created_time, id, rejected_reasons, rejection_labels, review_status, type, updated_time, summary_status
ad_groups23 fields
name, status, budget_in_micro_currency, bid_in_micro_currency, budget_type, start_time, end_time, targeting_spec, lifetime_frequency_cap, tracking_urls, auto_targeting_enabled, placement_group, pacing_delivery_type, conversion_learning_mode_type, summary_status, feed_profile_id, campaign_id, billable_event, id, type, ad_account_id, created_time, updated_time
pins15 fields
ad_id, pin_id, ad_account_id, media_type, image_url, all_image_urls, cover_image_url, video_url, title, description, alt_text, link, pin_url, board_id, created_at
campaigns12 fields
id, ad_account_id, name, status, lifetime_spend_cap, daily_spend_cap, order_line_id, tracking_urls, objective_type, created_time, updated_time, type
ad_accounts5 fields
id, name, owner, country, currency
Two money scales on the same platform. Spend arrives in the account currency. Budget caps and ad set budgets and bids, on the other hand, arrive in micros: divide by 1,000,000.
Output
Where the data landsa spreadsheet and a warehouse are different jobs
Google Sheets
For building a report by hand
Tick spend, impressions, clicks and the campaign name. If the client is paying for clicks to the site, use the outbound click field, which is smaller.
Since history only goes back 90 days, start extracting as early as you can: the spreadsheet is what will keep what the platform stops offering.
BigQuery
For modelling on top
7 tables: two of performance and five of structure.
Performance, always daily: one row per ad per day, and one row per account per day. Structure: campaigns, ad groups, ads, pins and accounts.
The pins table carries the creative (image, cover, video, title, description and link), but it is one row per ad, not per pin.
Trust
Data freshnessand the 90 day limit
Ad platforms rewrite the past. A conversion attributed days later, revised spend, a corrected row: Tuesday's number changes on Thursday. If the extraction only ever brought the newest day, your spreadsheet would freeze at the first value and drift away from the platform with nobody noticing.
So caOS re-reads the last 30 days on every sync and rewrites what changed. Older history stays in the destination and is not touched. In practice: what sits in your spreadsheet or your warehouse is what the platform says today, not what it said on the day of the first load.
Daily performance only goes back 90 days. Spend, impressions and clicks do not exist before that. Campaigns, ads and pins have no such restriction. The practical consequence: there is no deep history on Pinterest. History starts counting the day the source begins running, so connecting early is the only way to have the full year.
Detail
Good to knowwhat usually raises questions
An account with impressions and zero spend is normal. Accounts that do not run paid media show up in the list and bring impressions without spend. Before raising a ticket about zero spend, check whether the account runs paid media at all.
The name is not part of the key. Campaigns, ad groups and ads are identified by id, and renaming on Pinterest does not create a new entity. Anyone joining the campaigns table onto performance has to guarantee one row per id before joining: otherwise the same id with two names duplicates the metric, and the inflation goes unnoticed because nothing errors.
Pinterest does have reach, unlike Kwai and Google. And like all reach, it does not add up.
Support
When it failsthe message and what to do
I click and nothing happens. The pop-up is blocked. caOS waits ten minutes in silence and gives up without a message. Allow pop-ups and try again.
“Invalid state.” The link expired (it is valid for 10 minutes) or was already used. Start again from Connect new source.
Connected, but there is no account to choose. The symptom is 1 active connection and 0 accounts, and on the new source screen the card still shows a padlock, because zero accounts counts the same as no connection. Confirm that login can see an ad account.
“No Pinterest Ads account connected”, when creating the source. If the accounts found notice appears just below, the authorisation worked and all that is missing is ticking them.
A “needs reauthorisation” badge. Someone revoked access on Pinterest's side. Redo the authorisation: the accounts already chosen stay.