Skip to main content
OpenAI Ads is OpenAI’s advertising platform. Ads appear inside ChatGPT conversations, in clearly labeled cards below the assistant’s answer, and are managed in OpenAI Ads Manager — which is why the platform is often referred to as ChatGPT Ads. The connector reads OpenAI’s Advertiser API to extract the structure of your ad account — campaigns, ad groups, ads, custom audiences and conversion settings — together with the daily delivery reporting behind it: impressions, clicks, spend, click-through rate, cost per click, cost per thousand impressions and attributed conversions. Reporting is aggregated by design. OpenAI exposes performance at the account, campaign, ad group and ad level, and optionally broken down by country, device or catalog product. Individual ChatGPT conversations and personal user data are never available.

Configuring OpenAI Ads as a Source

In the Sources tab, click on the “Add source” button located on the top right of your screen. Then, select the OpenAI Ads option from the list of connectors. Click Next and you’ll be prompted to add your access.

1. Add account access

OpenAI Ads authenticates with a static API key, sent as a bearer token. Each key is scoped to a single ad account.
1

Open Ads Manager

Sign in at ads.openai.com with the ad account you want to extract data from.
2

Go to Settings

Open the Settings tab.
3

Issue an API key

Create a new API key and copy the value.
This is not the same credential as an OpenAI API key from platform.openai.com. The Ads API uses its own key, issued from Ads Manager.
The following configurations are available:
  • API Key: the key you copied from Ads Manager.
  • Start Date: the earliest date from which reporting records will be synced. Leave it empty to sync the last year, which covers the entire history of any ad account. The API does not serve data older than five years.
  • Lookback Days: (Default: 7 days) how many days before the last synced day each run re-reads. Delivery metrics and attributed conversions keep being adjusted for a few days after the fact, so the lookback ensures recent days stay correct.
Because a key is tied to one ad account, an advertiser managing several accounts needs one Nekt source per account.
Once you’re done, click Next.

2. Select streams

Choose which data streams you want to sync. For faster extractions, select only the streams that are relevant to your analysis. You can select entire groups of streams or pick specific ones.
Tip: The stream can be found more easily by typing its name.
Select the streams and click Next.

3. Configure data streams

Customize how you want your data to appear in your catalog. Select the desired layer where the data will be placed, a folder to organize it inside the layer, a name for each table (which will effectively contain the fetched data) and the type of sync.
  • Layer: choose between the existing layers on your catalog. This is where you will find your new extracted tables as the extraction runs successfully.
  • Folder: a folder can be created inside the selected layer to group all tables being created from this new data source.
  • Table name: we suggest a name, but feel free to customize it. You have the option to add a prefix to all tables at once and make this process faster!
  • Sync Type: you can choose between INCREMENTAL and FULL_TABLE.
    • Incremental: every time the extraction happens, we’ll get only the new data - which is good if, for example, you want to keep every record ever fetched.
    • Full table: every time the extraction happens, we’ll get the current state of the data - which is good if, for example, you don’t want to have deleted data in your catalog.
Once you are done configuring, click Next.

4. Configure data source

Describe your data source for easy identification within your organization, not exceeding 140 characters. To define your Trigger, consider how often you want data to be extracted from this source. Daily is usually enough, since reporting is bucketed by day. Optionally, you can define some additional settings:
  • Configure Delta Log Retention and determine for how long we should store old states of this table as it gets updated. Read more about this resource here.
  • Determine when to execute an Additional Full Sync. This will complement the incremental data extractions, ensuring that your data is completely synchronized with your source every once in a while.
Once you are ready, click Next to finalize the setup.

5. Check your new source

You can view your new source on the Sources page. If needed, manually trigger the source extraction by clicking on the arrow button. Once executed, your data will appear in your Catalog.
For you to be able to see it on your Catalog, you need at least one successful source run.

Streams and Fields

Available streams

The table below lists every stream, its slug (the exact identifier to pass when creating the source via API) and a short description. Streams marked optional are only served to ad accounts OpenAI has enabled the corresponding feature for — when it is not enabled, the stream is skipped with a warning in the run log and the rest of the extraction continues normally.

Fields by stream

Below you’ll find all available data streams from OpenAI Ads and their corresponding fields:
The single ad account the API key is scoped to (GET /ad_account). One row, carrying the account’s currency, time zone and review state.Primary key: id
Campaigns in the ad account (GET /campaigns), with their budgets, bidding type and targeting.Primary key: id
Ad groups within each campaign (GET /ad_groups). Read one campaign at a time, so every row carries its campaign_id.Primary key: id
Individual ads within each ad group (GET /ads), with the creative flattened into columns and the review outcome.Primary key: id
Customer lists uploaded for targeting (GET /custom_audiences). Requires custom audiences to be enabled on the ad account. Match counts are returned as coarse ranges — OpenAI never exposes exact figures or member identifiers.Primary key: id
Conversion events configured for the account (GET /conversions/event_settings). Requires conversion management to be enabled on the ad account. This is the table that explains how the conversion numbers were attributed.Primary key: id
Daily delivery totals for the whole ad account.Primary key: idReplication key: start_time (incremental)
Daily delivery metrics per campaign — the main reporting table.Primary key: idReplication key: start_time (incremental)
Daily delivery metrics per ad group.Primary key: idReplication key: start_time (incremental)
Daily delivery metrics per ad, including the creative text that ran.Primary key: idReplication key: start_time (incremental)
Daily campaign metrics broken down by the user’s country. Requires segmented insights to be enabled on the ad account.Primary key: idReplication key: start_time (incremental)
Daily campaign metrics broken down by device type. Requires segmented insights to be enabled on the ad account.Primary key: idReplication key: start_time (incremental)
Daily campaign metrics broken down by catalog item, for product-feed campaigns. Requires segmented insights to be enabled on the ad account.Primary key: idReplication key: start_time (incremental)
Attributed conversions per campaign per day. Requires conversion tracking to be enabled on the ad account.Primary key: date, campaign_idReplication key: date (incremental)

Data Model

The account structure is a strict hierarchy, and every reporting row carries the ids of its ancestors, so the reporting tables join directly onto the structure tables:
For an ad to be shown, the ad, its ad group and its campaign all have to be active, and the ad has to be approved — check review_status before investigating delivery.

Implementation Notes

Daily buckets and incremental replication

All reporting streams are bucketed by day and replicate incrementally on start_time (on date for conversions). Day boundaries follow the ad account’s time zone, reported in the timezone column. Each run re-reads the number of days set in Lookback Days before the last synced day, because OpenAI restates delivery metrics for a few days after the fact and conversions keep being attributed for the length of the attribution window. Re-read rows replace the previous version rather than duplicating it.

Currency and micro amounts

Spend, cost per click and cost per thousand impressions are reported in the account currency, available in ad_account.currency_code. Budget and bid limits are returned in micros: divide by 1,000,000 to get the amount in the account currency.

Metrics on segmented streams

A segmented row carries two sets of metrics: the campaign-level group (impressions, clicks, spend, and so on) and the segment-level group (country_impressions, device_clicks, product_spend, and so on). Both are extracted because which group holds the value for the individual cell depends on the grouping order the API applies. Use the segment-prefixed columns for the breakdown itself, and the unprefixed ones for the campaign total the row belongs to.

Conversions

conversions is always equal to click_through_conversions. View-through conversions — those that follow an impression without a click, within a fixed one-day window — are reported separately in view_through_conversions and are not included in the total. They are reporting only: cost per action, bidding and billing all remain click-through based.

Nested fields

Fields with an unpredictable or repeating structure are extracted as JSON strings: campaigns.targeting, ad_groups.product_set, ad_groups.bidding_custom_audience_bid_multipliers, conversion_event_settings.sources and conversion_event_settings.campaigns. Small, stable objects are flattened into scalar columns instead, such as the campaign budget (budget_lifetime_spend_limit_micros), the ad creative (creative_title, creative_body) and review outcomes (review_status, review_reason).

Rate limits

The Advertiser API allows 600 requests per minute per endpoint and 1,200 per minute per ad account. The connector stays well within both: the four delivery reports share a single endpoint and page through up to 2,000 rows per request, so a full day of reporting at every grain costs a handful of requests. If a rate limit is ever reached, the connector waits and retries, and the run log notes that the extraction is taking longer.

Privacy

The API exposes aggregated performance only. Individual ChatGPT conversations, prompts and personal user data are not available through it. Custom audience match counts are returned as coarse ranges, and uploaded member identifiers can never be read back.