# OpenAI Ads Web Device Mode Integration


{{< customreadfile "/includes/openai-ads-private-beta.md" >}}

After you have successfully instrumented OpenAI Ads as a destination in RudderStack, follow this guide to correctly send your events to OpenAI Ads in [web device mode]({{< ref "/destinations/rudderstack-connection-modes.md#device-mode" >}}).

Find the open source JavaScript SDK code for this destination in the [GitHub repository](https://github.com/rudderlabs/rudder-sdk-js/tree/develop/packages/analytics-js-integrations/src/integrations/OpenAIAds).

{{< info >}}
OpenAI Ads supports device mode only for web sources. Mobile device mode is not supported. Mobile and other non-web source types use cloud mode only.
{{< /info >}}

## Add web device mode integration

The RudderStack JavaScript SDK loads the OpenAI Ads Measurement Pixel from `https://bzrcdn.openai.com/sdk/oaiq.min.js` and initializes it with your Pixel ID.

If you use a Content Security Policy (CSP) header on your website, [allowlist]({{< ref "sources/event-streams/sdks/rudderstack-javascript-sdk/load-js-sdk.md#allowlist-destination-domain" >}}) the `bzrcdn.openai.com` domain for script loading.

## Identify

Use the [`identify`]({{< ref "event-spec/standard-events/identify.md" >}}) call to update the user data stored by the OpenAI Ads Measurement Pixel.

A sample `identify` call is shown below:

```javascript
rudderanalytics.identify("user-123", {
  email: "alex@example.com",
  phone: "+15551234567",
  firstName: "Alex",
  lastName: "Keener",
  city: "San Francisco",
  state: "CA",
  country: "US",
  postalCode: "94105",
});
```

RudderStack maps `identify` traits to the OpenAI Ads Measurement Pixel user object as follows:

| RudderStack property | OpenAI Ads user field | Notes |
| :----| :-----| :-----|
| `traits.email` <br /> `context.traits.email` | `email_sha256` | Normalized and hashed by RudderStack. |
| `traits.phone` <br /> `context.traits.phone` | `phone_number_sha256` | Normalized and hashed by RudderStack. |
| `userId` <br /> `anonymousId` | `external_id_sha256` | Normalized and hashed by RudderStack. |
| `traits.firstName` <br /> `traits.first_name` <br /> `context.traits.firstName` <br /> `context.traits.first_name` | `first_name_sha256` | Normalized and hashed by RudderStack. |
| `traits.lastName` <br /> `traits.last_name` <br /> `context.traits.lastName` <br /> `context.traits.last_name` | `last_name_sha256` | Normalized and hashed by RudderStack. |
| `traits.city` <br /> `context.traits.city` | `city` | Sent as a plain value. |
| `traits.state` <br /> `context.traits.state` | `region` | Sent as a plain value. |
| `traits.postalCode` <br /> `context.traits.postalCode` | `postal_code` | Sent as a plain value. |
| `traits.country` <br /> `context.traits.country` | `country` | Sent as a plain value. |

RudderStack rejects apparent pre-hashed values passed into non-hashed fields.

## Track

Use the [`track`]({{< ref "event-spec/standard-events/track.md" >}}) call to send conversion events to OpenAI Ads.

A sample `track` call is shown below:

```javascript
rudderanalytics.track("Order Completed", {
  orderId: "order-123",
  revenue: 49.99,
  currency: "USD",
  products: [
    {
      product_id: "sku-123",
      name: "T-shirt",
      category: "Apparel",
      quantity: 1,
      price: 49.99,
    },
  ],
});
```

RudderStack uses your [event mapping settings]({{< ref "destinations/streaming-destinations/openai-ads/setup-guide.md#event-mapping-settings" >}}) to resolve the OpenAI Ads event type for each `track` event. If no mapping matches the RudderStack event name, RudderStack does not send the event to the Measurement Pixel.

The Measurement Pixel does not support the `app_installed` and `app_opened` events. These events are supported in cloud mode, but not in web device mode.

### Track event data

RudderStack maps the following event data fields in web device mode:

| RudderStack property | OpenAI Ads field | Notes |
| :----| :-----| :-----|
| `messageId` or configured deduplication key path | `event_id` | Sent in the Measurement Pixel event options. The configured path must resolve to a scalar value. |
| `properties.optOut` <br /> `properties.opt_out` | `opt_out` | Optional boolean value sent in the Measurement Pixel event options. |
| `properties.amount` <br /> `properties.value` <br /> `properties.revenue` | `amount` | Converted to the currency's minor units when currency is available. |
| `properties.currency` <br /> Default currency setting | `currency` | Sent when amount is present. |
| `properties.plan_id` <br /> `properties.planId` | `plan_id` | Sent for `plan_enrollment` and custom event data shapes. |
| `properties.contents` <br /> `properties.products` | `contents` | Sent for `contents`, `plan_enrollment`, and custom event data shapes. Not sent for `customer_action` events. |

For each item in `properties.contents` or `properties.products`, RudderStack maps the following fields:

| RudderStack property | OpenAI Ads field |
| :----| :-----|
| `id` <br /> `content_id` <br /> `contentId` <br /> `item_id` <br /> `itemId` <br /> `product_id` <br /> `productId` <br /> `sku` | `id` |
| `name` <br /> `title` <br /> `product_name` <br /> `productName` | `name` |
| `content_type` <br /> `contentType` <br /> `type` <br /> `category` <br /> `product_category` | `content_type` |
| `quantity` <br /> `count` | `quantity` |
| `amount` <br /> `value` <br /> `price` | `amount` |
| `currency` <br /> `currency_code` <br /> `currencyCode` | `currency` |

## Page

Use the [`page`]({{< ref "event-spec/standard-events/page.md" >}}) call to send web page view events to OpenAI Ads.

A sample `page` call is shown below:

```javascript
rudderanalytics.page();
```

RudderStack resolves `page` events using your event mapping settings. Unmapped `page` events default to the OpenAI Ads `page_viewed` event.

## Screen

The OpenAI Ads web device mode integration does not support the [`screen`]({{< ref "event-spec/standard-events/screen.md" >}}) call. Send `screen` events in cloud mode instead.

