> For the complete documentation index, see [llms.txt](https://docs.dinmo.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.dinmo.io/integrations/destination-platforms/chatgpt-ads/send-conversion-events.md).

# Send conversion events

This destination sends server-side conversion events from a DinMo event model or segment to the OpenAI Conversions API.

Each activation represents one existing OpenAI conversion Event Setting and one action source. DinMo derives the OpenAI event and data types from that configuration, prepares identifiers for matching, and converts monetary values to the format required by OpenAI. The initial full run evaluates all source rows; later incremental runs send events that have not already been accepted and checkpointed.

## Before you begin

You need:

* an existing [ChatGPT Ads platform connection](/integrations/destination-platforms/chatgpt-ads.md);
* a **Send conversion events** destination on that connection;
* an active conversion Event Setting linked to the connection's pixel;
* an event model or segment with one conversion per row;
* a stable event ID and an event timestamp for every row.

For web events, the source model must also contain the URL where the event occurred.

## Configure the activation

After selecting the destination, configure these fields:

1. In **Conversion event**, select the existing Event Setting to send to. DinMo loads the active settings linked to the configured pixel in one list, including supported standard events and custom events.
2. Select the **Action source** shared by all rows in the activation.
3. Map the required and optional source columns for the selected event.

DinMo does not create conversion Event Settings. Receiving an event in the ChatGPT Ads **Data Source** view does not create a conversion Event Setting with the same name. If the list is empty or the event you need is missing, create or reactivate the Event Setting in ChatGPT Ads Manager, link it to the configured pixel, then refresh the activation form.

{% hint style="warning" %}
Use one event and one action source per activation. Split a source containing different event types or action sources into separate activations.
{% endhint %}

## Supported Event Settings

DinMo lists active custom Event Settings and active standard Event Settings whose event type is supported by the OpenAI Conversions API. The standard event types below are supported, but they appear in DinMo only after a corresponding active Event Setting has been created in ChatGPT Ads Manager for the configured pixel.

| Standard event           | OpenAI data shape | Typical use                                    |
| ------------------------ | ----------------- | ---------------------------------------------- |
| `app_installed`          | `customer_action` | A user installs an app.                        |
| `app_opened`             | `customer_action` | A user opens an app.                           |
| `appointment_scheduled`  | `customer_action` | A meeting, demo, or consultation is booked.    |
| `checkout_started`       | `contents`        | Checkout begins.                               |
| `contents_viewed`        | `contents`        | A product or another content item is viewed.   |
| `items_added`            | `contents`        | Items are added to a cart or selection.        |
| `lead_created`           | `customer_action` | A lead form or contact request is submitted.   |
| `order_created`          | `contents`        | A purchase is completed.                       |
| `page_viewed`            | `contents`        | An important page is viewed.                   |
| `registration_completed` | `customer_action` | An account or event registration is completed. |
| `subscription_created`   | `plan_enrollment` | A paid subscription starts.                    |
| `trial_started`          | `plan_enrollment` | A free trial starts.                           |

Custom Event Settings use the `custom` data shape. DinMo derives `type`, `custom_event_name`, and `data.type` from the selected setting; do not add columns for them to the source model. OpenAI custom event names contain 1–64 letters, digits, underscores, or hyphens and are sent in lowercase.

`app_installed` and `app_opened` require the `mobile_app` action source. A web event requires `web` and a mapped source URL. The other supported action sources are `offline`, `physical_store`, `phone_call`, `email`, and `other`.

## Field mapping

### Event fields

| DinMo field          | Requirement        | Source value                                                                                                             |
| -------------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------ |
| **Event ID**         | Required           | Stable, non-empty identifier for the conversion. Reuse it across retries and pixel/server deduplication.                 |
| **Event time**       | Required           | Timestamp for when the conversion occurred. It must be within the last 7 days and no more than 10 minutes in the future. |
| **Source URL**       | Required for `web` | Absolute HTTP or HTTPS URL with a host.                                                                                  |
| **OpenAI reference** | Optional           | The original OpenAI `oppref` attribution value, without modification.                                                    |
| **Opt out**          | Optional           | Boolean indicating whether to opt the event out of future user-level personalization.                                    |

DinMo converts Event time to the millisecond Unix timestamp expected by OpenAI.

### User matching fields

All user fields are optional, but mapping the identifiers you legitimately collect can improve conversion matching. DinMo omits optional user values that are `NULL` or blank.

Identifier and geographic fields can contain one value or an array. DinMo deduplicates them and sends the first three unique, non-empty values for each field.

{% hint style="info" %}
Map identifiers as raw values or valid SHA-256 digests. DinMo normalizes and SHA-256 hashes raw email addresses, phone numbers, external IDs, and names automatically. It recognizes existing SHA-256 values and preserves them, preventing double hashing.
{% endhint %}

| DinMo field                                        | Processing                                                                                                           |
| -------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| **Email**                                          | Trimmed, lowercased, and SHA-256 hashed.                                                                             |
| **Phone number**                                   | Normalized to 8–15 digits with its country calling code, then SHA-256 hashed.                                        |
| **External ID**                                    | Trimmed while preserving case, then SHA-256 hashed.                                                                  |
| **First name**, **Last name**                      | Lowercased, stripped of whitespace and ASCII punctuation while preserving non-ASCII characters, then SHA-256 hashed. |
| **Region**, **Postal code**, **City**, **Country** | Sent as raw geographic values. Country must be a valid ISO 3166-1 alpha-2 code such as `FR` or `US`.                 |
| **Android advertising ID**                         | Raw Android GAID in UUID format.                                                                                     |
| **OpenAI browser reference**                       | Raw, non-empty `__obref` cookie value.                                                                               |
| **IP address**, **User agent**                     | Valid IPv4 or IPv6 address and a non-empty browser user-agent string.                                                |

Existing SHA-256 values are normalized to lowercase. DinMo never sends raw email addresses, phone numbers, external IDs, or names to OpenAI.

{% hint style="info" %}
Apply your consent and data-governance requirements before collecting or sending attribution references, browser identifiers, network data, or pseudonymous identifiers.
{% endhint %}

### Event data fields

| DinMo field           | Available for                                | Source value                                                                                                                                     |
| --------------------- | -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Amount**            | All event shapes                             | Optional monetary value in the currency's major unit, for example `42.00` for EUR 42.00. DinMo converts it to the minor unit required by OpenAI. |
| **Currency**          | All event shapes                             | Three-letter ISO 4217 code. Required when Amount is mapped.                                                                                      |
| **Plan ID**           | Plan enrollment and custom events            | Non-empty internal subscription or trial plan identifier.                                                                                        |
| **Contents**          | Contents, plan enrollment, and custom events | JSON array of content objects.                                                                                                                   |
| **Custom properties** | Custom Event Settings only                   | JSON object whose properties are merged into the OpenAI custom data object.                                                                      |

DinMo omits mapped Plan ID and Contents values when the selected event shape does not support them. Custom properties are available only when the selected Event Setting is custom.

{% hint style="info" %}
Map monetary values as they are normally stored in your warehouse. For example, map EUR or USD 25.99 as `25.99`. DinMo converts event-level and item-level amounts to `2599` before sending them to OpenAI. Do not convert amounts to cents or other minor units before mapping them.
{% endhint %}

Each object in **Contents** may contain only `id`, `group_id`, `name`, `content_type`, `quantity`, `amount`, `currency`, and `variant_dict`. Quantities must be integers. Item amounts use the currency's major unit and are converted automatically. `content_type` must be non-empty, and currencies must be valid ISO 4217 codes. When an item has an amount, provide its currency either on that item or at event level. `variant_dict` must contain string keys and string values.

Example Contents value:

```json
[
  {
    "id": "sku_123",
    "name": "Starter bundle",
    "content_type": "product",
    "quantity": 1,
    "amount": 25.99,
    "currency": "EUR"
  }
]
```

Example Custom properties value:

```json
{
  "membership_tier": "gold",
  "coupon_applied": true
}
```

The custom object cannot override connector-owned fields such as `type`, `amount`, `currency`, `contents`, or `plan_id`.

## Delivery and retries

DinMo validates each mapped row, reports invalid rows as activation errors, and sends valid events in batches of at most 1,000. OpenAI rejects a complete request batch when any event in it is invalid.

An activation can complete successfully while reporting row-level errors. Invalid rows are excluded from delivery and are evaluated again after their source data is corrected; review the activation run summary to compare the source, added, and error row counts.

The destination is insert-only. It does not update or delete accepted events. Keep Event ID stable on reruns: OpenAI uses the Pixel ID, event name, and event ID to deduplicate matching browser and server events.

Schedule the activation frequently enough that event timestamps remain within the last 7 days. OpenAI also rejects timestamps more than 10 minutes in the future.

## Troubleshooting

### A conversion event is rejected

Check that the activation selects the intended Event Setting and action source. App lifecycle events require `mobile_app`; web events require `web` and a valid Source URL.

### A conversion event is not available

DinMo only lists active Event Settings linked to the configured pixel. Standard settings must use a supported event type. Create or reactivate the setting in ChatGPT Ads Manager, confirm its conversion source, then refresh the activation form.

### An event timestamp is rejected

Send the time when the conversion actually occurred. The timestamp must be within the last 7 days and no more than 10 minutes in the future. For an initial historical activation, filter the source model to this acceptance window.

### An identifier is rejected

Map the raw value or a valid lowercase SHA-256 digest. For phone numbers, include the country calling code. Use two-letter country codes and a valid UUID for Android GAID.

### A monetary value is rejected

Map Amount in the currency's major unit and map Currency whenever Amount is present. For example, map `25.99` with `EUR`; DinMo converts it to the integer `2599` required by OpenAI. Apply the same rule to amounts inside Contents.

### Contents or Custom properties is invalid

Confirm that Contents is a JSON array and Custom properties is a JSON object. Do not double-encode either value. Custom properties are available only for a custom event.

### A retry creates unexpected results

Preserve the original Event ID and Event time. Generating a new ID turns the retry into a distinct conversion.

For the authoritative API contract, see OpenAI's [Conversions API](https://developers.openai.com/ads/conversions-api) and [supported events](https://developers.openai.com/ads/supported-events) documentation.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.dinmo.io/integrations/destination-platforms/chatgpt-ads/send-conversion-events.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
