Skip to content
ceaksan

Dedup in OpenAI Ads: Not Counting the Same Conversion Twice

When the pixel and the Conversions API send the same conversion, double-counting happens. OpenAI Ads deduplicates it with three components: Pixel ID, event name, and event_id, keeping the pixel event_id equal to the server id. This guide shows how to generate a stable event_id, match on both sides, and the common mistakes.

Jun 13, 2026 4 min read
TL;DR

When the same conversion is sent from both the pixel and the Conversions API, it is counted twice unless set up correctly. OpenAI Ads deduplicates by matching three components: Pixel ID, event name, and event_id. On the pixel side options.event_id, on the server side the id field must carry the same value; the same Pixel ID must be used on both sides. OpenAI does not generate the event_id, the developer does: pick a stable, unique identifier per conversion such as an order number, and use the same value on both layers. For custom events, the same custom_event_name is matched in place of the event name.

In OpenAI Ads measurement, the pixel and the Conversions API often carry the same conversion: the user completes the order in the browser, the pixel fires; the same order is also recorded on the server and goes out from the Conversions API. Unless set up correctly, this single conversion is counted twice and reports inflate. Deduplication is the mechanism that binds these two records into one conversion.

This guide shows which fields establish the match, how a stable event_id is generated, and the common mistakes. The pixel and server setups themselves are the subject of separate posts; the focus here is reconciling the two layers without overlap.

Why Dedup Is Needed

The pixel and the Conversions API each fall short on their own. The pixel is thinned out by ad blockers, consent refusal, and cookie restrictions; the Conversions API sees the server-side record, not the live interaction in the browser. Used together, coverage widens, but when the same conversion goes from two sources, the risk of double-counting arises. Dedup is the way to keep the count single while widening coverage.

If the same conversion is sent from a single layer only, no dedup is needed. The event_id comes into play only when the same conversion goes from both the pixel and the server.

The Matching Key: Three Components

OpenAI Ads decides that two records are the same conversion by matching three components: Pixel ID, event name, and event_id1. If all three are identical on both sides, the records are counted as one conversion.

ComponentPixel sideServer sideRule
Pixel IDpixelId in initpid query parameterSame on both sides
Event namemeasure event nameevent typeSame on both sides
event_idoptions.event_idevent idSame value on both sides

On the server side the conversion’s identity is carried in the id field; on the pixel side the same value is sent as options.event_id2. So what establishes the match is the server id being exactly equal to the pixel event_id.

The Developer Generates the event_id

The critical point: OpenAI does not generate the event_id. The developer sets a stable, unique identifier per conversion and reuses it on the same pixel and server event1. A good event_id has two properties:

  • Unique: Each conversion gets a different value, so separate orders do not get mixed up.
  • Stable: The pixel and the server must be able to produce the same value for the same conversion. A value that already exists in the system and can be re-read, such as an order number or payment ID, is suitable for this reason.

An order ID naturally meets both conditions: it is unique per order and the same value can be read in the browser and on the server.

// Pixel side: send the conversion identity as event_id
oaiq(
  "measure",
  "order_created",
  { type: "contents", amount: 2599, currency: "USD" },
  { event_id: "order_12345" },
);
// Server side: send the same value as id
{
  "id": "order_12345",
  "type": "order_created",
  "timestamp_ms": 1773892800000,
  "data": {
    "type": "contents",
    "amount": 2599,
    "currency": "USD",
    "contents": [
      {
        "id": "sku_123",
        "name": "Starter bundle",
        "content_type": "product",
        "quantity": 1
      }
    ]
  }
}

Because on both sides the event_id/id value is order_12345, the event name is order_created, and the same Pixel ID is used, OpenAI counts these two records as one conversion.

Matching on Custom Events

If custom is sent instead of a standard event, the match is established with custom_event_name in place of the standard event name. For custom events, the same custom_event_name must be used on both sides1. On the pixel side custom_event_name is carried in the options object, on the server side in the event field; if the two differ, no match is made.

Common Mistakes

The mistakes that break dedup usually come from a value that should stay the same diverging on the two sides:

  • A new random event_id on every send: The pixel and the server produce different values, no match is made, the conversion is counted twice. The event_id must be stable per conversion.
  • Different Pixel ID: If the two sends carry different Pixel IDs, the match is never established in the first place.
  • Event name mismatch: If the pixel sends order_created and the server sends a different type, the records do not match.
  • Name divergence on custom events: A different custom_event_name on the two sides creates the same problem.
  • Unnecessary event_id: Adding an event_id when the conversion goes from a single layer does no harm but is unnecessary; dedup is meaningful only when there are two sources.

Which value should be the event_id?

A good event_id is a unique identifier accessible at the moment of conversion in both the browser and the server. An order number, a payment transaction ID, or a subscription ID is suitable. Avoid randomly generated values known on only one side; what establishes the match is both layers carrying the same value.

Next Steps

Once dedup is set up, the pixel and the Conversions API now widen coverage while keeping the count single. The next step is clarifying which event is sent when: the event taxonomy and the data shape each event expects are decisive for measurement being counted correctly.

Footnotes

  1. Conversions API (OpenAI Developers) — pixel/server dedup (“If you send the same conversion from the pixel and the Conversions API, reuse the same value as the API id and pixel event_id.”), using the same Pixel ID and the same custom_event_name on custom events (“Send both events with the same Pixel ID. For custom events, use the same custom_event_name on both sides as well.”). 2 3
  2. JavaScript Pixel (OpenAI Developers) — the dedup role of event_id (“Deduplication matches on your Pixel ID, the event name, and event_id.”), the developer generating the event_id (“When you need deduplication across browser and server events, generate the event_id yourself and reuse it on the same pixel and server-sent event.”).
Key Takeaways
  • 01 Dedup matches on three components: Pixel ID, event name, and event_id. If all three are identical on both sides, OpenAI counts the two records as one conversion.
  • 02 On the pixel options.event_id, on the server the id field carries the same value; the developer generates the event_id, not OpenAI.
  • 03 The event_id must be stable and unique per conversion: an order number is good, a random value that changes on every send is bad.
  • 04 For custom events, the same custom_event_name is matched on both sides in place of the standard event name.
  • 05 If the same conversion is sent from a single layer, no event_id is needed; dedup matters only when the same conversion goes from two sources.
Frequently Asked Questions (FAQ)
+ How does OpenAI Ads deduplicate conversions?

Deduplication relies on matching three components: Pixel ID, event name, and event_id. When the pixel event_id equals the Conversions API id and the same Pixel ID is used on both sides, OpenAI counts the two records as one conversion. For custom events, the same custom_event_name is matched in place of the event name.

+ Who generates the event_id?

OpenAI does not generate the event_id, the developer does. You pick a stable, unique value per conversion and reuse it on the same pixel and server event. A reproducible identifier such as an order number is suitable.

+ Do I have to send an event_id on every conversion?

No. The event_id is needed only when the same conversion is sent from more than one source, that is, from both the pixel and the Conversions API. If the conversion is sent from a single layer, there is no need for dedup.

+ Can I use a random value as the event_id?

If a random value regenerated on every send is used, the pixel and the server carry different event_ids, no match is made, and the conversion is counted twice. The event_id must be a stable value that stays the same on both layers for the same conversion; that is why an order ID is a good choice.