OpenAI Ads source coverage
Source-first discovery started 2026-11-05 before choosing controls. Scope: Ads Manager, account access, Ads API and OAuth integrations, conversion measurement, audience/feed data, audit and account spending controls. Ads has a distinct ad-account control plane, not an API Platform project. Baseline: no Ads guide or pack directory. Common identity/ownership evidence is coordinated with the OpenAI family ledger.
No tenants declared — Tier 0+1 only. Public source fetches and offline fixtures only; no credentials or live product requests/settings. Retrieval bodies and URL/time/status/SHA-256 are retained in the private API/Ads source cache. No live-validation or human-review status will be claimed.
Initial source-derived candidates
Read the full Ads index and follow its combined reference, not API Platform headings.
| Candidate and current official source | Plane and security behavior to reconcile | Initial disposition |
|---|---|---|
| Ads identity/access, SSO | Tenant global admin/Ads admin/account roles, group union, SSO/SCIM/offboarding | Read setup paths, propagation/session caveats and recovery before selecting controls |
| Authentication, partner setup | Account-scoped bearer key and client-account verification; OAuth mentioned by other endpoint references | Follow OAuth and key ownership/revocation evidence; separate from model API keys |
| Account management, account reference | Account pause, brand-review integrity, permission-gated daily/date-range spend limits and revision concurrency | Candidate integrity/financial abuse controls; read versus enforcement distinct |
| Audit logs | API-key-only audit read, actual audit_log_type, paging IDs/filters |
Candidate safe paginated export; no assumption that OAuth audit works |
| Conversions, pixel, image tag, setup | Server-only conversion keys, browser identifiers, consent/matching/PII/data boundaries and debugging | Read all authentication and privacy sections; no key creation or event transmission |
| Custom audiences, feeds, delta feeds, uploads, bulk operations | Customer-list hashes, data minimization, hosted feed credentials, cross-account references, asynchronous lifecycle | Follow operator-owned data sources, OAuth scopes, mutation/cancellation semantics and cleanup evidence |
| Combined docs, official API/provider/CLI indexes | Full automation census: Terraform, REST/GraphQL, CLI, SDK, native config/client/MDM, SIEM | Completed in the six-surface census below; supported interfaces and unverified contracts remain separate |
Retrieval record
All checks dated 2026-11-05. 34 successful direct developer-document fetches: every one of the 32 Markdown pages in the official Ads index, its combined export, and openapi.json. The index itself was fetched by the parent lane. Bodies/time/status/SHA-256 are in the private .hth-validation/openai-api-sources/ cache. The OpenAPI contract reports 2.3.0, 73 paths, 88 operations, two authentication schemes and one webhook. These are inventory counts, not a completeness score.
Direct HTTP fetches to five Help Center pages returned anti-bot 403 responses. Successful official-page web.open retrievals supplied the actual text; the 403s are not absence findings. The guide cites 12 successfully opened Help Center pages: Ads beta overview, Ads identity/access, SSO setup, tenant administration, Ads Manager plugin, HubSpot, GA4, Shopify, measurement partners, mobile partners, UI product feeds and Sponsored Agents. Additional account-setup/troubleshooting/conversion-measurement pages were investigated without originating separate claims. Public direct retrieval and successful fallback are distinct methods.
Final source reconciliation
| Candidate | Evidence and material observation | Final disposition |
|---|---|---|
| Ads identity / effective roles | Identity, SSO: tenant global admin, tenant Ads admin and ad-account roles differ; highest direct/group role wins; one effective admin remains; synchronized account group starts Member | 1.1 exact account/tenant paths, group/offboarding review and common identity link. Required-policy existing-session caveat explicit. Tenant SCIM membership does not itself authorize an advertiser. Ads-specific provisioning/role-write API remains unverified, not absent. |
| Keys and OAuth | Auth, partner setup, OpenAPI: account key, separate conversion credential; OAuth read/write/refresh/identity scopes and /me opaque application identity |
1.2 account-bound GET fails on mismatch and omits identifying labels. Registered-client OAuth library/review recommended. Ads client registration, refresh rotation and revocation details unverified; no guessed OAuth exchange or credential creation. |
| Account limits and lifecycle | Account reference, management, changelog: current daily caps since September 2026, invoice eligibility, billing permission, micros, revision conflicts/503 ambiguity, delayed stop | 2.1 native read plus exact daily-edit payload emitter; interruption/recovery/activation/brand-review checks. Emitters do not enforce settings. Irreversible archive distinguished from pause. |
| External app approval and AI-assisted writes | Tenant administration, HubSpot, plugin: global approval separate from member consent; HubSpot Ads off by default for Business/Enterprise; exact-action confirmation/read-back; recurring reviews recommendation-only | 2.2 manual documented paths and review records. Ads-specific policy write contract remains unverified; API campaign writes are not substituted. |
| Browser Pixel / image tag / multiple recipients | Pixel, image tag, multiple pixels: consent default true, explicit denial before init, AAM source detection, browser hashes, CSP host/nonce contract, cookie deletion versus retained server data | 3.1 official Pixel queue integration denies before init, wires grant/withdraw. Native command-order fixture; actual browser/network/cookie behavior not live-tested. Image tags and each recipient require separate review. |
| CAPI / source identity / event lifecycle | Conversions, setup, events: server-only key, Web Pixel ID, 1,000 max all-or-nothing batch, validation mode, dedup ID/Pixel pair, integration_source is not auth | 3.2 minimum approved signals and supported normalization; draft-first validation pack forces validate_only:true; explicit --send still transfers data. No production event sent. Full application event-schema validation remains application-owned. |
| Audience data and mutations | Audiences, upload, targeting: first-party rights, no broker lists, normalization, EEA/Swiss restrictions, async Add/Remove/Replace/Merge/recovery/revision/idempotency, independent merged copies | 3.3 ASCII email→native hashed CSV emitter and operation/offboarding guidance. Phone contract difference explicit. Accepted/ready states do not prove completed replacement; no raw member outcomes invented. |
| Product/hotel feed ingestion and deletion | Feeds, delta, hotel beta, UI imports: SSH/password replacement, SFTP pause versus ad delivery, eligible full refresh deletes missing products, dependent archive, public URL/source boundaries | 3.4 native feed/access assessment suppresses URI/credentials; per-source access and lifecycle guidance. Prose is_full_refresh field absent in current OpenAPI settings schema, so missing values remain unknown and feature eligibility must be checked. No speculative write using incomplete schema. |
| Connected sources | GA4, Shopify, HubSpot, measurement, mobile: account/property/Pixel/event permissions and disconnect do not delete historical reports/accounts/campaigns | 3.5 exact documented connection/disconnect paths, consent/retention/revocation checklist. Partner-native APIs, data retention and key rotation not inferred; need each processor’s supported contract. |
| Audit export | Audit: Ads key only, OAuth rejected, audit_log_type, last_id, actor filter, timestamp range, no total_count |
4.1 GET JSONL export follows native cursors and fails nonzero on incomplete collection; experimental Sigma uses documented update_campaign. No invented role-change event or API Platform schema. |
| Lead subscriptions and signed callbacks | OpenAPI: create/list/get/delete; HTTPS destination/signing secret/idempotency; OpenAI-Subscription-Id, Standard Webhooks v1 raw HMAC-SHA256/freshness; signed subscription body and synthetic flag |
4.2 read assessment plus official SDK signature receiver with candidate registry, signed account binding, schema-validator adapter, synthetic isolation and durable enqueue contract. List refuses unexplained has_more:true because spec has no cursor input. No subscription/key created. |
| Marketing/performance/limited product surfaces | Full 32-page index plus Sponsored Agents: reporting, bidding/targets/creative formats are not inherently security settings; Sponsored Agents selected-advertiser alpha with no public hardening contract established | Account/resource permission, approval and integrity guidance applies to indexed campaigns/adgroups/ads/bulk/insights/feeds. Campaign optimization and provider review decisions excluded under PHILOSOPHY scope. Sponsored Agent configuration retained as availability/research limitation rather than fabricated stub. |
Six-surface census and implementation choices
| Surface | Evidence status and lifecycle | Write versus verification |
|---|---|---|
| Terraform | Official API provider 1.5.0 full resource AND data-source lists fetched/installed: 30 resources, 49 data sources, none Ads account resources/data sources in that inventory | No fabricated Ads provider. This is a bounded current-provider observation. Native Ads account API is separate. |
| REST / GraphQL | Available current Ads OpenAPI: 73 paths/88 operations, bearer account key and AdsOAuth schemes, lead callback; public docs use same host | Six executable REST packs assess account/spend/feed/audit/subscriptions and draft/send conversion validation. No tenant mutation. No GraphQL contract in the fetched index/spec; no universal absence claim. Unknown tenant identity/partner-control APIs are explicit. |
| CLI | Repository inventory and current official OpenAI CLI README checked; its API admin namespace is API Platform, not Ads | No verified Ads-specific first-party CLI handle, so no invented openai ads pack. Parent maintains CLI inventory/disposition. No separate Ads daemon/client/MDM contract advertised in inspected indexes; this is a scoped discovery limit. |
| SDK | Official Measurement Pixel oaiq browser commands; actual OpenAI SDK 7.51.0 Standard Webhooks verifier. No Ads account-management namespace verified in SDK inventory |
Pixel integration plus lead receiver. Pixel fixture tests queue order, not the remote/browser SDK’s network behavior. Lead tests exercise actual SDK HMAC verification, not a stub. No speculative Ads SDK method. |
| Native config | Documented Ads daily-limit request and audience CSV file | Two native emitters, no account write/upload. No generic hardening YAML, fake policy toggles, MDM or SQL table. |
| SIEM | Available Ads audit JSONL with documented update_campaign example |
Protected export and experimental Sigma. Field mapping/ingestion/alerts remain untested in a real sink. |
Verified findings
All are omissions from the prior family baseline; Ads is a new substantive product guide.
| Type | Title / guidance | Verified URL | Target |
|---|---|---|---|
| OMISSION | Distinct effective Ads roles and session caveat require account-specific testing | Identity | 1.1 |
| OMISSION | Scoped keys/OAuth and organization app approval are different boundaries | OpenAPI, HubSpot | 1.2/2.2 |
| OMISSION | Conditional current daily spending limits use micros and revision concurrency | Account reference | 2.1 |
| OMISSION | Pixel consent defaults true; AAM/CAPI/partners need explicit disclosure review | Pixel, CAPI | 3.1–3.2/3.5 |
| OMISSION | Audience replacement/merge and feed refresh have separate asynchronous/deletion effects | Audiences, feeds | 3.3–3.4 |
| OMISSION | Disconnecting sources does not attest to deletion | GA4, Shopify | 3.5 |
| OMISSION | Audit and lead callback contracts differ from generic organization activity | Audit, OpenAPI | 4.1–4.2 |
Checks, remaining gaps and handoff
- PASS:
bun test scripts/test-openai-ads-refresh.test.ts: 12 tests, 91 assertions. Real SDK signatures plus loopback-only fixtures cover wrong accounts; native cursor/filter/HTTP/schema failures; micros/revision emission; forced validation mode; audience normalization; omission of connection/secret fields; incomplete subscription lists; Pixel ordering; callback tamper/freshness/registry/account/schema rejection; synthetic probes and durable retries. Transport checks prove no partial late-page export, fixed destinations/explicit loopback, control-character key refusal, stdin credential escaping, private CAPI request files, curlrc suppression, sanitized failures and body-size limits. The mock reads bodies only for POST; cloning empty GET streams had caused test-only timeouts and was removed before the successful complete rerun. - PASS: Bash syntax for every new API/config script; zero guide fences; 11 parsed controls with Description/Rationale/Why This Matters and no empty parser cells. Parent owns generated-pack synchronization and browser/render validation; no shared metadata/Git operations by this child.
- PASS:
bun install --cwd packs/openai-ads/sdk --frozen-lockfile --ignore-scripts. Its manifest/lock pin officialopenai@7.51.0; the receiver and tests resolve this local SDK directly, without an ambient root dependency. No root manifest/lockfile changes. - VERIFIED-LIVE: 0. Console paths, account feature/billing eligibility, real SSO/SCIM propagation, browser/network/cookie behavior, partner retention, deployed callback schema/queue adapters and SIEM ingestion remain DRIFT-CHECKED-ONLY. No live-validation marks or maturity promotion.
- Unverified interfaces: Ads client registration/refresh/revocation detail; tenant Ads identity/external-policy automation; partner-native APIs; unexplained lead-list pagination; Sponsored Agent settings. Missing precondition: current supported product/partner contract and, for enforcement tests, an authorized eligible tenant. These are not labeled feature absence.
- No external product-specific CIS/STIG/SCuBA identifiers or vulnerability claims originated. First-party documented security controls supplied the material omissions; no third-party source admission needed. Unresearched external baselines remain unasserted.
Authored corpus: 11 leveled controls, eight includes covering eight controls, 11 rendered artifacts across API/config/SDK/Sigma plus a shared GET helper. Counts describe authored corpus, not proof that every future feature is discoverable or available.
Dependency-only SDK manifest and Bun lockfile are excluded from pack counts.