Skip to main content

Overview

Connecting Pinterest Ads lets the dashboard:
  • Create, update, pause, resume, and delete campaigns and ad groups.
  • Create creative pins (image, video, carousel, idea-pin) and upload video media that is referenced from a pin.
  • Create and manage ads that reference a pin plus an ad group.
  • Pull spend, impressions, click-throughs, and conversion analytics.
  • Run creative experiments by rotating multiple ad groups under one campaign.
The integration uses the Pinterest Marketing API v5 with OAuth 2.0 authentication and refresh tokens.

Prerequisites

Before connecting, make sure you have:
  1. An active Pinterest Business account with at least one ad account.
  2. A user role on the ad account that allows campaign management.
  3. An OAuth 2.0 application configured for the dashboard’s redirect URI. The client_id and client_secret are set on the platform side as PINTEREST_ADS_CLIENT_ID and PINTEREST_ADS_CLIENT_SECRET.

OAuth scopes

The connection requests the following scopes:
ads:read
ads:write
user_accounts:read
ads:read covers list and analytics calls; ads:write covers all create / update / delete operations on campaigns, ad groups, ads, and pins. user_accounts:read is needed by the connect probe to walk the user’s accessible ad accounts.

Connect

  1. Open the Paid UA → Integrations page in the dashboard.
  2. Click Connect on the Pinterest Ads tile.
  3. Sign in with the Pinterest Business user that has access to your ad accounts.
  4. Approve the requested scopes.
  5. After redirect, the dashboard exchanges the auth code for tokens and probes /ad_accounts to confirm access and capture the ad account ids.
Access tokens are rotated automatically before expiry using the refresh token.

What happens behind the scenes

OperationAPI endpoint
List ad accounts the user can accessGET /ad_accounts
Create / list campaignsPOST / GET /ad_accounts/{id}/campaigns
Update / pause / resume / delete campaignPATCH / DELETE /ad_accounts/{id}/campaigns/{id}
Create / update ad groupsPOST / PATCH /ad_accounts/{id}/ad_groups[/{id}]
Create / update adsPOST / PATCH /ad_accounts/{id}/ads[/{id}]
Register video mediaPOST /ad_accounts/{id}/media
Create creative pinPOST /pins
Pull analyticsGET /ad_accounts/{id}/analytics?granularity=DAY&columns=...&campaign_ids=...
Update operations use HTTP PATCH (not POST or PUT). Pause / resume operations send { status: 'PAUSED' | 'ACTIVE' }. Every write request carries an Idempotency-Key HTTP header so retries do not produce duplicate resources, even if the platform connection drops mid-request.

Creatives (pins)

Pinterest’s creative is a Pin. The integration accepts the standard creative DTO (image, video, carousel, idea-pin) and translates it into the Pinterest pin shape:
  • Image pins carry media_source: { media_type: 'image', url: ... }.
  • Video pins require uploading the video first via /ad_accounts/{id}/media to get a media_id, then the pin references it.
  • Idea pins carry multiple images / video pages.
The CTA text translates to Pinterest’s cta_type enum (e.g. INSTALL_NOW, SIGN_UP, SHOP_NOW).

Budget conversion

Pinterest budgets and spend caps are stored in micro-currency (1 USD = 1,000,000 micros). The dashboard sends USD values in its DTOs and converts to micros (Math.round(amount_usd * 1_000_000)) before the request lands.

Rate limiting

Requests are throttled per (client_id, ad_account_id) using a sliding window built on Redis. The default budget is 1000 requests per hour per app. If the platform reports HTTP 429, the request is automatically retried with exponential backoff. If Redis is unavailable, the rate limiter fails closed and the request is reported as a quota error to the autonomous-growth runner — preventing accidental over-quota fan-out under outage.

Reporting

Analytics are pulled hourly (or on demand) from /ad_accounts/{id}/analytics. Default columns include SPEND_IN_DOLLAR, IMPRESSION_1, CLICKTHROUGH_1, and CONVERSION_1. Spend is reported in USD natively; non-USD ad accounts report local-currency spend in a separate field that the dashboard converts to USD on ingestion.

Experiments (multi-ad-group rotation)

The dashboard maps experiment variants onto multiple ad groups under a single campaign, with each variant carrying its own targeting and creative pin. The control variant ships active; treatments ship paused until the experiment runner toggles them. Per-variant performance is read back from the analytics endpoint with ad_group_ids=*. Pinterest also exposes a native ad-account split-test endpoint, but the dashboard prefers the uniform multi-ad-group model so experiments behave consistently across all paid-UA platforms.

Disconnect

Click Disconnect on the integration tile. The OAuth refresh token is removed from the dashboard. To fully revoke access, also remove the third-party app authorisation from your Pinterest Business connected-apps list.

Troubleshooting

  • “Pinterest Ads /ad_accounts returned 401” — the OAuth token has been revoked or has expired without a valid refresh token. Re-connect the integration.
  • “Pinterest Ads create_campaign: 429 — …” — your app’s hourly API quota was breached. The dashboard backs off automatically; if the error persists, lower campaign-mutation frequency.
  • “webhooks not supported on pinterest_ads” — Marketing API v5 does not expose webhooks. State changes (ad disapproved, daily cap hit) are detected via the hourly metrics-sync job.
  • Video pin creation fails with media_id not found — make sure the media upload (POST /ad_accounts/{id}/media) completed before referencing the returned media_id in the pin body.
  • Update returns 405 Method Not Allowed — Pinterest’s update verb is PATCH, not POST or PUT. The integration handles this automatically; if you see this error, please report it.