> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nekt.com/llms.txt
> Use this file to discover all available pages before exploring further.

# OpenAI Ads Conversions as a destination

> Send your conversions from Nekt to the OpenAI Ads Conversions API.

OpenAI Ads is OpenAI's advertising platform, where ads appear inside ChatGPT conversations and are managed in OpenAI Ads Manager. The Conversions API is its server-to-server measurement endpoint: instead of relying only on the browser pixel, you tell OpenAI directly which conversions happened, so attribution and reporting reflect what actually closed.

This destination sends conversions straight from your Lakehouse. That makes it the natural place for everything the pixel cannot see — a deal marked won in the CRM, a subscription that survived the trial, a sale closed over the phone or in a physical store.

If you also want to read your OpenAI Ads campaign and delivery data into the Lakehouse, see [OpenAI Ads as a data source](/sources/openai-ads).

## 1. Overview

Each row of your input table becomes one conversion event. Events travel in batches of up to 1,000, and personal identifiers — email addresses, phone numbers, customer IDs, names — are normalized and hashed with SHA-256 inside Nekt, so the raw values never leave your Lakehouse.

## 2. Important considerations

<Warning>
  OpenAI only accepts conversions from the **last 7 days**, and no more than 10 minutes in the future. Rows outside that window are skipped and reported in the run log. This is a limit of the OpenAI Ads API: historical conversions cannot be backfilled, so schedule this destination to run at least once a week — daily is better.
</Warning>

* **Deduplication.** If the same conversion also reaches OpenAI through the pixel, send the same value in the pixel's `event_id` and in this destination's `event_id`, with the same Pixel ID. OpenAI keeps the first event it receives and ignores the later duplicate.
* **Match quality.** Every identifier you map raises the chance OpenAI can attribute the conversion. Mapping the email address alone already works; adding phone number, customer ID, name and location improves it.
* **Batch behavior.** OpenAI rejects an entire batch when a single event in it is invalid. With **Continue on error** enabled, Nekt splits a rejected batch in half and retries until the invalid rows are isolated, so a single bad row never costs you the 999 good ones travelling with it.

## 3. Configuring the destination

1. In the [Destinations](https://app.nekt.ai/destinations) tab, click the "Add destination" button at the top right of your screen. Then select the OpenAI Ads - Conversions option from the list of connectors.

2. Click **Next** and you'll be prompted to add your access.

<Steps>
  <Step title="Open Ads Manager">
    Sign in at [ads.openai.com](https://ads.openai.com) with the ad account the conversions belong to.
  </Step>

  <Step title="Go to Conversions">
    Open the **Conversions** tab.
  </Step>

  <Step title="Copy the Pixel ID and issue a Conversions API key">
    Take the Pixel ID of the data source you are measuring, then create a Conversions API key and copy its value. Both must belong to the same ad account.
  </Step>
</Steps>

<Note>
  This is not the same credential as the Ads API key used by the OpenAI Ads source and by the Custom Audiences destination. The Conversions API has its own key, issued from the Conversions tab.
</Note>

The following configurations are available:

* **Conversions API key**: the key you copied from the Conversions tab.
* **Pixel ID**: the Pixel ID the conversions are attributed to.
* **Default action source**: where the conversion happened, used for rows whose table has no column for it. Choose **Offline** for conversions closed in a CRM, **Physical store** for in-person sales, **Phone call** for telesales.
* **Default source URL** (optional): the URL recorded for web conversions when the table has no column for it. OpenAI requires it whenever the action source is **Website**.
* **Validate only** (optional): send the events for validation without storing them, to confirm the column mapping before the first real run.
* **Continue on error**: keep syncing the remaining rows after OpenAI refuses one, isolating the invalid rows instead of failing the run.
* **Dry run**: log what would be sent without sending anything.

3. Click **Next**.

## 4. Select your data to send

1. Select the layer and then the table holding the conversions you want to send.

   > Tip: The table can be found more easily by typing its name.

2. Click **Next**.

## 5. Map your data to the destination

### Required fields

| Field name  | Description                                                                                                                                  |
| :---------- | :------------------------------------------------------------------------------------------------------------------------------------------- |
| event\_id   | Your identifier for the conversion, such as the order ID. Reuse the same value when the same conversion is resent, so OpenAI counts it once. |
| event\_type | What happened. See the supported event types below.                                                                                          |
| event\_time | When the conversion happened. A timestamp column, an ISO 8601 string or a Unix epoch all work. Must be within the last 7 days.               |

The supported event types are `order_created`, `checkout_started`, `items_added`, `contents_viewed`, `page_viewed`, `lead_created`, `appointment_scheduled`, `registration_completed`, `subscription_created`, `trial_started` and `custom`. Native app events also support `app_installed` and `app_opened`.

### Conversion value

| Field name | Description                                                                                                                                                                                               | Required |
| :--------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| amount     | The value of the conversion, as an integer in the currency's minor unit — `4290` means R\$ 42,90. If your column holds a decimal, add the `to_minor_units` transform to the mapping and Nekt converts it. | No       |
| currency   | The three-letter ISO 4217 currency code, such as `BRL` or `USD`. Required whenever an amount is sent.                                                                                                     | No       |
| contents   | The line items of the conversion, as a JSON array of objects. Each item accepts `id`, `group_id`, `name`, `content_type`, `quantity`, `amount`, `currency` and `variant_dict`.                            | No       |
| plan\_id   | Your identifier for the subscription or trial plan, for `subscription_created` and `trial_started`.                                                                                                       | No       |

### Matching the conversion to a person

Every field below is optional, and every one you map raises the chance OpenAI attributes the conversion. The first five are hashed by Nekt before being sent.

| Field name    | Description                                                                                                               |
| :------------ | :------------------------------------------------------------------------------------------------------------------------ |
| email         | The email address of the customer.                                                                                        |
| phone\_number | The phone number of the customer, in any format. Nekt normalizes it to the international digits-only form OpenAI expects. |
| external\_id  | Your own stable, pseudonymous customer identifier, such as a CRM ID.                                                      |
| first\_name   | The first name of the customer.                                                                                           |
| last\_name    | The last name of the customer.                                                                                            |
| city          | The city of the customer, sent as a raw value.                                                                            |
| region        | The state or region of the customer, sent as a raw value.                                                                 |
| postal\_code  | The postal code of the customer, sent as a raw value.                                                                     |
| country       | The two-letter country code of the customer, such as `BR`.                                                                |
| ip\_address   | The IP address recorded for the conversion.                                                                               |
| user\_agent   | The user agent recorded for the conversion.                                                                               |
| obref         | The browser reference from the pixel's `__obref` first-party cookie, passed through unchanged.                            |

### Other fields

| Field name               | Description                                                                                                                                                           |
| :----------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| action\_source           | Where the conversion happened, overriding the default action source for this row: `web`, `mobile_app`, `offline`, `physical_store`, `phone_call`, `email` or `other`. |
| source\_url              | The page the web conversion happened on, overriding the default source URL for this row.                                                                              |
| custom\_event\_name      | The name of your own event, required when the event type is `custom`. Use 1 to 64 letters, digits, underscores or hyphens.                                            |
| data\_type               | Overrides the data shape OpenAI expects for the event type. Leave it unmapped unless OpenAI support asks you to set it.                                               |
| oppref                   | The attribution identifier OpenAI provided for the click, when you captured it.                                                                                       |
| android\_advertising\_id | The Google Advertising ID of the device, for app conversions.                                                                                                         |
| opt\_out                 | Set to true to opt this conversion out of future user-level personalization.                                                                                          |

Once the fields are mapped, click **Next**.

## 6. Configure your OpenAI Ads Conversions destination

1. Describe your destination for easy identification within your organization. You can inform things like what data it brings, to which team it belongs, etc.

2. To define your [Trigger](https://docs.nekt.com/runs/scheduling-and-triggers), remember the 7-day window: a daily trigger keeps every conversion inside it comfortably.

3. Click **Done**.

### Check your new destination!

1. Once completed, you'll receive confirmation that your new destination is set up.

2. You can view it on the [Destinations](https://app.nekt.ai/destinations) page and trigger the pipeline manually with the refresh icon. Once it has run, the conversions appear in the reporting of OpenAI Ads Manager, attributed to the campaigns that earned them.

> If you encounter any issues, reach out to us via Slack, and we'll gladly assist you!
