Skip to main content
RapidDev - Software Development Agency
bolt-ai-integrationsBolt Chat + API Route

How to Integrate Bolt.new with Reddit Ads

Integrate Bolt.new with Reddit Ads using the Reddit Marketing API via Next.js API routes. Create a Reddit Ads developer app, implement OAuth 2.0 to obtain bearer tokens, then fetch campaign performance data including impressions, clicks, CPC, and conversion metrics. Build a community-targeted ad analytics dashboard. Reddit targets by subreddit and interest community — a fundamentally different model from demographic-based platforms. OAuth callback requires a deployed URL for production access.

What you'll learn

  • How to create a Reddit Ads developer app and configure OAuth 2.0 credentials
  • How to obtain and refresh bearer tokens for the Reddit Ads API
  • How to fetch campaign, ad group, and ad performance metrics via a Next.js API route
  • How to build an analytics dashboard displaying Reddit-specific metrics like community engagement
  • How to handle Reddit's subreddit-based targeting data in your dashboard
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate19 min read40 minutesMarketingApril 2026RapidDev Engineering Team
TL;DR

Integrate Bolt.new with Reddit Ads using the Reddit Marketing API via Next.js API routes. Create a Reddit Ads developer app, implement OAuth 2.0 to obtain bearer tokens, then fetch campaign performance data including impressions, clicks, CPC, and conversion metrics. Build a community-targeted ad analytics dashboard. Reddit targets by subreddit and interest community — a fundamentally different model from demographic-based platforms. OAuth callback requires a deployed URL for production access.

Build a Custom Reddit Ads Analytics Dashboard in Bolt.new

Reddit Ads reaches over 100,000 active communities organized by topic and interest — a targeting model fundamentally different from Facebook's demographic approach or Google's keyword-based intent. When you advertise on Reddit, you choose subreddits (communities like r/technology, r/personalfinance, or r/gaming) and interest categories that Reddit users self-select by joining. This community-first targeting creates higher engagement among enthusiasts compared to mass-market demographic targeting, but it also means the standard campaign analytics metrics tell only part of the story — upvotes, comments, and community engagement signal quality in ways that CTR alone does not.

The Reddit Ads API follows standard REST conventions with OAuth 2.0 authentication. All API calls use HTTPS, which means outbound requests from Bolt's WebContainer preview work correctly during development. You can build and populate your campaign analytics dashboard in Bolt, see real numbers, and test most of the integration before deploying. The exception is OAuth 2.0 authorization flows where Reddit redirects back to your app — these callbacks require a stable HTTPS URL, which means testing the full auth flow requires deploying to Netlify or Bolt Cloud first.

For building a dashboard for your own ad account — an agency tool for one account, an internal analytics view, or a personal dashboard — you can use a long-lived refresh token obtained once through the authorization flow, then stored as an environment variable. This approach avoids building full OAuth infrastructure for single-account access and works well for most Bolt use cases. Multi-tenant applications where users connect their own Reddit Ads accounts need the full OAuth PKCE flow and a deployed callback URL.

Integration method

Bolt Chat + API Route

Bolt generates Next.js API routes that proxy requests to Reddit's Ads API, keeping your client credentials and bearer tokens server-side. Reddit's API is REST over HTTPS, so outbound API calls for reading campaign data work in Bolt's WebContainer during development. OAuth 2.0 authorization for multi-user apps requires a deployed URL as the redirect URI, but single-account access using a refresh token can be tested immediately.

Prerequisites

  • A Bolt.new account with a Next.js project
  • A Reddit account with an active Reddit Ads account (ads.reddit.com)
  • At least $5 in ad spend history on the Reddit Ads account (required for API access)
  • A Reddit developer app created at reddit.com/prefs/apps with 'web app' type
  • A Reddit Ads API access request submitted at business.reddithelp.com (API access is not automatic)

Step-by-step guide

1

Create a Reddit Developer App and Request API Access

Reddit Ads API access requires two separate steps: creating an OAuth app at the Reddit developer portal, and separately requesting Ads API access through Reddit's business help center. This two-step requirement trips up most developers who assume creating a developer app is sufficient. First, go to reddit.com/prefs/apps and scroll to the bottom. Click 'Create App' or 'Create another app.' Choose the app type: select 'web app' for production use (supports OAuth 2.0 with refresh tokens), or 'script' for personal use with a single Reddit account (simpler but limited to your own account). Give your app a name and description. For the redirect URI, enter `https://localhost:3000/auth/callback` for initial setup — you will update this to your production URL after deployment. Copy your app's client ID (shown below the app name, looks like a random string) and generate a client secret (click 'edit' on the app to see the secret). These are your OAuth 2.0 credentials. Second, request Ads API access at business.reddithelp.com/helpcenter/s/contactsupport. Select 'Advertiser' as your issue type and explain your use case. Reddit manually reviews API access requests, with approval typically taking three to seven business days. While waiting for API access approval, you can build the dashboard frontend and API route structure using mock data. Once approved, Reddit will email your Ads account ID (format: `t2_xxxxxxxx`) and confirm your app has been granted Ads API permissions. Add your credentials to Bolt's .env file to proceed.

Bolt.new Prompt

Add a .env file with REDDIT_CLIENT_ID=your-client-id, REDDIT_CLIENT_SECRET=your-client-secret, REDDIT_ACCESS_TOKEN=your-access-token, REDDIT_REFRESH_TOKEN=your-refresh-token, and REDDIT_ACCOUNT_ID=t2_your-account-id. Create a lib/reddit.ts file that exports a redditFetch helper function which takes an endpoint string and optional params. The function should call https://ads-api.reddit.com/api/v2.1/{endpoint} with Authorization: Bearer {REDDIT_ACCESS_TOKEN} header from process.env and return the parsed JSON. Include error handling that throws with Reddit's error message.

Paste this in Bolt.new chat

lib/reddit.ts
1// lib/reddit.ts
2const REDDIT_ADS_BASE = 'https://ads-api.reddit.com/api/v2.1';
3
4interface RedditFetchOptions {
5 params?: Record<string, string>;
6 method?: 'GET' | 'POST' | 'PATCH' | 'DELETE';
7 body?: Record<string, unknown>;
8}
9
10export async function redditFetch<T = unknown>(
11 endpoint: string,
12 options: RedditFetchOptions = {}
13): Promise<T> {
14 const accessToken = process.env.REDDIT_ACCESS_TOKEN;
15 if (!accessToken) throw new Error('REDDIT_ACCESS_TOKEN is not configured');
16
17 const url = new URL(`${REDDIT_ADS_BASE}/${endpoint}`);
18 if (options.params) {
19 Object.entries(options.params).forEach(([key, value]) => {
20 url.searchParams.set(key, value);
21 });
22 }
23
24 const response = await fetch(url.toString(), {
25 method: options.method || 'GET',
26 headers: {
27 Authorization: `Bearer ${accessToken}`,
28 'Content-Type': 'application/json',
29 'User-Agent': 'BoltApp/1.0',
30 },
31 body: options.body ? JSON.stringify(options.body) : undefined,
32 });
33
34 if (!response.ok) {
35 const errorText = await response.text();
36 throw new Error(`Reddit Ads API error ${response.status}: ${errorText}`);
37 }
38
39 return response.json() as Promise<T>;
40}
41
42export async function refreshRedditToken(): Promise<string> {
43 const credentials = Buffer.from(
44 `${process.env.REDDIT_CLIENT_ID}:${process.env.REDDIT_CLIENT_SECRET}`
45 ).toString('base64');
46
47 const response = await fetch('https://www.reddit.com/api/v1/access_token', {
48 method: 'POST',
49 headers: {
50 Authorization: `Basic ${credentials}`,
51 'Content-Type': 'application/x-www-form-urlencoded',
52 'User-Agent': 'BoltApp/1.0',
53 },
54 body: new URLSearchParams({
55 grant_type: 'refresh_token',
56 refresh_token: process.env.REDDIT_REFRESH_TOKEN || '',
57 }),
58 });
59
60 const data = await response.json() as { access_token?: string; error?: string };
61 if (data.error || !data.access_token) {
62 throw new Error(`Token refresh failed: ${data.error}`);
63 }
64 return data.access_token;
65}

Pro tip: For single-account access (your own Reddit Ads account), use a 'script' type app instead of 'web app'. Script apps can obtain tokens via the password grant type without needing an OAuth redirect flow, which simplifies initial testing in Bolt's WebContainer.

Expected result: The Reddit API helper is set up with your credentials in .env. The redditFetch function is ready to call any Reddit Ads API endpoint with Bearer token authentication.

2

Obtain a Long-Lived Access Token via OAuth 2.0

Reddit uses OAuth 2.0 for all Ads API access. The token flow depends on your app type. For 'script' apps (single Reddit account access), you can use the password grant to obtain tokens without a redirect flow — ideal for building personal or internal dashboards without deploying first. For 'web app' type (multi-user access), you need the authorization code flow with a redirect URI, which requires a deployed URL. For script apps: send a POST request to `https://www.reddit.com/api/v1/access_token` with Basic Auth using your client ID and secret, and a body with `grant_type=password`, `username=your-reddit-username`, and `password=your-reddit-password`. The response includes `access_token` (valid for one hour) and a `refresh_token` for renewal. For web apps (multi-user): construct an authorization URL pointing to `https://www.reddit.com/api/v1/authorize` with query params `client_id`, `response_type=code`, `state=random-string`, `redirect_uri=your-deployed-url/auth/callback`, `duration=permanent`, and `scope=ads:read ads:write`. After the user approves, Reddit redirects to your callback URL with a `code` parameter. Exchange this code for tokens via a POST to the token endpoint. The `duration=permanent` parameter is critical — it requests a refresh token that lets you obtain new access tokens indefinitely without re-authorization. For the refresh token obtained during initial setup, add it to your .env as `REDDIT_REFRESH_TOKEN`. When the access token expires (after one hour), your API route calls the refresh endpoint using the client credentials and refresh token to obtain a new access token. Build this refresh logic directly into your API routes so token expiry is handled transparently without manual intervention.

Bolt.new Prompt

Create a Next.js API route at app/api/reddit/auth/route.ts that handles Reddit OAuth. On GET with a 'code' query param, exchange it for access and refresh tokens by POSTing to https://www.reddit.com/api/v1/access_token with Basic Auth (REDDIT_CLIENT_ID:REDDIT_CLIENT_SECRET) and grant_type=authorization_code. Return the tokens as JSON. Also create an app/api/reddit/refresh/route.ts that uses REDDIT_REFRESH_TOKEN from process.env to get a new access token and returns it.

Paste this in Bolt.new chat

app/api/reddit/refresh/route.ts
1// app/api/reddit/refresh/route.ts
2import { NextResponse } from 'next/server';
3
4export async function POST() {
5 const clientId = process.env.REDDIT_CLIENT_ID;
6 const clientSecret = process.env.REDDIT_CLIENT_SECRET;
7 const refreshToken = process.env.REDDIT_REFRESH_TOKEN;
8
9 if (!clientId || !clientSecret || !refreshToken) {
10 return NextResponse.json(
11 { error: 'Reddit credentials not configured' },
12 { status: 500 }
13 );
14 }
15
16 const credentials = Buffer.from(`${clientId}:${clientSecret}`).toString('base64');
17
18 const response = await fetch('https://www.reddit.com/api/v1/access_token', {
19 method: 'POST',
20 headers: {
21 Authorization: `Basic ${credentials}`,
22 'Content-Type': 'application/x-www-form-urlencoded',
23 'User-Agent': 'BoltApp/1.0',
24 },
25 body: new URLSearchParams({
26 grant_type: 'refresh_token',
27 refresh_token: refreshToken,
28 }),
29 });
30
31 const data = await response.json() as {
32 access_token?: string;
33 expires_in?: number;
34 error?: string;
35 };
36
37 if (!response.ok || data.error) {
38 return NextResponse.json(
39 { error: data.error || 'Token refresh failed' },
40 { status: 401 }
41 );
42 }
43
44 return NextResponse.json({
45 accessToken: data.access_token,
46 expiresIn: data.expires_in,
47 });
48}

Pro tip: Store the access token in a server-side cache (e.g., a module-level variable with an expiry timestamp) to avoid calling the refresh endpoint on every request. Reddit access tokens last one hour — refresh once per session rather than on each API call.

Expected result: The token refresh endpoint returns a fresh access token. You can verify this works by calling /api/reddit/refresh from your browser and checking that a valid access_token string is returned in the response.

3

Build the Campaign Analytics API Route

Reddit's Ads API organizes campaigns in a three-level hierarchy: Campaigns (top-level objectives), Ad Groups (targeting and bidding), and Ads (creatives). Performance data is fetched via dedicated reporting endpoints rather than embedded in the campaign objects themselves. This separation means you typically need two API calls: one to fetch campaigns list and one to fetch their performance metrics. The campaigns endpoint is `GET /accounts/{account_id}/campaigns` and returns campaign metadata including name, status, objective, and budget configuration. The reporting endpoint for performance metrics is typically `GET /accounts/{account_id}/reports` with date range and breakdown parameters. Key metrics available include impressions, clicks, conversions, spend, CPM, CPC, CTR, and video views for video ads. Reddit Ads has unique metrics that differ from other platforms. The `ecpm` (effective CPM) reflects actual auction-clearing prices, and Reddit also provides `video_watched_75_percent` and `video_complete_views` for video creatives. The `reddit_engagement` metric counts post upvotes, comments, and shares that organic Reddit users take on your promoted posts — a metric unique to the platform that reflects content quality beyond click performance. For date ranges, the reporting API accepts ISO 8601 date strings for `start_time` and `end_time`. The granularity parameter controls whether you get aggregated totals or daily breakdowns — use `TOTAL` for summary cards and `DAY` for trend charts. A practical detail: Reddit's Ads API returns monetary values in microdollars (1,000,000 microdollars = $1.00). Divide all spend values by 1,000,000 before displaying them. This is different from Meta's API (which uses dollars as strings) and Stripe (which uses cents).

Bolt.new Prompt

Create a Next.js API route at app/api/reddit/campaigns/route.ts that fetches campaign performance from Reddit Ads API. Accept query params: startDate and endDate (ISO 8601). Call GET /accounts/{REDDIT_ACCOUNT_ID}/campaigns to get campaigns, then GET /accounts/{REDDIT_ACCOUNT_ID}/reports with date_start, date_end, entity=campaign, and fields for impressions, clicks, spend, ecpm, ecpc, ctr, conversions. Join by campaign ID. Convert spend from microdollars (divide by 1000000). Return sorted by spend descending. Handle REDDIT_ACCESS_TOKEN from process.env.

Paste this in Bolt.new chat

app/api/reddit/campaigns/route.ts
1// app/api/reddit/campaigns/route.ts
2import { NextResponse } from 'next/server';
3import { redditFetch } from '@/lib/reddit';
4
5interface RedditCampaign {
6 id: string;
7 name: string;
8 status: string;
9 objective: string;
10 daily_budget_in_cents?: number;
11 total_budget_in_cents?: number;
12}
13
14interface RedditReportRow {
15 id: string;
16 impressions: number;
17 clicks: number;
18 spend: number; // microdollars
19 ecpm: number;
20 ecpc: number;
21 ctr: number;
22 conversions?: number;
23}
24
25export async function GET(request: Request) {
26 const { searchParams } = new URL(request.url);
27 const startDate = searchParams.get('startDate') ||
28 new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString().split('T')[0];
29 const endDate = searchParams.get('endDate') ||
30 new Date().toISOString().split('T')[0];
31
32 const accountId = process.env.REDDIT_ACCOUNT_ID;
33 if (!accountId) {
34 return NextResponse.json({ error: 'REDDIT_ACCOUNT_ID is not configured' }, { status: 500 });
35 }
36
37 try {
38 const [campaignsData, reportsData] = await Promise.all([
39 redditFetch<{ data: RedditCampaign[] }>(
40 `accounts/${accountId}/campaigns`,
41 { params: { limit: '100' } }
42 ),
43 redditFetch<{ data: RedditReportRow[] }>(
44 `accounts/${accountId}/reports`,
45 {
46 params: {
47 entity: 'campaign',
48 fields: 'impressions,clicks,spend,ecpm,ecpc,ctr,conversions',
49 date_start: startDate,
50 date_end: endDate,
51 granularity: 'TOTAL',
52 },
53 }
54 ),
55 ]);
56
57 const metricsMap = new Map<string, RedditReportRow>();
58 (reportsData.data || []).forEach((row) => {
59 metricsMap.set(row.id, row);
60 });
61
62 const campaigns = (campaignsData.data || []).map((campaign) => {
63 const metrics = metricsMap.get(campaign.id);
64 return {
65 id: campaign.id,
66 name: campaign.name,
67 status: campaign.status,
68 objective: campaign.objective,
69 dailyBudget: campaign.daily_budget_in_cents
70 ? campaign.daily_budget_in_cents / 100
71 : null,
72 impressions: metrics?.impressions ?? 0,
73 clicks: metrics?.clicks ?? 0,
74 spend: metrics ? metrics.spend / 1_000_000 : 0,
75 cpm: metrics ? metrics.ecpm / 1_000_000 : 0,
76 cpc: metrics ? metrics.ecpc / 1_000_000 : 0,
77 ctr: metrics?.ctr ?? 0,
78 conversions: metrics?.conversions ?? 0,
79 };
80 });
81
82 campaigns.sort((a, b) => b.spend - a.spend);
83
84 const totals = campaigns.reduce(
85 (acc, c) => ({
86 spend: acc.spend + c.spend,
87 impressions: acc.impressions + c.impressions,
88 clicks: acc.clicks + c.clicks,
89 conversions: acc.conversions + c.conversions,
90 }),
91 { spend: 0, impressions: 0, clicks: 0, conversions: 0 }
92 );
93
94 return NextResponse.json({ campaigns, totals, dateRange: { startDate, endDate } });
95 } catch (err) {
96 const message = err instanceof Error ? err.message : 'Failed to fetch Reddit campaigns';
97 return NextResponse.json({ error: message }, { status: 500 });
98 }
99}

Pro tip: Reddit Ads API rate limits are 100 requests per minute per OAuth token. The parallel Promise.all fetch for campaigns and reports counts as 2 requests — well within limits. If you add more endpoints later (ad groups, ads), batch requests carefully to stay under the rate limit.

Expected result: The API route returns a campaigns array with performance metrics joined from the reports endpoint. Spend values should be in dollars (e.g., 127.43 not 127430000). Call /api/reddit/campaigns in the browser to verify your real campaign data appears.

4

Build the Reddit Ads Dashboard Interface

Reddit Ads dashboards benefit from surfacing community-specific context that standard ad platform dashboards omit. Beyond the usual spend, clicks, and CTR metrics, Reddit advertisers care about which subreddit communities drove the best performance and how organic Reddit engagement (upvotes, comments) on promoted posts compares across creatives. For the dashboard layout, organize it as: a top summary row with total spend, total clicks, average CTR, and total conversions; a campaign table with sortable columns; and a secondary section showing performance by subreddit community when ad group data is available. The community breakdown is where Reddit Ads insight differs most from other platforms — seeing that r/personalfinance converts at 3x the rate of r/news for your financial product is the kind of insight that reshapes your entire targeting strategy. For date range selection, Reddit's API accepts specific ISO date strings, so build a date range picker with presets (Last 7 days, Last 30 days, Last 90 days) that compute the correct ISO strings. Use the same pattern as the Facebook Ads dashboard for the React date picker component — this consistency makes users comfortable across your multi-platform analytics app. For the campaign status display, Reddit campaigns have statuses including ACTIVE, PAUSED, COMPLETED, DRAFT, and SCHEDULED. Color-code these clearly: green for ACTIVE, yellow for PAUSED, gray for COMPLETED, and blue for SCHEDULED. The DRAFT status indicates campaigns that have been created but not yet submitted for review — these are important to surface separately since they are not yet spending. Charts that work well for Reddit Ads: a horizontal bar chart ranking campaigns by spend (same as other ad platforms), a scatter plot comparing CTR vs CPC to identify efficient subreddit targeting, and a conversion funnel chart from impressions to clicks to conversions.

Bolt.new Prompt

Build a Reddit Ads dashboard page at /reddit-ads. Fetch from /api/reddit/campaigns with date range params defaulting to last 30 days. Show: (1) summary cards for total spend (formatted as $X.XX), total clicks, average CTR percentage, and total conversions; (2) a Recharts bar chart of spend by campaign; (3) a sortable table with columns for Campaign Name, Status (color-coded badge), Objective, Spend, Impressions, Clicks, CTR, CPC, and Conversions. Add a date range selector with Last 7d / Last 30d / Last 90d presets. Include loading skeletons and an error state.

Paste this in Bolt.new chat

Pro tip: Reddit Ads objective names differ from Meta's. Reddit uses TRAFFIC, CONVERSIONS, VIDEO_VIEWS, APP_INSTALLS, BRAND_AWARENESS, and LEAD_GENERATION. Map these to user-friendly display names in your dashboard (e.g., TRAFFIC → 'Website Traffic') for better readability.

Expected result: The Reddit Ads dashboard loads with real campaign data, displays spend and performance metrics with proper formatting, and the date range selector refreshes the data correctly when changed.

5

Deploy and Set Up OAuth Callback for Production

During development in Bolt's WebContainer, outbound calls to Reddit's Ads API work correctly for fetching campaign data. The constraint is OAuth 2.0 callback handling — when you build a multi-user app where different advertisers can connect their Reddit Ads accounts, the OAuth redirect URL must point to a stable HTTPS server. Bolt's WebContainer preview URL (`webcontainer-api.io` subdomain) changes and cannot receive the OAuth callback reliably. Deploy to Netlify via Settings → Applications → Connect Netlify, or click Publish to deploy to Bolt Cloud. After deployment, you will have a stable URL like `https://your-app.netlify.app`. Update your Reddit developer app at reddit.com/prefs/apps to add the production redirect URI: `https://your-app.netlify.app/api/reddit/auth/callback`. In your hosting dashboard (Netlify environment variables or Bolt Cloud secrets), add the production values: `REDDIT_CLIENT_ID`, `REDDIT_CLIENT_SECRET`, `REDDIT_ACCESS_TOKEN`, `REDDIT_REFRESH_TOKEN`, and `REDDIT_ACCOUNT_ID`. These should be your production credentials, not the development placeholders from your .env file. For building a SaaS product where multiple advertisers connect their Reddit Ads accounts, you need a proper token storage system. Each user's access token and refresh token must be stored in your database (Supabase or similar), associated with their user ID, and retrieved per-request. The single-token approach in .env only works for single-account access. Build the multi-tenant flow after validating the single-account integration works end-to-end in production.

Bolt.new Prompt

Add an /api/reddit/health route that checks if REDDIT_ACCESS_TOKEN and REDDIT_ACCOUNT_ID are configured, then calls Reddit Ads API GET /accounts/{REDDIT_ACCOUNT_ID}/campaigns with limit=1 to verify authentication works. Return { connected: true, accountId } on success or { connected: false, error } if any check fails. Add a connection status banner at the top of the Reddit Ads dashboard page that shows this health check result.

Paste this in Bolt.new chat

.env.example
1# Production environment variables add in Netlify Dashboard or Bolt Cloud Secrets
2# Never commit these values to your git repository
3
4REDDIT_CLIENT_ID=your_client_id_here
5REDDIT_CLIENT_SECRET=your_client_secret_here
6REDDIT_ACCESS_TOKEN=your_access_token_here
7REDDIT_REFRESH_TOKEN=your_refresh_token_here
8REDDIT_ACCOUNT_ID=t2_your_account_id
9
10# Redirect URI registered in Reddit developer app settings:
11# https://your-app.netlify.app/api/reddit/auth/callback

Pro tip: Reddit access tokens expire after one hour. For production, implement automatic token refresh: catch 401 errors in your redditFetch helper, call the refresh endpoint, update the stored token, and retry the original request. This makes token expiry transparent to your users.

Expected result: The app is deployed with production Reddit credentials configured. The health check confirms the API connection is working. OAuth callbacks to /api/reddit/auth/callback succeed with the deployed URL registered in your Reddit developer app.

Common use cases

Reddit Ads Campaign Performance Dashboard

Build a dashboard showing campaign-level performance across all active Reddit Ads campaigns. Display spend, impressions, clicks, CPC, CPM, and conversion metrics with the ability to drill down into individual ad groups and ads. Compare performance across campaigns targeting different subreddit communities to identify which audiences drive the best results.

Bolt.new Prompt

Build a Reddit Ads analytics dashboard. Create a Next.js API route at /api/reddit/campaigns that calls Reddit's Ads API to fetch all campaigns with their performance metrics (spend, impressions, clicks, cpc, cpm, conversions) for a given date range. Accept accountId and dateRange as query params. Use REDDIT_ACCESS_TOKEN from process.env as a Bearer token. Build a React dashboard with a summary row of total spend and clicks, a sortable campaign table, and a bar chart comparing spend by campaign. Show subreddit targeting for each campaign.

Copy this prompt to try it in Bolt.new

Subreddit Targeting Performance Analyzer

Analyze which subreddit communities are driving the best campaign performance. Pull ad group targeting data to identify the most cost-efficient community placements, compare engagement rates across different subreddit categories, and surface insights about which communities convert best for your offer type.

Bolt.new Prompt

Create a subreddit performance analyzer using Reddit Ads API. Build a Next.js API route at /api/reddit/ad-groups that fetches all ad groups in an account with their targeting details and performance metrics (impressions, clicks, cpc, ctr, conversions). Create a React component showing each ad group's targeted subreddits, key performance metrics, and a cost-per-conversion badge. Group ad groups by subreddit category (technology, finance, gaming, etc.) and show aggregate performance per category. Store REDDIT_ACCESS_TOKEN and REDDIT_ACCOUNT_ID in process.env.

Copy this prompt to try it in Bolt.new

Reddit Ads Budget Monitor and Alert System

Build a monitoring dashboard that tracks budget pacing across Reddit Ads campaigns and alerts when campaigns are over-spending or under-delivering against their daily budgets. Show real-time spend versus budget allocation to help optimize campaign budget distribution across subreddit targets.

Bolt.new Prompt

Build a Reddit Ads budget monitoring dashboard. Create a Next.js API route at /api/reddit/budget-status that fetches all active campaigns with their daily budgets, current spend, and pacing. Calculate spend percentage for today. Return campaigns sorted by overpace (spending too fast) vs underpace (spending too slow). Build a React dashboard with color-coded pacing indicators: green for 80-110% of expected pace, yellow for 50-80% or 110-130%, red for under 50% or over 130%. Add a total account spend summary. Use REDDIT_ACCESS_TOKEN and REDDIT_ACCOUNT_ID from process.env.

Copy this prompt to try it in Bolt.new

Troubleshooting

401 Unauthorized — 'invalid_token' or 'token_expired' error from Reddit API

Cause: Reddit access tokens expire after exactly one hour. If your REDDIT_ACCESS_TOKEN in .env is more than an hour old, all API calls will return 401.

Solution: Call your /api/reddit/refresh endpoint to get a new access token, then update REDDIT_ACCESS_TOKEN in your .env file. For production, build automatic token refresh into your redditFetch helper to catch 401 responses, call the refresh endpoint, and retry the request automatically.

typescript
1// Add auto-refresh to lib/reddit.ts:
2export async function redditFetchWithRefresh<T>(endpoint: string, options = {}): Promise<T> {
3 try {
4 return await redditFetch<T>(endpoint, options);
5 } catch (err) {
6 if (err instanceof Error && err.message.includes('401')) {
7 const newToken = await refreshRedditToken();
8 process.env.REDDIT_ACCESS_TOKEN = newToken;
9 return redditFetch<T>(endpoint, options);
10 }
11 throw err;
12 }
13}

403 Forbidden — 'insufficient_scope' or 'USER_REQUIRED' from Reddit Ads API

Cause: Either the OAuth token was generated without the required 'ads:read' and 'ads:write' scopes, or your Reddit developer app has not been approved for Ads API access by Reddit's team.

Solution: Verify your Reddit Ads API access has been approved by checking if you received a confirmation email from Reddit Business support. If approved, regenerate your access token and explicitly include the 'ads:read ads:write' scopes in your OAuth authorization request. Script app tokens must also include the correct scope in the authorization request.

Spend values appear as extremely large numbers (e.g., 12743000 instead of $12.74)

Cause: Reddit's Ads API returns monetary values in microdollars — multiply by 1,000,000 to get dollars. Forgetting to convert this results in spend figures that appear to be millions of dollars.

Solution: Divide all spend, CPM, and CPC values from the Reddit Reports API by 1,000,000 before displaying or storing them. Budget values from the campaigns endpoint are in cents — divide those by 100.

typescript
1// Correct conversion in API route:
2spend: metrics ? metrics.spend / 1_000_000 : 0, // microdollars to dollars
3cpm: metrics ? metrics.ecpm / 1_000_000 : 0, // microdollars to dollars
4dailyBudget: campaign.daily_budget_in_cents / 100, // cents to dollars

OAuth callback fails during local development — redirect to localhost does not work in WebContainer

Cause: Bolt's WebContainer cannot reliably receive OAuth callbacks from external services like Reddit. The WebContainer uses dynamic URLs that change between sessions and cannot be registered as stable OAuth redirect URIs.

Solution: For single-account access, use a Reddit 'script' app type which allows password-grant authentication without a redirect URI. For web app OAuth flows, deploy to Netlify or Bolt Cloud first to get a stable HTTPS URL, register that URL as your redirect URI in the Reddit developer app, then complete the OAuth flow on the deployed site.

Best practices

  • Use a 'script' type Reddit app and password grant for single-account internal dashboards — it eliminates the OAuth redirect complexity and works immediately without deploying.
  • Store monetary values from Reddit's API as raw microdollars in any database, only converting to dollars at display time — this preserves precision and matches what the API returns natively.
  • Cache Reddit Ads API responses for at least 5 minutes since campaign metrics update at most hourly and the API has a 100 requests per minute rate limit per token.
  • Implement automatic token refresh in your API helper using try-catch on 401 errors — Reddit access tokens expire after exactly one hour and manual token rotation breaks production dashboards.
  • Display Reddit's unique engagement metrics (upvotes, comments, shares on promoted posts) alongside standard click metrics — they signal creative quality in ways CTR does not capture.
  • Always divide spend values by 1,000,000 and budget values by 100 before displaying — Reddit's API uses microdollars for metrics and cents for budget fields, mixing two different units.
  • Add Reddit Ads account ID validation (must start with 't2_' prefix) to your API routes to provide clear error messages when the account ID is misconfigured.
  • Build subreddit-level performance breakdowns using the ad group reporting endpoint — community-level insight is Reddit's key differentiator from other ad platforms and unlocks targeting optimization unavailable in standard dashboards.

Alternatives

Frequently asked questions

Does Bolt.new have a native Reddit Ads integration?

No — Bolt.new does not have a native Reddit Ads connector. The integration requires building Next.js API routes that call Reddit's Ads API endpoints with OAuth 2.0 authentication. Bolt's AI can generate this boilerplate from a descriptive prompt, significantly reducing the initial setup time even without a built-in connector.

Can I test the Reddit Ads dashboard in Bolt's WebContainer preview without deploying?

Yes for most features — outbound GET requests to Reddit's Ads API work in Bolt's WebContainer since they are standard HTTPS calls. You can fetch campaign data, populate your dashboard, and test the analytics display entirely in the preview. The only feature requiring deployment is the OAuth 2.0 authorization callback, which Reddit sends back to your redirect URI. For single-account access using a pre-obtained refresh token stored in .env, no OAuth callback is needed during development.

Do I need to apply separately for Reddit Ads API access beyond creating a developer app?

Yes — creating a developer app at reddit.com/prefs/apps is only the first step. You must also request Ads API access through Reddit's business help center and wait for manual approval, which typically takes three to seven business days. Without explicit API access approval, your developer app can authenticate with Reddit but cannot call the Ads API endpoints. The approval process requires explaining your use case.

Why does the Reddit Ads API show spend as multi-million dollar values?

Reddit's Ads API reports API returns monetary values in microdollars, not dollars. One US dollar equals 1,000,000 microdollars in their API response. Divide all spend, eCPM, and eCPC values from the reports endpoint by 1,000,000 to convert to dollars. Note that the campaigns endpoint returns budget values in cents (divide by 100), not microdollars — a different unit used for the same type of data.

How does Reddit Ads targeting differ from Facebook Ads in my dashboard?

Reddit targets users by the communities (subreddits) they join and engage with, not by demographic attributes like age, income, or interests inferred from behavior. This means your Reddit Ads dashboard should surface subreddit-level performance data — which communities drove the best CTR and conversions — rather than demographic breakdowns. Reddit's API provides targeting data per ad group, including the specific subreddits targeted, enabling community-level performance analysis that has no equivalent on other platforms.

How long do Reddit access tokens last and how should I handle expiry?

Reddit access tokens expire after exactly one hour. Refresh tokens obtained with 'duration=permanent' in the OAuth request do not expire and can generate new access tokens indefinitely. Build automatic token refresh into your API helper: catch 401 responses, call the refresh endpoint using your client credentials and refresh token, store the new access token, and retry the original request. This makes expiry invisible to dashboard users.

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.