> ## Documentation Index
> Fetch the complete documentation index at: https://docs.appdna.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Pinterest Ads

> Connect a Pinterest Ads account to manage campaigns, ad groups, ads, and creative pins, upload media, pull analytics, and run multi-ad-group creative experiments from the dashboard.

## 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, with OAuth credentials configured by your administrator.

## OAuth scopes

The connection requests the following scopes:

```
ads:read
ads:write
```

`ads:read` covers list and analytics calls (including walking the user's accessible ad accounts); `ads:write` covers all create / update / delete operations on campaigns, ad groups, ads, and pins.

## 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

| Operation                                 | API endpoint                                                                   |
| ----------------------------------------- | ------------------------------------------------------------------------------ |
| List ad accounts the user can access      | `GET /ad_accounts`                                                             |
| Create / list campaigns                   | `POST` / `GET /ad_accounts/{id}/campaigns`                                     |
| Update / pause / resume / delete campaign | `PATCH` / `DELETE /ad_accounts/{id}/campaigns/{id}`                            |
| Create / update ad groups                 | `POST` / `PATCH /ad_accounts/{id}/ad_groups[/{id}]`                            |
| Create / update ads                       | `POST` / `PATCH /ad_accounts/{id}/ads[/{id}]`                                  |
| Register video media                      | `POST /ad_accounts/{id}/media`                                                 |
| Create creative pin                       | `POST /pins`                                                                   |
| Pull analytics                            | `GET /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 ad account using a sliding-window rate limiter, and rate limits apply. If the platform reports HTTP 429, the request is automatically retried with exponential backoff.

If the rate limiter is unavailable, it fails closed and the request is reported as a quota error to the platform's automation — 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.
