Skip to main content

Reddit Ads

The Reddit Ads source syncs campaigns, ads, and daily campaign performance metrics from the Reddit Ads API v3 for a single ad account.

Prerequisites

  • A Reddit Ads account with at least one ad account.
  • A Reddit developer app, which gives you the app ID and secret this connector uses as its OAuth client ID and client secret. Only business admins with a verified Reddit account can create one.
  • An OAuth refresh token for that app, authorized with the adsread scope.
  • The ID of the ad account you want to sync.

Set up the Reddit Ads source

Step 1: Create a developer app

  1. In Reddit Ads Manager, open your business's Developer Applications page.
  2. Select Add Apps > Create an app, then fill in the app name, About URL, redirect URL, and primary contact. Reddit requires a redirect URL even though the connector never uses it interactively, so any URL you control works, such as https://example.com/oauth/callback.
  3. Select Create App. Reddit shows the app ID and secret. Copy both. The app ID is your OAuth Client ID and the secret is your OAuth Client Secret.

If you already have a Reddit app under Preferences > Apps, you can select Add Apps > Migrate an existing app instead. Migrating limits the app's scope to the Ads API.

For details, see Reddit's Create a Developer Application guide.

Step 2: Get a refresh token

The connector authenticates with the OAuth refresh token grant, so you need a long-lived refresh token. Get one with the authorization code flow described in Reddit's authentication guide.

  1. Sign in to Reddit as the user whose ads data you want to sync, then open the following URL in a browser, replacing the placeholders:

    https://www.reddit.com/api/v1/authorize?client_id=YOUR_APP_ID&response_type=code&state=airbyte&redirect_uri=YOUR_REDIRECT_URL&duration=permanent&scope=adsread

    Set duration to permanent. A temporary authorization doesn't return a refresh token, and the connector can't sync without one. adsread is the only scope the connector needs.

  2. Select Allow. Reddit redirects to your redirect URL with a code query parameter. Copy the code, removing any trailing #_ characters. The code expires after 10 minutes and works only once.

  3. Exchange the code for tokens:

    curl -X POST https://www.reddit.com/api/v1/access_token \
    -H 'content-type: application/x-www-form-urlencoded' \
    -A 'YOUR_USER_AGENT' \
    -u 'YOUR_APP_ID:YOUR_APP_SECRET' \
    -d 'grant_type=authorization_code&code=YOUR_CODE&redirect_uri=YOUR_REDIRECT_URL'
  4. Copy the refresh_token value from the response. That's your OAuth Refresh Token. The connector uses it to obtain access tokens itself, so you don't need the access_token value.

Step 3: Find your ad account ID

In Reddit Ads Manager, open Business Manager > Assets > Ad Accounts. The ID appears under the ad account's name and starts with a2_. You can also call List Ad Accounts By Business with the token you just created.

Step 4: Configure the source in Airbyte

Enter the client ID, client secret, refresh token, and ad account ID, then set the remaining fields:

  • User Agent: Reddit requires a descriptive user agent on every request, in the format platform:app_id:version (by /u/username). For example, airbyte:reddit-ads-sync:v1.0 (by /u/your-username). Reddit heavily throttles default user agents such as Python/urllib or Java.
  • start_time: Optional. The earliest data to sync, in RFC 3339 format with a UTC offset, such as 2024-05-11T00:00:00Z. It applies to all three streams: it's the earliest modified_at for ad and campaign, and the earliest report date for campaign_report. If you leave it empty, all three streams start 24 months before the current sync.

Supported streams

StreamAPI endpointPrimary keyIncremental cursor
adGET /api/v3/ad_accounts/{ad_account_id}/adsidmodified_at
campaignGET /api/v3/ad_accounts/{ad_account_id}/campaignsidmodified_at
campaign_reportPOST /api/v3/ad_accounts/{ad_account_id}/reportscampaign_id, datedate

All three streams support full refresh and incremental sync, and all read from the single ad account you configure. To sync more than one ad account, create one source per account.

campaign_report returns one row per campaign per day, in GMT, with delivery and conversion metrics such as impressions, clicks, spend, reach, frequency, and per-objective conversion counts and values.

Sync behavior and limitations

  • Report metrics use micro-units. Reddit returns spend, cpc, cpv, ecpm, and the *_ecpa conversion metrics multiplied by 1,000,000, and the *_total_value and *_avg_value conversion metrics multiplied by 100. The connector loads these values unchanged, so divide them in your destination before reporting on currency amounts.
  • Recent report data changes after it lands. Reddit says metrics can take up to 6 hours to stabilize, and conversion data keeps updating as events arrive. The campaign_report stream re-reads a 7-hour window on each sync to pick up late updates, but rows for the last day or two can still change after they're synced.
  • Report history has a limit. Delivery data goes back 24 months, and reach and frequency data start in June 2024. If you set start_time earlier than 24 months ago, campaign_report still starts 24 months before the current sync, because Reddit rejects requests for older report data. The ad and campaign streams aren't clamped.
  • start_time filtering happens after the fetch. For ad and campaign, the Reddit API has no server-side filter on modified_at, so the connector requests every record in the ad account on each sync and discards those modified before your cursor value. Sync duration scales with the size of the account, not with the amount of new data.

Performance considerations

Reddit applies rate limits per authorized user and per endpoint group, so sources that use the same Reddit user share those limits. The report endpoint this connector calls for campaign_report allows 60 requests per minute (the ads-reporting group); the campaign and ad read endpoints belong to a separate group with its own quota. The connector retries 429 and 5xx responses up to 10 times with exponential backoff, and waits 60 seconds between report retries. For the full list of policies, see Reddit's rate limiting documentation.

Access tokens are valid for one hour or one day, depending on what Reddit returns. The connector reuses a token until it expires, then refreshes it. If a request still fails with 401, the connector refreshes the token and retries that request.

Configuration

InputTypeDescriptionDefault Value
client_idstringOAuth Client ID.
start_timestringOptional UTC start date applied to all three streams, in YYYY-MM-DDTHH:MM:SSZ format. A value earlier than 24 months ago is clamped for campaign_report, because Reddit only serves report data for the last 24 months.24 months before the current date
user_agentstringUser Agent. A unique and descriptive user agent string in the format: platform:app_id:version (by /u/yourusername). Required for all requests.
ad_account_idstringad_account_id.
client_secretstringOAuth Client Secret.
refresh_tokenstringOAuth Refresh Token.

Streams

Stream NamePrimary KeyPaginationSupports Full SyncSupports Incremental
adidDefaultPaginator
campaignidDefaultPaginator
campaign_reportcampaign_id.dateDefaultPaginator

IP allow list

If you use Airbyte Cloud and your organization restricts access to specific IPs, add the Airbyte Cloud IP addresses to your allow list.

Reference

Config fields reference

Field
Type
Property name
ad_account_id
required
string
ad_account_id
OAuth Client ID
required
string
client_id
OAuth Client Secret
required
string
client_secret
OAuth Refresh Token
required
string
refresh_token
string
user_agent
string
start_time

Changelog

Expand to review
VersionDatePull RequestSubject
0.0.42026-08-0483603Update dependencies
0.0.32026-07-3083266Stop refreshing the access token before every request, and refresh it before retrying a 401. Make start_time optional, apply it to all three streams, and default it to 24 months before the sync; clamp campaign_report to Reddit's 24-month reporting window
0.0.22026-07-2883100Update dependencies
0.0.12026-07-2781399Initial release by @Ella6882 via Connector Builder