Fix guide · WordPress · advanced · about 60 min
OpenAI Pixel event_id missing on WordPress and WooCommerce
For the finding “OpenAI events have no event ID”. Also for: Any website, Shopify, Webflow, Framer.
What this means
Each event the OpenAI Pixel (the ChatGPT Ads Measurement Pixel) sends can carry an event ID that your site sets: the event_id option in the fourth argument of oaiq("measure", ...). Your site calls measure without one.
The requests still contain an ID, which makes this confusing: without your own event_id, the pixel puts a random value in the event’s id field (OpenAI does not document this, but you can see it in the request payload). Only the visitor’s browser knows it, so your server can never send the same ID with its copy of the event.
Whether this costs you money depends on whether your site also sends events from a server through the OpenAI Conversions API. On WordPress that is common, because PixelYourSite, Pixel Manager for WooCommerce (Pro) and several smaller plugins can send server events:
- Yes, or you are not sure: OpenAI treats a browser event and a server event as the same conversion when they share the Pixel ID, the event name and the event ID. With a random browser ID they never match, so the same order or lead can be counted twice.
- No, browser pixel only: there is nothing to deduplicate yet. It matters the day you add the Conversions API.
We cannot see server-to-server traffic from a browser, so we cannot tell whether your Conversions API works. We only see whether your site passes its own event IDs to the pixel.
How to confirm it yourself
Because the pixel fills in an ID on its own, the Network tab cannot tell you whether your site sets one. Look at the calls instead.
- Search the places where code lives on your site for
oaiq("measure"(oroaiq('measure'): WPCode snippets, Elementor Pro’s Custom Code, theme files, and Custom HTML tags in Google Tag Manager (GTM). - For each call, look for a fourth argument with
event_id, as inoaiq("measure", "lead_created", { type: "customer_action" }, { event_id: "lead-8f3a2c" }). - In GTM, open the OpenAI tag and check its Event ID field. OpenAI’s template marks it as optional, to be filled when another system sends the same conversion from a server.
- If a plugin sends your events, read its documentation for how it sets event IDs, and remember that it only sets them on the events it sends.
- To see the effect, trigger a test conversion and compare the
idin the browser request (Network tab, filterbzr.openai.com) with the ID your server sends for the same action. If they differ, deduplication fails.
How to fix
OpenAI deduplicates a browser event and a server event that use the same Pixel ID, the same event name (for custom events, the same custom_event_name) and the same event ID, and keeps the first one it receives. On WordPress the simplest way to get there is to let one plugin send both.
Route 1: one plugin for browser and server events. All of these are third-party; there is no OpenAI plugin.
- PixelYourSite (free and Pro): create a Conversion Key in OpenAI Ads Manager, switch on the Conversions API in PixelYourSite’s OpenAI settings and paste the key. Its documentation says the browser pixel and the Conversions API share the same Pixel ID and event ID. Use its Validate server events option only while testing, because OpenAI checks those events without recording them.
- Pixel Manager for WooCommerce (Pro, from version 1.60.0): create an API key for your pixel in the Conversions tab of OpenAI Ads Manager and paste it into OpenAI Conversions API token under Tracking Pixels > OpenAI (Show advanced settings). SweetCode says browser and server events share one event ID.
- Measurement Pixel for OpenAI Ads: its plugin page says deduplication across pixel and server covers
page_viewedin the free version and every event in Pro. - PixelBridge: its plugin page says it uses matching event IDs for browser and server events “where supported”.
Then:
- Remove every other copy of the pixel: OpenAI’s snippet in WPCode, Elementor Custom Code or the theme, OpenAI tags in GTM, and a second tracking plugin. Their events arrive without your IDs (and usually also show up as “Duplicate OpenAI events”).
- Watch out for full-page caching. If an event ID is printed into the page’s HTML, a page cache (WP Rocket, LiteSpeed Cache, your host’s or CDN’s cache) can serve the same ID to every visitor, and OpenAI keeps only the first event with it (see “OpenAI event IDs repeat across visits”). PixelYourSite’s documentation describes this problem and its Events delivery options in PixelYourSite Pro’s Global Settings, which fetch the ID through a request the cache does not store; keep them on if you use a cache. With any plugin, check that the ID changes when you open the same page in a new private window.
Route 2: Google Tag Manager with a server container. GTM4WP can push WooCommerce events such as purchase to the data layer. Put a unique value into the Event ID field of the OpenAI web tag: the order ID from the purchase data layer for orders, or a variable such as Stape’s Unique Event ID for other events. Map the same value to the event ID in your server tag (Stape’s OpenAI Ads Events API tag has an Event ID parameter). Details are in the general guide.
Route 3: your own code. If a developer sends server events from your theme or a custom plugin, both sides must read the ID from one place. For WooCommerce orders, the order number works well. The order confirmation page is the /order-received/ endpoint of the Checkout page, and WooCommerce says to keep Checkout out of the cache, so the number is not shared between visitors. This snippet (for a child theme’s functions.php or a WPCode PHP snippet) sends the purchase from the confirmation page, which runs the woocommerce_thankyou hook in both the classic and the block checkout:
add_action( 'woocommerce_thankyou', function ( $order_id ) {
$order = wc_get_order( $order_id );
if ( ! $order ) {
return;
}
// OpenAI wants an integer in the currency's ISO 4217 minor unit:
// x1 for zero-decimal currencies such as JPY, x1000 for three-decimal
// ones such as KWD, x100 for most others (EUR, USD, GBP).
$currency = $order->get_currency();
$zero = array( 'BIF', 'CLP', 'DJF', 'GNF', 'ISK', 'JPY', 'KMF', 'KRW', 'PYG', 'RWF', 'UGX', 'UYI', 'VND', 'VUV', 'XAF', 'XOF', 'XPF' );
$three = array( 'BHD', 'IQD', 'JOD', 'KWD', 'LYD', 'OMR', 'TND' );
$factor = in_array( $currency, $zero, true ) ? 1 : ( in_array( $currency, $three, true ) ? 1000 : 100 );
$amount = (int) round( (float) $order->get_total() * $factor );
$event_id = 'order_' . $order->get_order_number();
?>
<script>
if (window.oaiq) {
oaiq(
"measure",
"order_created",
{ type: "contents", amount: <?php echo $amount; ?>, currency: "<?php echo esc_js( $order->get_currency() ); ?>" },
{ event_id: "<?php echo esc_js( $event_id ); ?>" }
);
}
</script>
<?php
} );
Your server code then sends the same order as an order_created event with id set to the same order_1234 value and the same Pixel ID. A customer who reloads the confirmation page sends the event again with the same ID, and OpenAI keeps only the first. For leads and page views, generate the ID in the browser (not in cached PHP output) and send it to your server with the form.
Common causes
- OpenAI’s snippet and
measurecalls were pasted into WPCode, Elementor or the theme without the optional fourth argument. - A plugin with the Conversions API was added later, but an older snippet or GTM tag still sends its own browser events.
- Two tracking plugins run side by side, and only one of them shares IDs with its server events.
- The event ID is printed into cached HTML, so it repeats for every visitor.
- In GTM, the OpenAI tag’s Event ID field is empty, or the server tag reads a different value.
How to verify the fix
- Every
oaiq("measure", ...)call for your key events passes anevent_id, and the value changes from one order or lead to the next and between visitors (test in two private windows). - For one test order, the
idin the browser request equals theidyour server sends. - With access to the Advertiser API, OpenAI’s recent-events endpoint (
GET /v1/conversions/events?pid=<PIXEL-ID>) lists a sample of recent events with their channel:pixel_sdkfor the browser,server_to_serverfor your server. - Re-run the check on IsPixelWorking. The issue should be gone.
Sources
- OpenAI Developers, Measurement Pixel (
measurearguments,event_id, deduplication on Pixel ID, event name andevent_id, first event wins): https://developers.openai.com/ads/measurement-pixel - OpenAI Developers, Conversions API (event
id): https://developers.openai.com/ads/conversions-api - OpenAI Developers, Supported Events (amounts as integers in the currency’s standard ISO 4217 minor unit): https://developers.openai.com/ads/supported-events
- OpenAI Developers, Conversion Tracking (Monitoring Events,
pixel_sdkandserver_to_server): https://developers.openai.com/ads/conversion-tracking - OpenAI on GitHub, Ads Measurement Pixel GTM template (Event ID field): https://github.com/openai/ads-measurement-pixel-gtm-template
- PixelYourSite, OpenAI Settings (Conversion Key, Validate server events, shared Pixel ID and event ID): https://www.pixelyoursite.com/docs/openai-settings-setup
- PixelYourSite, Meta settings (event ID and the cache problem, Events delivery): https://www.pixelyoursite.com/docs/meta-facebook-settings-setup
- SweetCode, Pixel Manager: OpenAI (Conversions API from 1.60.0, OpenAI Conversions API token): https://sweetcode.com/docs/pmw/plugin-configuration/openai
- SweetCode, OpenAI Ads tracking for WooCommerce (shared event ID): https://sweetcode.com/blog/openai-ads-tracking-woocommerce
- WordPress.org, Measurement Pixel for OpenAI Ads (deduplication:
page_viewedin Free, every event in Pro): https://wordpress.org/plugins/measurement-pixel-for-openai-ads/ - WordPress.org, PixelBridge: ChatGPT Ads Pixel Tracking (matching event IDs where supported): https://wordpress.org/plugins/pixelbridge-ads-tracking-for-openai/
- WordPress.org, GTM4WP (WooCommerce data layer events): https://wordpress.org/plugins/duracelltomi-google-tag-manager/
- Stape, Unique Event ID variable: https://stape.io/helpdesk/documentation/unique-event-id
- Stape, OpenAI Ads Events API tag (Event ID parameter): https://stape.io/helpdesk/documentation/openai-ads-events-api-tag
- WooCommerce Developer Docs, Configuring caching plugins (do not cache Cart, Checkout, My Account): https://developer.woocommerce.com/docs/best-practices/performance/configuring-caching-plugins/
- WooCommerce Developer Docs, WooCommerce endpoints (Order received is a Checkout endpoint): https://developer.woocommerce.com/docs/best-practices/urls-and-routing/woocommerce-endpoints
- WooCommerce source, classic order confirmation template (
woocommerce_thankyou): https://github.com/woocommerce/woocommerce/blob/trunk/plugins/woocommerce/templates/checkout/thankyou.php - WooCommerce source, block Order Confirmation, Additional Information block (
woocommerce_thankyou): https://github.com/woocommerce/woocommerce/blob/trunk/plugins/woocommerce/src/Blocks/BlockTypes/OrderConfirmation/AdditionalInformation.php - WooCommerce Code Reference,
WC_Order(get_order_number,get_total,get_currency): https://woocommerce.github.io/code-reference/classes/WC-Order.html
More OpenAI guides
- OpenAI Pixel fires before cookie consent on WordPress
- OpenAI Pixel not firing after cookie consent on WordPress
- Repeated OpenAI event IDs drop ChatGPT Ads conversions
- Duplicate OpenAI Pixel events on WordPress and WooCommerce
- ChatGPT Ads click ID (oppref) lost on WordPress
- OpenAI Pixel tracks a button on desktop but not on mobile
- Two OpenAI Pixel IDs on one site: when it's fine, how to fix
- OpenAI Conversions API deduplication: match the pixel event_id
- OpenAI Ads Pixel setup: install the ChatGPT Measurement Pixel
- How to set up the OpenAI Conversions API for ChatGPT Ads