OpenAI Ads is new, thin, and a little fiddly. Conversion tracking is where most people get stuck. Here is the exact process that cleared the “no recent conversion events” warning for me, step by step.
Why ChatGPT Ads conversion tracking trips people up
Performance marketers have been waiting for ChatGPT Ads, or OpenAI Ads, for some time now. It sat in talks and speculation for a long while, and it finally arrived in May. These are still early days. It still looks pretty thin and nascent to anyone who has been running Google Ads, LinkedIn Ads, or Meta Ads for a few years.
Setting up campaigns, ad groups, and ads is fairly straightforward, apart from the context hints (that’s a topic for another day). Where a lot of people get stuck is conversion tracking. OpenAI does provide a step-by-step process for it, and even with that, I had my own share of struggles.
I tried a few things. I tried the events stream. There is a “start polling” option that did nothing for me. The warning stayed put, telling me no events were set up, and at one point flagging two events with parameters that didn’t match. I know several people who have hit this exact wall, so let me put down the process that finally worked. There may be other ways that work for you, but this is definitely one of them.
Two steps, nothing exotic
Setting up conversions has two parts: setting up the data source, and then setting up the conversion event. There’s nothing new here conceptually. It is the same shape as any CPC platform you’ve used before. Honestly, the data source part is quite uneventful. The conversion event is where the friction lives.
Step 1: Set up the data source (the base pixel)
In Ads Manager, go to Tools → Conversions. There’s a Create button. Click it and create a data source. OpenAI gives you a snippet that needs to sit in the <head> section of every page (or every landing page) of your site. You can do this a few different ways. I used Google Tag Manager.
Here’s how I set it up in GTM:
- Create a new tag. I named mine
openai_ads_setup_code. - Tag type: Custom HTML.
- Paste the base code and add your Pixel ID.
- Set the trigger to Initialization – All Pages.
- Run a Preview. At page load, the tag should show as fired.
- Submit and save.
The base pixel looks like this (swap in your own Pixel ID):
<script>
!function(w,d,s,u){if(w.oaiq)return;var q=function(){q.q.push(arguments)};q.q=[];w.oaiq=q;var j=d.createElement(s);j.async=1;j.src=u;var f=d.getElementsByTagName(s)[0];f.parentNode.insertBefore(j,f)}(window,document,"script","https://bzrcdn.openai.com/sdk/oaiq.min.js");
oaiq("init",{pixelId:"YOUR-PIXEL-ID"});
</script>
If the tag isn’t firing, cross-check three things: the Pixel ID, the code itself, and (most commonly the culprit) whether you’ve set the trigger to Initialization – All Pages rather than a normal page-view trigger.
Step 2: Set up the conversion event
There are multiple event types you can set up: registration completed, lead created, app installed, app opened, and plenty more. I went with lead created.
In my case, the flow is simple. The user sees the ad in ChatGPT, clicks it, and lands on a landing page. On that page there’s a short form: they drop in their email and submit. In GTM, I already had an event set up for a successful form submission, so I had the trigger side covered.
OpenAI provides a script you can add as a Custom HTML tag in GTM, and in theory you set the right trigger for a successful form submit and it should just work. For me, it didn’t. That’s where the newer Codex route came in.
The Codex route that unblocked me
There’s an option that recently showed up in Ads Manager where you can create the conversion event using ChatGPT Codex. Here’s how that played out:
- Click the “set up with Codex” option in Ads Manager.
- If you don’t have Codex installed, install it. It adds a plugin called
openai-ads-conversions. - Tell Codex your constraints. I told it plainly: I don’t have access to the website, the server side, or any code, but I can implement through Google Tag Manager, so give me steps accordingly.
- Codex then handed me GTM-specific steps and a code snippet to add as a Custom HTML tag.
- I also gave Codex the base code I’d already implemented, so it had the full picture.
The three things Codex caught that mattered
A few details from Codex made the difference between a tag that fires and a conversion that actually registers:
- The
debug: trueflag. The script I’d copied from Ads Manager haddebug: truein it. Codex confirmed that’s fine for testing and told me to keep it while validating in GTM Preview and the browser console, then remove it before pushing to production. - The two parameters that have to match. In the conversion event code there’s a parameter under
oaiqwith a main value and atype. Those two are critical and they have to match what you configured. This is exactly the “parameters that didn’t match” warning I kept seeing. - Load order. Codex made sure the base code loads before the conversion event code. My original line only worked if
oaiqwas already available at that exact moment. So it added awindow.oaiq &&guard to prevent an error if the lead event fired before the base pixel had initialised. It shouldn’t normally happen, but I added it anyway. Codex also suggested tag sequencing, which I didn’t end up implementing.
The lead event tag ended up looking like this:
<script>
window.oaiq && oaiq("measure", "lead_created", {
type: "customer_action"
});
</script>
The trigger is the successful form submission event you already have in GTM. In my setup the tags line up like this:
openai_ads_setup_code– trigger: Initialization / All Pages.OpenAI_ads_Leads(thelead_createdevent) – trigger: successful form submit only.
Validation: four layers of checks
This is the part I wouldn’t skip past too quickly if I were you, so slow down here. There are multiple layers of checks and each one matters.
- GTM Preview. Both tags should fire: the base code at page load, and the conversion event on form submit.
- Browser Network tab. Filter for
openai,bzr, oroaiq. Confirm the SDK loads frombzrcdn.openai.com. - Live landing page test. Go to the actual published landing page and submit a test lead. In the Network tab, confirm the request fires again to
bzr.openai.com/v1/sdk/events. - Inspect the payload. Click the request and open the payload. It should contain the exact lead type you selected. In my case that was
"type": "lead_created".
A healthy request payload looks like this:
[
{
"type": "lead_created",
"timestamp_ms": 1782541528292,
"id": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"source_url": "https://your-landing-page.com/lp/example",
"data": {
"type": "customer_action"
}
}
]
The thing that actually fixed it
Here’s the honest bit. Initially the payload wasn’t coming through, and that’s why everything was silently failing. The tags fired, the SDK loaded, and still nothing registered. What broke the logjam was going back and removing debug: true, doing a hard refresh, filling out the form again, and re-checking. That’s when I finally saw the payload carrying "type": "lead_created".
Then I waited. The “no recent conversion events” warning references the last 24 complete UTC hours, so it doesn’t clear instantly. A couple of hours after my live test, the warning on the Ads Manager conversions tab was gone, and conversion events started showing up in the OpenAI Ads Manager Conversions tab.
If you’re stuck at the same warning, the sequence that worked for me was: valid base pixel on all pages, a matching conversion event on the real submit, remove debug: true, hard refresh, confirm the payload on a live submission, then give it time to process. That was it.