---
title: "OpenAI Ads"
description: "OpenAI Ads is OpenAI's advertising platform, where campaigns are created and delivered across ChatGPT and the web. Advertisers measure results with the OpenAI…"
url: "https://www.contentstack.com/docs/lytics/openai"
product: "Contentstack"
doc_type: "guide"
audience:
  - developers
  - admins
version: "current"
last_updated: "2026-11-05"
---

# OpenAI Ads

## Overview

[OpenAI Ads](https://developers.openai.com/ads) is OpenAI's advertising platform, where campaigns are created and delivered across ChatGPT and the web. Advertisers measure results with the OpenAI measurement pixel, and can supplement it with server-side data through OpenAI's APIs.

The Lytics integration offers two exports:

Job type

What it does

[OpenAI Ads: Conversions API Export](#openai-ads-conversions-api-export)

Sends server-side conversion events from a Lytics audience to an OpenAI pixel.

[OpenAI Ads: Custom Audience Export](#openai-ads-custom-audience-export)

Syncs Lytics audience membership into an OpenAI custom audience for campaign targeting.

OpenAI Ads exposes these as two separate APIs, on two hosts, with two separate credentials. Each export uses its own authorization, so if you plan to run both jobs you will create two authorizations.

## Authorization

If you haven't already done so, you will need an OpenAI Ads account before you begin the process described below.

If you are new to creating authorizations in Lytics, see the [Authorizations](/docs/lytics/keys-authorizations) documentation for more information.

1.  Select **OpenAI Ads** from the list of providers.
2.  Select the method for authorization. Note that different methods support different job types. OpenAI Ads supports the following authorization methods:
    *   [OpenAI Ads API Key](#openai-ads-api-key) - Custom Audience Export
    *   [OpenAI Conversions API Key](#openai-conversions-api-key) - Conversions API Export
3.  Enter a **Label** to identify your authorization.
4.  (Optional) Enter a **Description** for further context on your authorization.
5.  Complete the configuration steps needed for your authorization. These steps will vary by method.
6.  Click **Save Authorization**.

### OpenAI Ads API Key

This method supports the [Custom Audience Export](#openai-ads-custom-audience-export) job type only. Create an Ads API key in OpenAI Ads Manager under **Settings**.

**Each Ads API key is scoped by OpenAI to a single ad account.** Use the key belonging to the ad account you want to sync audiences to — there is no ad account to select anywhere in Lytics, because the key itself is the scope. A job configured with this authorization can only reach custom audiences on that one ad account.

1.  In the **Ads API Key** text box, enter your OpenAI Ads API key.

When you save, Lytics verifies the key by reading the ad account it is scoped to. A key that cannot reach an ad account is rejected.

### OpenAI Conversions API Key

This method supports the [Conversions API Export](#openai-ads-conversions-api-export) job type only. This is a **separate credential** from the Ads API key, on a different host, and one cannot be substituted for the other. Find the Conversions API key on the conversions tab in OpenAI Ads Manager.

1.  In the **Conversions API Key** text box, enter your OpenAI Conversions API key.

Lytics cannot verify this key when you save it. Every OpenAI conversions endpoint requires a Pixel ID, which is configured on the job rather than on the authorization, so the authorization is only checked for a value. If the key is wrong, the export job — not the authorization — is where the failure appears.

## OpenAI Ads: Conversions API Export

Send server-side conversion events from a Lytics audience to an OpenAI pixel using the [OpenAI Conversions API](https://developers.openai.com/ads/conversions-api). Server-side events supplement the browser pixel with conversions it cannot observe — offline purchases, phone orders, back-office events — and improve campaign measurement and optimization.

### Integration Details

*   **Implementation Type**: Server-side Integration
*   **Implementation Technique**: API Integration, Audience Trigger Integration
*   **Frequency**: Real-time Integration
*   **Resulting data**: Conversion events on the configured OpenAI pixel, built from Lytics user fields.

Once the job is started, it will:

1.  Optionally scan the existing audience membership, building a conversion event from each user's fields according to the job's configuration.
2.  Add each event to a batch. The batch is sent to OpenAI every five seconds, or when it reaches 1,000 events, whichever happens first.
3.  Run continuously. As users enter or exit the Lytics audience — or as the user fields you selected under **Fields to Trigger** change — further events are sent.

#### Invalid Events Are Dropped, Not Sent

A conversions batch at OpenAI is **all-or-nothing**: if OpenAI rejects one event in a request, the entire request fails. There is no partial-success mode.

To keep one malformed profile from taking a whole batch of good conversions down with it, Lytics drops any user it cannot build a valid event for, and reports those users as omitted on the job. An event is dropped when:

*   The event type is missing or unsupported.
*   No timestamp could be determined, or no event ID could be determined.
*   The event type is **Custom** and no custom event name was mapped or configured.
*   The action source is **Web** and no source URL was mapped or configured.
*   The event type is **App Installed** or **App Opened** and no action source was configured. OpenAI requires one for these.
*   The user has no identifiers at all and no attribution reference (oppref).

If every user in a batch is dropped, the job reports that no valid events were found.

#### Deduplicating Against the Browser Pixel

OpenAI deduplicates on **Pixel ID + event name + event ID**. To have a server-side event collapse with the same conversion observed by the browser pixel, map **Event ID** to the Lytics field holding the same ID the pixel sends, and use the same custom event name in both places.

If **Event ID** is not mapped, Lytics synthesizes one from the user's ID and the event timestamp. That keeps the event valid, but it cannot match anything the pixel sent, so the conversion will be counted twice if the pixel also reports it.

#### Attribution References

**Attribution Reference** (oppref) and **Browser Reference** (obref) are OpenAI's click and browser identifiers, and are the strongest match signals available. Neither one reaches Lytics on its own: your site must run the OpenAI measurement pixel, and the resulting \_\_oppref and \_\_obref cookies must be captured into Lytics user fields through the [JavaScript tag](/docs/lytics/lytics-javascript-tag). Without them, matching relies on hashed email, phone, and the other user fields you map.

### Fields

Lytics normalizes every identifier to OpenAI's documented rules before sending it. Values that are already SHA-256 hex digests are passed through unchanged.

Mapping target

OpenAI field

Normalization applied by Lytics

Email

emails\_sha256

Trimmed, lowercased, SHA-256 hashed.

Phone Number

phone\_numbers\_sha256

Digits only — the leading + and leading zeros are stripped — kept only if 8 to 15 digits remain, then SHA-256 hashed.

External ID

external\_ids\_sha256

Trimmed, SHA-256 hashed.

First Name

first\_names\_sha256

Lowercased, whitespace and ASCII punctuation removed, then SHA-256 hashed. Non-ASCII characters are preserved.

Last Name

last\_names\_sha256

Same as First Name.

City

cities

Trimmed. Sent as plain text.

Region or State

regions

Trimmed. Sent as plain text.

Postal Code

postal\_codes

Trimmed. Sent as plain text.

Country Code

countries

Trimmed, uppercased. Only two-letter values are sent.

Google Advertising ID

android\_advertising\_id

Lowercased and sent **unhashed** — OpenAI hashes it server-side. An all-zero ID (an opted-out device) is dropped.

IP Address

ip\_address

Sent as-is.

User Agent

user\_agent

Sent as-is.

Browser Reference

obref

Sent as-is, unhashed.

**Phone numbers are normalized differently for each OpenAI export**

The Conversions API wants digits only, with no +. The [Custom Audience Export](#openai-ads-custom-audience-export) wants full E.164, including the +. Lytics applies the correct form for each job automatically; the same Lytics phone field can be used for both.

For fields that hold a set of values, OpenAI accepts up to three values, and Lytics sends the first three unique values in the order they appear on the profile.

The event body is built from the **Event Mapping** inputs:

Mapping target

Notes

Event ID

Used for deduplication against the browser pixel. Synthesized if not mapped.

Event Timestamp

Must be within the last 7 days, and no more than 10 minutes in the future. The current time is used if not mapped.

Custom Event Name

Required when the event type is **Custom**, unless set in the job's **Custom Event Name** text box.

Source URL

Required for web events. Falls back to the job's **Fallback Source URL**.

Attribution Reference

The \_\_oppref cookie value.

Conversion Value

Converted to whole minor units before sending — see **Conversion Value Units** below.

Currency Code

Three-letter ISO 4217 code. Falls back to the job's **Currency Code**.

Plan ID

Sent for subscription and trial events only.

Item ID, Item Name, Item Quantity

Sent as event contents. Not sent for events in the customer\_action family.

**Conversion value is sent in minor units**

OpenAI requires the conversion value as a whole number of minor units, so 19.99 US dollars is sent as 1999. Use the **Conversion Value Units** setting to tell Lytics which units your mapped field is already in. Selecting the wrong one produces a silent 100× error in your reported conversion value — the job will not fail.

Each event type belongs to a data family that OpenAI requires the payload to declare. Lytics sets it for you; the family is shown in parentheses next to each event type in the **Event Type** dropdown.

Data family

Event types

contents

Checkout Started, Contents Viewed, Items Added, Order Created, Page Viewed

customer\_action

App Installed, App Opened, Appointment Scheduled, Lead Created, Registration Completed

plan\_enrollment

Subscription Created, Trial Started

custom

Custom

An example payload:

```
{
    "integration_source": "lytics",
    "events": [
        {
            "id": "0473bcd3-b7d1-56c0-9049-9289d5599b95",
            "type": "order_created",
            "timestamp_ms": 1765236624000,
            "action_source": "web",
            "source_url": "https://www.example.com/checkout/complete",
            "oppref": "b1f0c2d9e7a4",
            "data": {
                "type": "contents",
                "amount": 1999,
                "currency": "USD",
                "contents": [
                    {
                        "id": "SKU-1123",
                        "name": "Trail Runner",
                        "quantity": 2
                    }
                ]
            },
            "user": {
                "emails_sha256": ["dbd8928a943dbd80caca9e33c6ff8adb8a6a32511626114d47b9048b7496fe12"],
                "phone_numbers_sha256": ["b13ce5d3de6d5b0dd1c6dbf9b3a1b8ab2a5b3c7d6e9f0a1b2c3d4e5f60718293"],
                "cities": ["portland"],
                "countries": ["US"],
                "ip_address": "192.192.1.1",
                "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Gecko/20100101 Firefox/47.0"
            }
        }
    ]
}
```

### Configuration

Follow these steps to set up and configure an OpenAI Ads Conversions API export job in the Lytics platform. If you are new to creating jobs in Lytics, see the [Destinations](/docs/lytics/destinations) documentation for more information.

1.  Select **OpenAI Ads** from the list of providers.
2.  Select the export **OpenAI Ads: Conversions API Export** from the list.
3.  Select the [OpenAI Conversions API Key](#openai-conversions-api-key) authorization you would like to use, or create a new one.
4.  Enter a **Label** to identify this job you are creating in Lytics.
5.  (Optional) Enter a **Description** for further context on your job.
6.  In the **Audiences** input, select the Lytics audiences that contain the users to export.
7.  In the **Pixel ID** text box, enter the OpenAI Pixel ID these conversions belong to. Find it on the conversions tab in OpenAI Ads Manager.
8.  From the **Event Type** input, select the OpenAI conversion event type. Select **Custom** to send an event name of your own.
9.  (Optional) In the **Custom Event Name** text box, enter the event name. Required when the event type is **Custom** and no custom event name is mapped. Use 1 to 64 letters, digits, underscores, or hyphens, starting and ending with a letter or digit — and use the same name in the browser pixel so the two deduplicate.
10.  (Optional) From the **Action Source** input, select where the conversion happened. Required for **App Installed** and **App Opened** events. Web events also require a source URL.
11.  From the **User Data Mapping** input, map Lytics user fields to OpenAI user matching fields. At least one identifier must be mapped, and match rates rise with each additional one.
12.  (Optional) From the **Event Mapping** input, map Lytics user fields to OpenAI event fields.
13.  (Optional) From the **Conversion Value Units** input, select whether your mapped value field holds major units (dollars) or minor units (cents). Defaults to major units.
14.  (Optional) From the **Currency Code** input, select the currency used when no currency field is mapped. Defaults to USD.
15.  (Optional) In the **Fallback Source URL** text box, enter a URL to use for web events whose mapped **Source URL** field is empty.
16.  (Optional) Select the **Opt Out of Personalization** toggle to opt these events out of future user-level personalization at OpenAI.
17.  (Optional) From the **Fields to Trigger** input, select up to 75 user fields to trigger user change events. For any user in the exported audience, if any of the selected field values change, that user is sent to the OpenAI Conversions API.
18.  (Optional) From the **Audience Trigger Events** input, select which type of audience trigger events to send.
19.  (Optional) Select the **Existing Users** checkbox to immediately push users who currently exist in the selected Lytics audiences. Deselecting will only push users as they enter or leave the audience.
20.  Click the **Complete** button to start the job.

## OpenAI Ads: Custom Audience Export

Export your Lytics audiences to an [OpenAI custom audience](https://developers.openai.com/ads/custom-audiences) to target specific customers in your OpenAI Ads campaigns. Refine your targeting using Lytics audiences built on behavioral data, data science scores, and content affinities from across your channels.

### Integration Details

*   **Implementation Type**: Server-side Integration
*   **Implementation Technique**: API Integration, Audience Trigger Integration
*   **Frequency**: Batch Integration
*   **Resulting data**: An OpenAI custom audience whose membership tracks the selected Lytics audiences.

Once the job is started, it will:

1.  Create a new OpenAI custom audience, unless you selected an existing one to sync into.
2.  Add the users already in the selected Lytics audiences, then keep the audience current from there.
3.  As users enter the exported Lytics audience, add their identifiers to an add batch. As users exit, add their identifiers to a removal batch. Identifiers that are not already SHA-256 hashed are hashed before being added, except Google Advertising IDs, which OpenAI hashes itself.
4.  Send both batches every two minutes, or once either batch reaches 2,500 identifiers, whichever happens first.
5.  Run continuously, keeping the OpenAI audience in step with the Lytics audience. Users who exit the Lytics audience are always removed from the OpenAI audience.

Membership changes at OpenAI are **asynchronous**: OpenAI acknowledges a batch immediately and applies it in the background. Lytics waits briefly for each batch to settle so the job's synced counts reflect what OpenAI actually accepted. A batch that OpenAI reports as failed is counted as omitted on the job.

**OpenAI reports audience size in ranges, not exact counts**

For privacy reasons, OpenAI reports matched users as a range (under\_25k, 25k\_100k, and so on) rather than an exact number, so Lytics cannot report how many exported users matched. OpenAI publishes **25,000 matched users** as the planning threshold for inclusion targeting and bid adjustments; exclusion-only campaigns have no minimum size.

### Fields

Lytics exports the following fields to OpenAI.

Lytics User Field

Description

OpenAI Identifier Type

Normalization applied by Lytics

Email Field

Email address

email\_sha256

Trimmed, lowercased, SHA-256 hashed.

Phone Field

Phone number

phone\_number\_sha256

Normalized to E.164 **including the leading +**, then SHA-256 hashed.

Mobile ID Field

Google Advertising ID

gaid

Trimmed and lowercased, sent **unhashed**.

Each field may be scalar or a set, and may already hold SHA-256 hashed values — those are passed through unchanged. A user with no usable value in any of the three fields is skipped and counted as omitted on the job.

**Do not map a pre-hashed Google Advertising ID**

OpenAI lowercases and hashes advertising IDs with its own scheme, so a value that is already a SHA-256 digest can never match. Lytics skips pre-hashed values in the **Mobile ID Field** rather than sending a guaranteed miss.

### Configuration

Follow these steps to set up and configure an OpenAI Ads custom audience export job in the Lytics platform. If you are new to creating jobs in Lytics, see the [Destinations](/docs/lytics/destinations) documentation for more information.

1.  Select **OpenAI Ads** from the list of providers.
2.  Select the export **OpenAI Ads: Custom Audience Export** from the list.
3.  Select the [OpenAI Ads API Key](#openai-ads-api-key) authorization you would like to use, or create a new one.
4.  Enter a **Label** to identify this job you are creating in Lytics.
5.  (Optional) Enter a **Description** for further context on your job.
6.  In the **Audiences** input, select the Lytics audiences that contain the users to export.
7.  (Optional) In the **OpenAI Audience Name** text box, enter a name for a new custom audience in OpenAI. Must be at least three characters. If left blank, the audience is named Lytics <audience name> after the Lytics audience being exported. This is ignored when you select an existing audience below.
8.  (Optional) From the **Existing OpenAI Custom Audience** input, select an existing OpenAI custom audience to sync into instead of creating a new one. Only audiences on the ad account your authorization is scoped to are listed.
9.  (Optional) From the **Email Field** input, select the field that contains the user's email.
10.  (Optional) From the **Phone Field** input, select the field that contains the user's phone number.
11.  (Optional) From the **Mobile ID Field** input, select the field that contains the user's Google Advertising ID.
12.  Click the **Complete** button to start the job.

At least one of **Email Field**, **Phone Field**, or **Mobile ID Field** must be selected, and mapping more than one raises your match rate.