OpenAI Ads conversion tracking: the pixel, browser events and the Conversions API
Conversion tracking is what turns ads in ChatGPT from a reach buy into a performance channel. Without it there is no cost per order, no return on ad spend and no conversion-optimised bidding. The setup has three parts: a pixel, browser events with an event id, and the same events sent again from your server. This guide walks through each, using the exact names OpenAI uses.
What are the pieces?
A pixel is a conversion source with an id such as KvdtBLEZ9JbvBYn5nfySRD, created in Ads Manager under Conversions or through the API. A conversion event setting names the event that counts for reporting and bidding, for example order_created with a 30-day click window, and links it to the pixel. A Conversions API key lets your server send events to the same pixel. Campaigns then reference the event setting.
Pixel management and Conversions API keys are enabled per ad account. If the Conversions tab is missing in your Ads Manager, or the API answers 404 on the conversions endpoints, the account has not been enabled yet and your OpenAI representative has to switch it on.
Step 1: create the pixel and the conversion event
In Ads Manager open Conversions, create a pixel (client type web) and note the pixel id. Then create a conversion event: pick the standard event that matches the outcome you pay for, choose the attribution window (OpenAI's examples use 30 days) and select the pixel as its source. Attach the event setting to every campaign that should report or optimise on it.
Shops use order_created. Service businesses use lead_created, appointment_scheduled or registration_completed. Subscription products use subscription_created or trial_started. Custom events are allowed for reporting, but only a standard event can be the goal of a conversion-optimised campaign.
Step 2: install the pixel
Add the snippet below to the head of every page, with your own pixel id. It loads the SDK from bzrcdn.openai.com and initialises the pixel. Ads Manager gives you the same snippet in a compressed form; both work.
<script>
window.oaiq = window.oaiq || function () {
(window.oaiq.q = window.oaiq.q || []).push(arguments);
};
oaiq("init", { pixelId: "YOUR-PIXEL-ID" });
</script>
<script async src="https://bzrcdn.openai.com/sdk/oaiq.min.js"></script>
If your site sets a Content Security Policy, allow https://bzrcdn.openai.com in script-src, and https://bzr.openai.com plus https://bzrcdn.openai.com in connect-src. For a site that asks for consent first, call oaiq("consent", false) before init and oaiq("consent", true) once the visitor agrees.
The pixel also reads the oppref parameter that ChatGPT appends to your landing page URL after an ad click, keeps it in a first-party cookie, and attaches it to every event. That is how a conversion is tied back to the ad.
Step 3: fire browser events
Call oaiq("measure", ...) when the outcome happens. Always pass an event_id that your server also knows, such as the order number: OpenAI deduplicates on pixel id, event name and event id, so the browser and the server can both report the same conversion without double counting.
oaiq("measure", "order_created", {
type: "contents",
amount: 12999,
currency: "EUR",
contents: [{ id: "sku_123", name: "Starter bundle", content_type: "product", quantity: 1 }]
}, {
event_id: "order_12345"
});
oaiq("measure", "lead_created", { type: "customer_action" }, { event_id: "lead_9876" });
Amounts are integers in the smallest currency unit, so 129.99 euro is 12999. The type inside the data must match the event: contents for page, product, cart, checkout and order events, customer_action for leads, registrations and appointments, plan_enrollment for subscriptions and trials, and custom for custom events.
Step 4: send the same events from your server
Create a Conversions API key in Ads Manager (or through the API) and keep it on your server; it never goes into page code. Then post events to https://bzr.openai.com/v1/events?pid=YOUR-PIXEL-ID with the key as a bearer token. One request carries up to 1,000 events, and a request with validate_only set to true checks the payload without recording anything.
curl -X POST "https://bzr.openai.com/v1/events?pid=YOUR-PIXEL-ID" \
-H "Authorization: Bearer YOUR-CONVERSIONS-API-KEY" \
-H "Content-Type: application/json" \
--data '{
"validate_only": false,
"events": [{
"id": "order_12345",
"type": "order_created",
"timestamp_ms": 1789459200000,
"oppref": "the value stored from the landing page",
"source_url": "https://shop.example.com/checkout/confirmation",
"action_source": "web",
"user": { "emails_sha256": ["sha-256 of the trimmed, lowercased email"], "countries": ["NL"] },
"data": { "type": "contents", "amount": 12999, "currency": "EUR" }
}]
}'
Personal data is hashed before it leaves your server: SHA-256 as lowercase hex, after normalisation. Emails are trimmed and lowercased. Phone numbers keep the country code and drop spaces, punctuation, the plus sign and leading zeros. Names are lowercased with whitespace and punctuation removed. Country, city, region and postal code are sent as they are. The event timestamp must be within the last seven days. The click identifier goes in oppref at event level; if you also read the pixel's __obref cookie in the browser, pass it unchanged as user.obref.
Step 5: check that events arrive
Ads Manager shows recent events per pixel, and the API exposes a sample of the last fifty. Look for two channels: pixel_sdk for browser events and server_to_server for API events. If you see only one channel, the other side is not wired up. If you see both with the same event ids, deduplication is working.
Conversions appear in reports after about a day. Cost per acquisition, post-click conversion rate and attributed sales are computed from the events matched inside the attribution window. View-through conversions, when enabled for an account, use a fixed one-day window and are reported separately.
How does Adsonomy do this for you?
Adsonomy creates the pixel, the event settings and the Conversions API key on your ad account when the account allows it, or takes the ids you paste from Ads Manager. It generates the install code for a plain site, Google Tag Manager, Shopify, WooCommerce and BigCommerce. For a connected shop it turns synced orders into server-side order_created events with the order number as the event id, hashes the customer fields and sends them in batches. A small inbound API takes leads and orders from your own backend. The Conversions page shows every event sent, accepted or rejected, and pulls the platform's samples to confirm the pixel is alive.
Once events flow, cost per order and return on ad spend become signals for rules and for the AI manager, and campaigns can move to conversion-optimised bidding where the account supports it.
Frequently asked questions
Do I need both the pixel and the Conversions API?
No, but you want both. The pixel is the quick start and captures the click identifier for you. The server call is more reliable because ad blockers and closed tabs do not affect it. When both send the same event with the same event id, OpenAI counts it once.
Where does the click identifier come from?
ChatGPT appends an oppref parameter to your landing page URL when someone clicks an ad. The pixel stores it in a first-party cookie named __oppref and attaches it to browser events. For server events you pass it yourself in the oppref field, so store it with the order or lead when the visit lands.
Which events can a campaign optimise on?
Only standard events: order_created, lead_created, registration_completed, appointment_scheduled, subscription_created, trial_started, checkout_started, items_added, contents_viewed, page_viewed and the app events. Custom events are reported but cannot be an optimisation goal.
What about consent in the EU?
The pixel accepts a consent call. Initialise it with consent set to false, then set it to true after the visitor accepts measurement. Events fired while consent is false are not sent and are not replayed. On the server side, stop sending the browser reference once consent is revoked.
Adsonomy runs ads inside ChatGPT for shops and service businesses. Control edition: you run it with rules. Autopilot: the AI manager runs it inside your guardrails. Launching 1 October 2026.
Join the waitlist