ChatGPT Ads
Use the ChatGPT Ads connector to sync ad account configuration, campaign hierarchy, product feeds, custom audiences, and daily performance insights (including segmented breakdowns by country, device, and platform) into your Athena lakehouse. This is a Blotout custom connector built on the Airbyte Connector Builder (declarative manifest).
Prerequisites
Section titled “Prerequisites”- A tag with Blotout Cloud set up (green checkmark in the Tags table)
- A ChatGPT Ads API key — created in Ads Manager under account settings
- The ad account must be active with at least one campaign
Create the pipeline
Section titled “Create the pipeline”Follow the shared Create a pipeline steps until the source catalogue appears, then select ChatGPT Ads.
Source configuration
Section titled “Source configuration”On the Source step, configure the connector:
| Field | Purpose |
|---|---|
| Schedule Type | How the pipeline runs — typically Scheduled |
| Sync Frequency | How often Airbyte syncs (for example, Every 24 hours) |
| Source Name | Name for this pipeline — used in the Athena schema <SOURCE_NAME>_<ENV> |
Authentication (Bearer Token)
Section titled “Authentication (Bearer Token)”Every request carries Authorization: Bearer <key>.
Configuration fields
Section titled “Configuration fields”| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| api_key | secret string | Yes | — | ChatGPT Ads API key. One key = one ad account. |
| start_date | string | Yes | — | Earliest date for insights (YYYY-MM-DD), read in the ad account’s timezone. Retention: 365 days for delivery, ~30 days for product reporting. |
| end_date | string | No | Today | Set only for a bounded backfill. |
| lookback_days | integer | No | 7 | Rewind before the stored cursor. Spend and attribution are not settled on the day they happen. |
| include_conversion_metrics | boolean | No | true | Adds conversion/revenue fields to entity-level insights. Turn off if a 400 names a conversion field. |
| page_size | integer | No | 500 | List endpoints; API max 500. |
| insights_page_size | integer | No | 1000 | Insights endpoints; API max 2000. |
| base_url | string | No | https://api.ads.openai.com/v1 | Override only for a dedicated host. Keep the /v1. |
Supported sync modes
Section titled “Supported sync modes”- Full Refresh (10 dimension streams)
- Incremental Sync — Append, cursor
date(8 metric streams)
Supported streams
Section titled “Supported streams”Dimension streams (Full Refresh)
Section titled “Dimension streams (Full Refresh)”| Stream | Endpoint | Primary Key | Notes |
|---|---|---|---|
ad_account | GET /ad_account | id | Single row. The check stream. Carries timezone and currency_code. |
campaigns | GET /campaigns | id | Budgets in micros, times as unix integers. |
ad_groups | GET /ad_groups?campaign_id= | id | Substream over campaigns. campaign_id added by connector. |
ads | GET /ads?ad_group_id= | id | Substream over ad groups. ad_group_id added by connector. |
product_feeds | GET /feeds | feed_id | Catalogue health with product_count. |
product_feed_uploads | GET /feeds/uploads | upload_id | rows_accepted / rows_rejected / rows_ads_eligible + diagnostics. |
custom_audiences | GET /custom_audiences | id | Match counts are range strings, not numbers. |
spend_limit_windows | GET /ad_account/spend_limit_windows | window_id | Budget pacing: amount_micros vs spent_micros. |
conversion_event_settings | GET /conversions/event_settings | id | Attribution window — may require enablement. |
conversion_pixels | GET /conversions/pixels | id | May require enablement — 404 is a provisioning state. |
Metric streams (Incremental — cursor date)
Section titled “Metric streams (Incremental — cursor date)”All eight hit GET /ad_account/insights with different aggregation_level and segments[] values.
| Stream | Aggregation | Segments | Primary Key |
|---|---|---|---|
insights_account_daily | ad_account | — | date |
insights_campaign_daily | campaign | — | date, campaign_id |
insights_ad_group_daily | ad_group | — | date, ad_group_id |
insights_ad_daily | ad | — | date, ad_id |
insights_campaign_by_country | campaign | country | date, campaign_id, country_name |
insights_campaign_by_device | campaign | device | date, campaign_id, device_type |
insights_campaign_by_platform | campaign | platform | date, campaign_id, platform |
insights_product_daily | campaign | product | date, campaign_id, product_feed_id, item_id |
Key details
Section titled “Key details”Hierarchy is not in the payload — ad_groups has no campaign_id in the API response; ads has no ad_group_id. The connector partitions over parent streams and stamps the parent ID onto each record. These fields are added by the connector, not the API.
Insights project nothing unless asked — omitting fields[] returns only impressions. Every insights stream sends an explicit field list.
Money: micros vs plain — *_micros on campaigns/ad groups/spend limits are millionths of the account currency. Insights spend is already a plain number. Do not divide both by 1e6.
Ratios do not re-aggregate — ctr, cpc, cpm, cpa, post_click_cvr, order_created_roas are computed by the API over its row grain. Recompute from base measures in dbt.
Downstream notes
Section titled “Downstream notes”- Schema:
chatgpt_ads_<client>_prod.* - Deduplication for insights streams:
SELECT * FROM ( SELECT *, ROW_NUMBER() OVER ( PARTITION BY date, campaign_id ORDER BY _airbyte_extracted_at DESC ) AS rn FROM chatgpt_ads_<client>_prod.insights_campaign_daily) WHERE rn = 1Changelog
Section titled “Changelog”| Version | Date | Description |
|---|---|---|
| 1.0.0 | 2026-09 | Initial release with 18 streams: 10 dimension (Full Refresh) + 8 metric (Incremental Append) |
Complete Schema and Summary
Section titled “Complete Schema and Summary”Continue through the Schema and Summary steps to choose streams and confirm the connection. Save and run the first sync.
After a successful sync, Airflow creates an organization-scoped DAG for the pipeline, and dbt models feed downstream analytics.
Related documentation
Section titled “Related documentation”- Data Pipelines overview — Tags-first create flow