OpenAI Ads
The openai_ads connector reads ad accounts, campaigns, ad groups, ads, and performance reporting from the OpenAI Advertising API. It runs on StreamWright's declarative HTTP Transport (transport = "http").
Auth & HTTP Configuration
OpenAI Ads uses bearer token authentication. Endpoints, default cursor pagination (last_id → after), record envelope extraction (data), and exponential backoff retries are configured in source.yaml:
kind: source
name: openai_ads_demo
spec:
config:
account_ids: { type: list, items: string, description: "Ad account IDs" }
start_date: { type: date, required: false, description: "Start date for performance metrics" }
secrets:
openai_ads_key: { type: string }
auth:
provider: openai_ads
type: bearer
token: "{{ secrets.openai_ads_key }}"
http:
base_url: https://api.ads.openai.com
paginator: { type: cursor, token_path: last_id, param: after, has_more_path: has_more }
records: { path: data }
retry: { codes: [429, 500, 502, 503, 504], max_attempts: 5, backoff: exponential, max_delay: 2m }
API keys are registered as secrets at connection time and automatically redacted as *** in every log message.
Reading data
Each stream queries its corresponding REST endpoint, inheriting pagination and error recovery:
partitions:
- { name: account_id, values: "{{ config.account_ids }}" }
retry: { max_attempts: 3, max_delay: 2m }
requests:
- name: raw_campaigns
http:
path: /v1/campaigns
method: GET
params:
ad_account_id: "{{ partition.account_id }}"
limit: 500
transform:
mode: page
steps:
- name: campaigns
select: |
SELECT partition->>'account_id' AS account_id,
record->>'id' AS campaign_id,
record->>'name' AS campaign_name,
record->>'status' AS status,
(record->>'budget_micros')::BIGINT AS budget_micros,
record->>'currency' AS currency
FROM raw_campaigns
export:
campaigns:
step: campaigns
primary_key: [account_id, campaign_id]
Reference streams (examples)
The starter template (examples/sources/ads/openai_ads) includes the following reference streams:
| Stream | Description | Mode |
|---|---|---|
ad_accounts | Accessible advertiser accounts and currency | page |
campaigns | Campaign settings and budgets | page |
ad_groups | Ad groups and bidding strategies | page |
ads | Account-level ads and creative definitions | page |
ad_group_tree | Hierarchical campaigns joined with child ad groups | run |
ad_tree | Hierarchical campaigns joined with child ads | run |
campaign_performance | Daily delivery metrics (impressions, clicks, spend) per campaign | incremental |
ad_group_performance | Daily delivery metrics per ad group | incremental |
ad_performance | Daily delivery metrics per ad | incremental |
These streams are reference examples. Because streams in StreamWright are declarative, you can customize columns, adjust DuckDB queries, or add new endpoints to match your upstream reporting needs.
Shared vocabulary
openai_ads maps to the same canonical nodes as Google,
Microsoft, and Meta Ads, enabling a single cross-network pipeline across every platform.