Log in / Create free account🌐 ES☀️

Advanced training · Module 17 — ChatGPT Ads in depth — context hints, measurement, bidding and automation

Advanced measurement in ChatGPT Ads: Conversions API, deduplication and the data type of each event

⏱️ 7 min read · 🤖 ChatGPT Ads 📐 Measurement · updated on 2026-09-16

The ChatGPT Ads pixel is the short route to measurement, and on many websites it's enough. But it goes blind in a very common case: a conversion that doesn't finish on the page where it's installed.

It happened to us: our sign-up is completed in the client dashboard, not on the website, so we send it from the server. This is what we learnt, traps included. No pixel yet? Start with lesson 3 of module 12 (Intermediate).

When the pixel isn't enough

Move to the Conversions API, which sends events from your server, when:

The usual approach is to combine both and deduplicate.

The thread you can't lose: the oppref

Whoever clicks your ad arrives with a click identifier in the URL: the oppref. The pixel captures it and stores it in a first-party cookie, __oppref. On the server nobody does that for you: collect it and send it with the event exactly as it came.

The challenge is carrying it through to the conversion, perhaps on another domain and days later: a hidden form field, a parameter in the link or your database will do. We store it on the website on arrival and retrieve it on the server.

Deduplication: one conversion, one count

If the same conversion arrives through the pixel and the API, OpenAI counts it once when the pixel ID, the event name and the event identifier all match.

⚠️ Pitfall: the identifier has a different name on each side: event_id in the pixel, id in the Conversions API. Generate the value once (the order number, for example) and use it in both.

The data type of each event

Each standard event requires a data type and, if it doesn't match, the API rejects the whole batch. It happened to us when we sent a sign-up with the data type from the official example, which is a purchase: sign-up requires customer_action. The full table:

Event What it measures Data type
registration_completed Registration completed customer_action
lead_created Lead created customer_action
appointment_scheduled Appointment booked customer_action
app_installed App installed customer_action
app_opened App opened customer_action
order_created Order placed (purchase) contents
checkout_started Checkout started contents
items_added Added to basket contents
contents_viewed Content viewed contents
page_viewed Page viewed contents
subscription_created Subscription created plan_enrollment
trial_started Trial started plan_enrollment
custom Custom event custom

Also, amount and currency go together, and the custom event carries a name of your own, 1 to 64 characters (letters, digits, hyphens or underscores, starting and ending with a letter or digit, and not matching a standard event).

💡 Ninja trick: before copying an official example, check which event it uses and adjust the data type to yours: a single mistyped event sinks the whole batch.

The hashed email: better attribution, still personal data

You can add the customer's email hashed with SHA-256 to improve attribution. Normalise it first (no stray spaces, all lowercase): "Ana@Example.com" and "ana@example.com" produce different hashes.

⚠️ Pitfall: hashing isn't anonymising. A hashed email is still personal data: we declared it in our privacy policy before sending it. This isn't legal advice; check it with whoever handles your data protection.

The pixel's automatic advanced matching does something similar on its own: it detects customer information on your website (such as form entries) and hashes it with SHA-256 in the browser. The documentation doesn't explain how to switch it off, so mention it in your privacy policy too.

Attribution: which window counts

Line up the windows before comparing with Google Ads or your analytics.

Conversion campaigns: a single standard event

You need exactly one active standard event as the goal; custom events can't be used for optimisation. And it needs volume: if you sell little, optimising towards leads or sign-ups may suit you better. The objective and the event can't be changed later: you'd have to create another campaign (lesson 3 of this module).

The pixel starts with consent switched on: in Europe, call oaiq("consent", false) before initialising it and switch it on when the person accepts (anything blocked isn't resent). On the server, the filter is yours: apply your website's consent criteria before forwarding the oppref or the email, and stop if someone withdraws consent.

Two keys that get mixed up

Ads Manager has two different keys, and we mixed them up:

Both live on your server, never in your website's code.

What to remember

📎 Sources and further reading

⚠️ Free training with no support. Ninja Scripts support channels (email and Telegram) are only for the use of the scripts, not for Google Ads questions or questions about this training.

Pick up here

← BeforeBidding and budgets in ChatGPT Ads: objectives, strategies, the auction and where to startChatGPT Ads in depth — context hints, measurement, bidding and automationAfter →Reporting and diagnostics in ChatGPT Ads: what you can measure, when the data arrives and why your ad isn't showingChatGPT Ads in depth — context hints, measurement, bidding and automationRelatedMeasuring ChatGPT Ads from day one: pixel, conversions and how to read the reportAdvertising in ChatGPT: first stepsRelatedBefore the first euro: the checklist for launching an app campaignAdvertising an app: first stepsRelatedAdvertising an app is not advertising a website: the six differences that catch people outAdvertising an app: first stepsRelatedAdvanced attribution: what data-driven attribution really measures and which decisions it supportsMeasurement II — offline conversions, values, GA4, attribution and lead quality

See the full syllabus

🎓
You're reading the Ninja Academy in the open

Create your free account (no card) to save your progress, take the graded quizzes, earn the Basic level certificate and unlock part of the Intermediate and Advanced training.

Create my free account →
🥷

Subscriber feature

This option is part of the Ninja Scripts Suite subscription.

See the subscription →