Skip to main content

Ads and pixels

OpenAI Pixel

Configure the OpenAI Pixel

Copy the pixel ID from the conversions tab in OpenAI Ads Manager. Remove the standalone OpenAI installation snippet, because the helper creates the oaiq queue and initializes the pixel itself.

npm install @c15t/integrations@alpha
src/consent-scripts.ts
import { openaiPixel } from '@c15t/integrations/openai-pixel';

export const scripts = [openaiPixel({ pixelId: 'YOUR_PIXEL_ID' })];

Register the scripts

Complete your framework quickstart first. Keep its Inth endpoint, policy, styles and consent UI. Remove the vendor's original script, SDK initializer or tag-manager entry, so the vendor loads only through c15t.

The vendor pages put the helper in src/consent-scripts.ts. If your framework quickstart already has a scripts array, such as the one in c15t.config.ts in the Next.js guide, add the helper to that array instead of creating a second file. The scripts export is a configuration, not an initializer. Add it to the c15t provider you already have, at the registration point for your framework below. These are edits to that provider, not a second provider.

Add the configuration to scripts in c15t.config.ts, next to next.config.ts:

import { defineConsentConfig } from 'c15t/next';
import { scripts } from './src/consent-scripts';

export default defineConsentConfig({ scripts });

Keep the rest of your config, such as mode and routePrefix, in the same call. ConsentRoot reads the config in the browser, so the layout keeps passing only state. App Router, Pages Router and static export all read the same file. See Next.js scripts and embeds.

Options

OptionDefaultBehavior
pixelIdRequiredPixel ID passed to oaiq('init', ...). The helper trims it. Empty or whitespace-only values log an error and the script does not load.
debugfalseLogs SDK activity, including queued and dropped events, to the browser console.
userNoneUser matching fields passed to init: email_sha256, phone_number_sha256, external_id_sha256, first_name_sha256, last_name_sha256, country, city, region and postal_code.
scriptSrchttps://bzrcdn.openai.com/sdk/oaiq.min.jsSDK URL override. A blank value falls back to the default.

c15t forwards user unchanged. Normalize and hash identifiers yourself as OpenAI's user data rules describe. If user data arrives after initialization, call window.oaiq('init', { pixelId, user }) again with the complete object.

Loading and revocation

openaiPixel uses the marketing category. Before marketing is allowed, c15t defines no oaiq function and loads nothing from OpenAI. Measurement permission alone does not load the pixel. When marketing becomes allowed, the helper queues oaiq('consent', false), init and oaiq('consent', true), then loads oaiq.min.js. The first call overrides the SDK's default consent of true.

On revocation the helper keeps the SDK and calls oaiq('consent', false). If the visitor allows marketing again before the page reloads, it calls oaiq('consent', true) without reinitializing the pixel. OpenAI drops events sent while consent is denied and does not replay them later. The SDK can still send diagnostic pings while consent is denied.

Guard your own oaiq calls

The helper sends no page view or conversion, so every event comes from your code. After revocation window.oaiq still exists, so its presence does not mean marketing is allowed. Check the permission first, then that the queue exists:

src/track-order.ts
export function trackOrder(marketingAllowed: boolean, orderId: string) {
	if (!marketingAllowed || typeof window.oaiq !== 'function') return;
	window.oaiq(
		'measure',
		'order_created',
		{ type: 'contents', amount: 2599, currency: 'USD' },
		{ event_id: orderId }
	);
}

Pass the current marketing permission from your framework, for example useConsent('marketing') in React. amount is an integer in the currency's minor unit, so 2599 is $25.99. Reuse event_id on the server event to deduplicate it.

@c15t/integrations/openai-pixel also exports openaiPixelEvent, a typed wrapper around oaiq('measure', ...). It drops calls made before the queue exists and does not check permission, so apply the same guard before calling it. A custom event needs custom_event_name in its options. To send to one pixel when you run several, call window.oaiq('measureSingle', pixelId, ...).

Verify the OpenAI Pixel

Set debug: true while you test. After you allow marketing, oaiq.min.js loads from bzrcdn.openai.com. Trigger one guarded event and check that a request to https://bzr.openai.com/v1/sdk/events succeeds and the event appears in Event Stream in Ads Manager. An accepted request confirms delivery, not attribution to a ChatGPT ad. Then revoke marketing. Until the page reloads, calling trackOrder sends nothing. Turn off debug when you finish.

If your site sets a Content Security Policy, allow https://bzrcdn.openai.com in script-src, both https://bzr.openai.com and https://bzrcdn.openai.com in connect-src, and https://bzr.openai.com in img-src.

Test in a private window with an opt-in policy. Open DevTools Network, disable the cache and filter by the vendor's domain:

  1. Load the page. No request goes to the vendor before you choose.
  2. Click Reject, then reload. There is still no vendor request.
  3. Open Privacy settings and allow the helper's category. The vendor script loads without a page reload.
  4. Turn the category off again and save. c15t reloads the page, and the new page makes no vendor request.

c15t reloads on revocation because removing a script element does not stop code that already ran. The vendor's listeners, timers and queued events stay alive until the page unloads. If you set reloadOnConsentRevoked: false, stop the vendor yourself. Register a callback-only script whose onConsentChange calls the vendor's opt-out API, as shown in custom integrations, and check the permission before each of your own event calls. The reload does not delete cookies the vendor already set; see clear on revocation for your framework.

The helper sets vendor to its script ID, so once you declare that vendor a visitor can turn it off inside an allowed category. See vendor consent for your framework. The consent verification guide covers navigation, expiry and hosting checks.