> ## 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 Custom Audiences as a destination

> Send your customer lists from Nekt to OpenAI Ads Custom Audiences.

OpenAI Ads is OpenAI's advertising platform, where ads appear inside ChatGPT conversations and are managed in OpenAI Ads Manager. Custom audiences let you use a customer or prospect list to control who can see those ads: you send the list of people, wait for OpenAI to match them, and then include or exclude the matched customers in a campaign, or raise your bid for them in an ad group.

This destination keeps an audience in step with a table in your Lakehouse. Whatever the table holds after each run — the customers who bought last quarter, the trials that never converted, the accounts a campaign should never reach — is what the audience contains.

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

The destination addresses the audience **by name**. On the first run it looks the name up on your ad account and creates the audience if it is not there yet, so there is no ID to copy between OpenAI and Nekt. Every run after that updates the same audience.

Each row of your input table contributes one identifier — an email address or a phone number. Rows with a blank value are skipped, duplicates within a run are sent once, and a value that is already a SHA-256 hash is detected and never hashed twice.

## 2. Important considerations

<Warning>
  Custom audiences are not supported for campaigns targeting the European Economic Area (EEA) or Switzerland, where personalized ads are not yet available.
</Warning>

* **Minimum size.** An audience generally needs about **25,000 matched users** before OpenAI lets you use it for targeting or bid adjustments. Sending 25,000 identifiers does not guarantee that many matches. The audience's `ready` status in Ads Manager is the authoritative signal.
* **Processing time.** OpenAI takes roughly **20 to 30 minutes** to process a membership change before the audience is usable again.
* **Enabled per account.** Using an audience in campaign targeting, and applying ad-group bid multipliers, are switched on by OpenAI for each ad account. If either is unavailable, ask your OpenAI representative to enable it for the account.
* **First-party data only.** Only upload audience data you have the right to use for advertising, and never broker-sourced data. Confirm your use complies with the required rights, notices, consents and legal bases, and with OpenAI's [Ad Tools Terms](https://openai.com/policies/ad-tools-terms/), before sending anything.

## 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 - Custom Audiences 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 whose audience you want to keep in sync.
  </Step>

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

  <Step title="Issue an API key">
    Create a new API key and copy the value.
  </Step>
</Steps>

<Note>
  This is not the same credential as an OpenAI API key from `platform.openai.com`. The Ads API uses its own key, issued from Ads Manager, and each key is tied to a single ad account.
</Note>

The following configurations are available:

* **Ads API key**: the key you copied from Ads Manager.

* **Audience name**: the name of the audience to keep in sync. It is created on the first run if the ad account does not have it yet.

* **Identifier type**: the kind of identifier every row of your table carries. An audience holds a single type.

  | Option                              | What Nekt sends                                                                       |
  | :---------------------------------- | :------------------------------------------------------------------------------------ |
  | Email address                       | The address, trimmed and lowercased. OpenAI hashes it on arrival.                     |
  | Phone number (E.164)                | The number in E.164 form, such as `+5511987654321`. OpenAI hashes it on arrival.      |
  | Email address (hashed with SHA-256) | Only the hash of the normalized address. The raw address never leaves your Lakehouse. |
  | Phone number (hashed with SHA-256)  | Only the hash of the normalized number. The raw number never leaves your Lakehouse.   |

* **Write mode**: how the table changes the audience.

  | Option                                   | Effect                                                                       |
  | :--------------------------------------- | :--------------------------------------------------------------------------- |
  | Add the rows to the audience             | The rows join the current membership. Anyone already in the audience stays.  |
  | Remove the rows from the audience        | The rows are taken out of the audience.                                      |
  | Replace the whole audience with the rows | The audience ends up holding exactly the rows of this run, and nothing else. |

* **Audience description** (optional): applied to the audience when Nekt creates it.

* **Audience ID** (optional): the ID of an existing audience, used instead of the name lookup. Leave it empty unless two audiences share the same name.

* **Continue on error**: keep syncing the remaining rows after OpenAI refuses one. When off, the run stops at the first refused row.

* **Dry run**: log what would be written without writing anything, to validate a new column mapping.

<Note>
  Choosing an unhashed identifier type and letting OpenAI normalize the value gives the highest match rate, because OpenAI applies its own normalization rules before matching. Choose a hashed type when your policy is that raw personal data must not leave the Lakehouse.
</Note>

3. Click **Next**.

## 4. Select your data to send

1. Select the layer and then the table holding the customer list 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

This destination has a single field. Map it to the column of your table that holds the identifier.

| Field name | Description                                                                                                  | Required |
| :--------- | :----------------------------------------------------------------------------------------------------------- | -------- |
| identifier | The email address or phone number of one person, matching the identifier type selected in the configuration. | Yes      |

Once the field is mapped, click **Next**.

## 6. Configure your OpenAI Ads Custom Audiences 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), consider how frequently the audience needs to reflect changes in the source table.

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. For the audience to appear in Ads Manager, wait for the pipeline to run — you can trigger it manually with the refresh icon. Remember that OpenAI then takes 20 to 30 minutes to finish processing the membership before the audience can be used.

<Note>
  A full replacement is never applied from an empty result. If the input table produces no usable identifiers, the audience is left untouched, so a failed upstream run cannot empty an audience your campaigns are targeting.
</Note>

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