Skip to main content
RapidDev - Software Development Agency
v0-integrationsNext.js API Route

How to Integrate Pinterest Ads with V0

Connect Pinterest Ads to your V0-generated Next.js app by creating a server-side API route that calls the Pinterest Ads API using an OAuth 2.0 access token. Store your Pinterest app credentials in Vercel environment variables, then fetch campaign performance metrics — impressions, clicks, spend, and conversions — to display in a custom visual analytics dashboard built with V0.

What you'll learn

  • How to authenticate with the Pinterest Ads API using OAuth 2.0 in a Next.js route handler
  • How to fetch campaign, ad group, and ad performance metrics from Pinterest Ads
  • How to build a visual ad analytics dashboard in V0 displaying impressions, clicks, and spend
  • How to store Pinterest API credentials securely in Vercel environment variables
  • How to filter analytics by date range and campaign in your dashboard
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate11 min read45 minutesMarketingApril 2026RapidDev Engineering Team
TL;DR

Connect Pinterest Ads to your V0-generated Next.js app by creating a server-side API route that calls the Pinterest Ads API using an OAuth 2.0 access token. Store your Pinterest app credentials in Vercel environment variables, then fetch campaign performance metrics — impressions, clicks, spend, and conversions — to display in a custom visual analytics dashboard built with V0.

Visualizing Pinterest Ads Performance in a V0 Dashboard

Pinterest is a unique advertising platform where users actively seek inspiration and shopping ideas — making it particularly effective for e-commerce, home decor, fashion, food, and lifestyle brands. Pinterest Ads analytics tell a different story than other platforms: visually-driven metrics like close-up rates and save rates matter alongside standard click-through rates. Building a custom analytics dashboard with V0 gives you the flexibility to surface the metrics that matter most for Pinterest's visual format.

The Pinterest Ads API v5 is the current version, providing access to ad accounts, campaigns, ad groups, ads, and analytics. Authentication uses OAuth 2.0 — either a long-lived access token for server-side integrations or a full OAuth flow for multi-account tools. For a single-account analytics dashboard, using a long-lived token generated in the Pinterest Developer portal is the simplest approach.

V0 excels at generating dashboard layouts with data tables, charts, and metric cards. For Pinterest specifically, the visual nature of the platform lends itself to showing Pin thumbnails alongside performance data — a design choice that makes your analytics dashboard feel native to Pinterest. This tutorial walks through fetching campaign analytics, calculating key metrics, and displaying them in a V0-generated dashboard.

Integration method

Next.js API Route

Pinterest Ads API uses OAuth 2.0 for authentication. Integration happens through a Next.js API route that exchanges your access token for Pinterest API calls to fetch ad account data, campaign metrics, and performance analytics. The access token and app credentials are stored in Vercel environment variables, and all API calls are made server-side to keep credentials out of the browser.

Prerequisites

  • A V0 account at v0.dev with a Next.js project created
  • A Pinterest Business account with active ad campaigns
  • A Pinterest Developer app registered at developers.pinterest.com
  • A Pinterest Ads API access token (generated in the Developer portal or via OAuth flow)
  • Your Pinterest ad account ID from the Ads Manager
  • A Vercel account connected to your V0 project for deployment

Step-by-step guide

1

Generate the Ads Analytics Dashboard UI with V0

Open V0 and describe the Pinterest Ads analytics dashboard you want to build. Pinterest's visual format means a good dashboard design should incorporate some visual elements alongside the numbers — Pin thumbnails, color-coded performance indicators, and chart visualizations suited to campaign data. Ask V0 to generate a dashboard with metric summary cards at the top showing total spend, impressions, clicks, and conversions, followed by a sortable campaign data table below. Include a date range picker so users can filter by last 7 days, last 30 days, or a custom range. Ask for a spend trend line chart using recharts (V0 handles this library well). Request status badge components for campaign status (active, paused, archived) with color coding. Make sure V0 generates proper loading skeletons since API calls have latency, and request empty state components for when no campaigns are found. Once the UI is generated, review it in the V0 preview and refine any layout issues before moving on to the API routes.

V0 Prompt

Build a Pinterest Ads analytics dashboard with Pinterest's red (#E60023) as the accent color. Include: 4 metric cards at the top (Total Spend, Impressions, Clicks, CTR), a date range selector, a campaign performance table with columns for Campaign Name, Status, Budget, Spend, Impressions, Clicks, and CTR, and a spend-over-time line chart below. Add sorting on all table columns. Show skeleton rows while loading data from /api/pinterest-ads/campaigns.

Paste this in V0 chat

Pro tip: Ask V0 to use Pinterest's brand red (#E60023) as the accent color for CTAs and highlights — it makes the dashboard feel appropriately on-brand for Pinterest analytics.

Expected result: A Pinterest-styled analytics dashboard with metric cards, a data table, and chart area renders in the V0 preview.

2

Get a Pinterest Ads API Access Token

Before writing any code, you need an access token for the Pinterest Ads API. There are two ways to obtain one. The first and simplest method for a single-account dashboard is to generate a long-lived token directly in the Pinterest Developer portal: go to developers.pinterest.com, log in, navigate to My Apps, create a new app, then use the app's credentials to generate an access token via the OAuth token endpoint. The token has the ads:read scope for fetching analytics data. The second method is implementing a full OAuth 2.0 authorization code flow for multi-account tools — this is more complex and requires redirect URI handling. For most analytics dashboards managing a single Pinterest Ads account, the long-lived token approach is sufficient. In the Pinterest Developer portal, go to your app settings, click 'Generate access token', select the ads:read scope, and copy the token that is generated. This token is tied to your Pinterest account and gives read access to all ad accounts associated with it. Store it securely — treat it like an API key.

Pro tip: Pinterest access tokens expire after a year by default. Plan for token refresh by implementing the OAuth refresh token flow if you need long-term unattended access to the API.

Expected result: You have a Pinterest Ads API access token with the ads:read scope ready to add to Vercel.

3

Create the Pinterest Ads API Routes

Create a Next.js App Router route handler at app/api/pinterest-ads/campaigns/route.ts that calls the Pinterest Ads API v5 to fetch campaign performance data. The Pinterest Ads API base URL is https://api.pinterest.com/v5. To fetch campaigns, call GET /ad_accounts/{ad_account_id}/campaigns. To fetch analytics for those campaigns, call GET /ad_accounts/{ad_account_id}/campaigns/analytics with date range parameters in YYYY-MM-DD format. The analytics endpoint returns metrics per campaign per day. You will need your Pinterest ad account ID — find it in Ads Manager (the number in the URL when you are viewing your ad account). Your route handler should accept query parameters for startDate and endDate and pass them to the Pinterest analytics endpoint. Combine the campaign list (for names and budgets) with the analytics data (for performance metrics) by joining on campaignId. Return a unified array of campaign objects with both static fields and performance metrics to your frontend. Always authenticate using the Bearer token: set the Authorization header to Bearer ${process.env.PINTEREST_ACCESS_TOKEN}.

app/api/pinterest-ads/campaigns/route.ts
1// app/api/pinterest-ads/campaigns/route.ts
2import { NextRequest, NextResponse } from 'next/server';
3
4const PINTEREST_API = 'https://api.pinterest.com/v5';
5const AD_ACCOUNT_ID = process.env.PINTEREST_AD_ACCOUNT_ID;
6
7function getHeaders() {
8 return {
9 'Authorization': `Bearer ${process.env.PINTEREST_ACCESS_TOKEN}`,
10 'Content-Type': 'application/json',
11 };
12}
13
14export async function GET(request: NextRequest) {
15 const { searchParams } = new URL(request.url);
16 const startDate = searchParams.get('startDate') || getDefaultStartDate();
17 const endDate = searchParams.get('endDate') || getTodayDate();
18
19 try {
20 // Fetch campaigns list
21 const campaignsResponse = await fetch(
22 `${PINTEREST_API}/ad_accounts/${AD_ACCOUNT_ID}/campaigns?page_size=25`,
23 { headers: getHeaders(), next: { revalidate: 300 } }
24 );
25
26 if (!campaignsResponse.ok) {
27 return NextResponse.json(
28 { error: `Pinterest API error: ${campaignsResponse.status}` },
29 { status: campaignsResponse.status }
30 );
31 }
32
33 const campaignsData = await campaignsResponse.json();
34
35 // Fetch analytics for the date range
36 const analyticsUrl = new URL(
37 `${PINTEREST_API}/ad_accounts/${AD_ACCOUNT_ID}/campaigns/analytics`
38 );
39 analyticsUrl.searchParams.set('start_date', startDate);
40 analyticsUrl.searchParams.set('end_date', endDate);
41 analyticsUrl.searchParams.set('columns', 'SPEND_IN_DOLLAR,IMPRESSION_1,CLICK_TYPE_URL_CLICK,TOTAL_CONVERSIONS');
42 analyticsUrl.searchParams.set('granularity', 'TOTAL');
43
44 const analyticsResponse = await fetch(analyticsUrl.toString(), {
45 headers: getHeaders(),
46 });
47 const analyticsData = await analyticsResponse.json();
48
49 // Merge campaigns with analytics
50 const analyticsMap = new Map(
51 (analyticsData || []).map((a: Record<string, unknown>) => [a.campaign_id, a])
52 );
53
54 const campaigns = (campaignsData.items || []).map((c: Record<string, unknown>) => {
55 const analytics = analyticsMap.get(c.id) as Record<string, unknown> | undefined;
56 return {
57 id: c.id,
58 name: c.name,
59 status: c.status,
60 budget: c.daily_budget,
61 spend: analytics?.SPEND_IN_DOLLAR || 0,
62 impressions: analytics?.IMPRESSION_1 || 0,
63 clicks: analytics?.CLICK_TYPE_URL_CLICK || 0,
64 conversions: analytics?.TOTAL_CONVERSIONS || 0,
65 ctr: analytics?.IMPRESSION_1
66 ? ((analytics.CLICK_TYPE_URL_CLICK as number) / (analytics.IMPRESSION_1 as number) * 100).toFixed(2)
67 : '0.00',
68 };
69 });
70
71 return NextResponse.json({ campaigns });
72 } catch (error) {
73 console.error('Pinterest Ads error:', error);
74 return NextResponse.json({ error: 'Failed to fetch campaigns' }, { status: 500 });
75 }
76}
77
78function getDefaultStartDate() {
79 const d = new Date();
80 d.setDate(d.getDate() - 30);
81 return d.toISOString().split('T')[0];
82}
83
84function getTodayDate() {
85 return new Date().toISOString().split('T')[0];
86}

Pro tip: The Pinterest analytics endpoint requires at least one column in the 'columns' parameter. Start with SPEND_IN_DOLLAR, IMPRESSION_1, and CLICK_TYPE_URL_CLICK as the core metrics.

Expected result: Calling /api/pinterest-ads/campaigns returns a JSON array of campaign objects with spend, impressions, clicks, and CTR for the date range.

4

Add Environment Variables in Vercel

In the Vercel Dashboard, navigate to your project and click Settings → Environment Variables. Add the following variables. PINTEREST_ACCESS_TOKEN: the long-lived OAuth access token generated from the Pinterest Developer portal. PINTEREST_AD_ACCOUNT_ID: your Pinterest ad account ID — a numeric string found in the URL when viewing your Ads Manager account (e.g., if the URL is ads.pinterest.com/advertiser/123456789/, your account ID is 123456789). Neither of these variables should have the NEXT_PUBLIC_ prefix since they are used only in server-side route handlers and must never appear in browser-accessible JavaScript. Set these variables for all environment scopes: Production, Preview, and Development. For Development, you can use the same credentials since there is no separate sandbox environment for Pinterest Ads (you will be reading real campaign data). After adding the variables, redeploy your Vercel project. Verify the integration is working by navigating to /api/pinterest-ads/campaigns in your browser — you should see real campaign data returned.

Pro tip: Pinterest's access token can be verified by calling the Pinterest API test endpoint: GET https://api.pinterest.com/v5/user_account — it should return your Pinterest user information if the token is valid.

Expected result: PINTEREST_ACCESS_TOKEN and PINTEREST_AD_ACCOUNT_ID are configured in Vercel environment variables and the API route returns live campaign data.

Common use cases

Campaign Performance Dashboard

A D2C e-commerce brand uses V0 to build a Pinterest Ads analytics dashboard showing campaign spend, ROAS, and top-performing Pins with thumbnail previews, updated daily.

V0 Prompt

Create a Pinterest Ads dashboard with a date range picker and campaign filter dropdown at the top. Show metric cards for total spend, total impressions, average CTR, and total conversions. Below, a campaign table with campaign name, status badge, budget, spend, impressions, clicks, and CTR. Sort by spend descending by default. Fetch from /api/pinterest-ads/campaigns.

Copy this prompt to try it in V0

Pin Performance Analysis

A content creator analyzes which of their promoted Pins perform best. The V0 dashboard shows Pin thumbnails alongside engagement metrics to identify winning creatives for budget allocation.

V0 Prompt

Build a Pin performance page with a masonry grid of promoted Pin cards. Each card shows the Pin thumbnail image, Pin title, ad group name, and metrics: saves, close-ups, clicks, and spend. Allow sorting by any metric. Add a 'Top Performers' section highlighting the 3 Pins with the best click-through rate this week.

Copy this prompt to try it in V0

Weekly Ads Report Generation

A marketing agency uses V0 to build a client-facing Pinterest Ads report page that automatically pulls the past week's campaign data and displays it in a clean, shareable format.

V0 Prompt

Create a weekly Pinterest Ads report page with a header showing client logo, report period, and total ad spend. Display a summary section with week-over-week change indicators for impressions, clicks, and conversions. Add a campaign breakdown table and a spend-over-time line chart. Include an export to PDF button.

Copy this prompt to try it in V0

Troubleshooting

Pinterest API returns 401 Unauthorized

Cause: The PINTEREST_ACCESS_TOKEN is invalid, expired, or does not have the ads:read scope.

Solution: Regenerate the access token in the Pinterest Developer portal. Make sure to select the ads:read scope when generating. Verify the token is correctly copied without trailing whitespace into the Vercel environment variable.

Pinterest API returns 403 Forbidden on analytics endpoint

Cause: The access token belongs to a user who does not have access to the specified ad account, or the ad account ID is incorrect.

Solution: Verify the PINTEREST_AD_ACCOUNT_ID matches the numeric ID in your Ads Manager URL. The Pinterest account that generated the access token must be an admin or analyst on that ad account.

Analytics endpoint returns an empty array with no data

Cause: No campaigns ran during the specified date range, or the date format is incorrect. Pinterest requires YYYY-MM-DD format for date parameters.

Solution: Verify the date format in your API route uses YYYY-MM-DD (e.g., '2026-03-01', not '03/01/2026'). Check the Ads Manager to confirm campaigns were active during the date range being queried.

typescript
1// Correct date format
2const startDate = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString().split('T')[0]; // '2026-03-01'

Campaign spend shows $0 for active campaigns

Cause: The analytics endpoint column name for spend is SPEND_IN_DOLLAR — using the wrong column name returns null or zero.

Solution: Double-check the exact column names in the Pinterest API documentation. Spend is SPEND_IN_DOLLAR (not SPEND or COST). Add console.log of the raw API response in development to confirm what field names Pinterest returns.

Best practices

  • Store PINTEREST_ACCESS_TOKEN and PINTEREST_AD_ACCOUNT_ID in Vercel environment variables without the NEXT_PUBLIC_ prefix
  • Cache Pinterest analytics responses with next: { revalidate: 300 } to reduce API calls since campaign data does not change minute-by-minute
  • Use YYYY-MM-DD date format for all Pinterest API date parameters
  • Implement pagination for large ad accounts with many campaigns using the Pinterest API's page_size and bookmark parameters
  • Display CTR as a percentage (e.g., 2.35%) rather than a decimal (0.0235) for more intuitive dashboard readability
  • Show week-over-week or period-over-period percentage changes alongside absolute numbers to make performance trends immediately visible
  • Include a campaign status filter since Pinterest Ads accounts often have many paused or archived campaigns alongside active ones

Alternatives

Frequently asked questions

Where do I find my Pinterest ad account ID?

Your Pinterest ad account ID is the numeric string in the URL when you are logged into Pinterest Ads Manager. For example, if your URL is https://ads.pinterest.com/advertiser/123456789/overview/, your ad account ID is 123456789. It is also visible in Ads Manager under account settings.

Does the Pinterest Ads API have a sandbox or test environment?

Pinterest does not offer a separate sandbox environment for the Ads API. API calls read from and write to your real Pinterest Ads account. Use a test ad account with minimal or paused campaigns during development to avoid accidentally modifying active campaigns.

What metrics does Pinterest Ads API provide?

Pinterest Ads API provides impressions, clicks, spend, saves (Pins saved to boards), close-up views (zoomed-in engagements), outbound clicks (to your website), video views, add-to-cart events, checkouts, and custom conversion events. Visual engagement metrics like close-ups and saves are unique to Pinterest and often more meaningful than click rates alone.

Can I use the Pinterest Ads API to create and manage campaigns?

Yes, the Pinterest Ads API v5 supports both read and write operations. With the ads:write scope, you can create campaigns, ad groups, and ads programmatically. For the analytics dashboard in this tutorial, the ads:read scope is sufficient.

How do I handle accounts with hundreds of campaigns in the API?

The Pinterest Ads API returns paginated results with a default page size of 25. To fetch all campaigns, implement cursor-based pagination: check for a bookmark in the API response and include it as a bookmark parameter in your next request until no more pages exist. For very large accounts, consider fetching only active campaigns in the initial load.

Can V0 generate a pin thumbnail grid for ad creative analysis?

Yes. Prompt V0 to generate a masonry or responsive grid layout showing Pinterest Pin thumbnails with overlay performance metrics. V0 will use the Next.js Image component for the thumbnails and position metric badges using absolute positioning with Tailwind. Wire up the Pin image URL from the Pinterest API's pin_id field which resolves to a thumbnail URL.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.