The JavaScript Measurement Pixel
Chapter 08 — The JavaScript Measurement Pixel
The JavaScript Pixel is the browser-side SDK that fires website conversion events after a user clicks an ad in ChatGPT.
Install snippet
The pixel must be added to the <head> of every page that should report conversions, ideally near the top so early conversions are not lost while other content loads.
<script>
(function (w, d, s, u) {
if (w.oaiq) return;
var q = function () { q.q.push(arguments); };
q.q = [];
w.oaiq = q;
var js = d.createElement(s);
js.async = true;
js.src = u;
var f = d.getElementsByTagName(s)[0];
f.parentNode.insertBefore(js, f);
})(window, document, "script", "https://bzrcdn.openai.com/sdk/oaiq.min.js");
oaiq("init", {
pixelId: "<YOUR-PIXEL-ID>",
});
</script> pixelId is required. Provision one from the Conversions tab of Ads Manager. debug: true is optional and writes SDK activity to the browser console during testing.
Sending events
oaiq("measure", eventName, eventProps, eventOptions); | Argument | Required | Description |
|---|---|---|
eventName | Yes | A standard event name (Chapter 10) or custom. |
eventProps | No | Event data. Always send type and any optional fields explicitly. |
eventOptions | No | Delivery options, including event_id for deduplication and custom_event_name for custom events. |
custom_event_name and event_id go in eventOptions, never in eventProps. This trips up almost everyone the first time.
What the SDK handles automatically
- Captures
oppreffrom the landing-page URL — OpenAI’s privacy-preserving identifier. - Stores
opprefin a first-party__opprefcookie so later page views can reuse it. - Adds the current page origin as
source_urlon every event. - Timestamps each event.
- Batches closely grouped
measurecalls.
You do not configure any of this manually. The SDK does it.
Operational rules
- Use integers for
amountandquantity. No strings, no floats. - Use only documented fields inside
contents[](Chapter 11). - Always run the pixel from the browser. Never call the server-side Conversions API directly from page code — it will leak your API key.
Example: order conversion (Shopify)
oaiq("measure", "order_created", {
type: "contents",
amount: 2599,
currency: "USD",
contents: [
{
id: "sku_123",
name: "Starter bundle",
content_type: "product",
quantity: 1
}
]
}, {
event_id: "order_12345"
}); amount: 2599 means $25.99 in a USD account — integers in the lowest currency denomination, always.
Pixel-only is fine, dual-shipping is better
The pixel by itself produces usable attribution. OpenAI’s own recommendation is to dual-ship pixel + Conversions API for resilience: pixel events are vulnerable to ad-blockers, network drops, and JavaScript errors; server-side events are not. Chapter 9 covers the server side, Chapter 12 covers how to deduplicate when running both.