# Google Campaign Manager Enhanced Conversions Export Integration

## Overview

The Google Campaign Manager 360 (CM360) Enhanced Conversions connector allows you to export conversion data from Treasure AI directly to Google Campaign Manager 360. It uses the [Campaign Manager 360 API](https://developers.google.com/doubleclick-advertisers/guides/conversions_ec) to upload or update conversion records tied to Floodlight activities.

## Prerequisites

- Basic knowledge of Treasure AI, including the TD Toolbelt.
- A Google account with access to Campaign Manager 360.
- A Campaign Manager User Profile ID with permissions to upload conversions.
- The Floodlight Configuration ID and Floodlight Activity ID for the conversion actions you want to upload.


## Limitations and Known Issues

- Each conversion record may contain a maximum of **5 `userIdentifiers`** entries. Records exceeding this limit are invalid.
- `userIdentifiers` entries must each contain exactly one identifier type: email, phone number, or address info. Mixing types within the same numeric suffix is not allowed and is enforced at schema validation time.
- Address-based `userIdentifiers` require all seven address fields for the same numeric suffix: `first_name`, `last_name`, `city`, `state`, `country_code`, `postal_code`, and `street_address`.
- The query schema must include exactly one conversion identifier column (or one group of `encrypted_user_id_candidates*` columns). Having zero or more than one identifier group is rejected at schema validation before any records are processed.
- When using encrypted user IDs (`include_encrypted: true`), the `encryption_entity_id` must be provided.
- Custom variable entries require both `custom_variable_type` and `custom_variable_value` for the same suffix.
- Cart data item entries require all three item fields for the same suffix: `cart_data_item_id`, `cart_data_item_quantity`, and `cart_data_item_unit_price`.


## Use the Treasure Console

### Create a New Connection

Before running your query, you must create and configure the data connection on the Treasure Console. As part of the data connection, you provide authentication to access the integration.

1. Open **Treasure Console**.
2. Navigate to **Integrations Hub** > **Catalog**.
3. Search for and select **Google Campaign Manager Enhanced Conversions**. Select **Create Authentication**.


![](/assets/new_connection_1.4eebbb96eddacd601d1d39daaaa962111403ef5d861014f57ce88905e6383fcd.4ced5e4f.webp)

1. Select the credentials to authenticate.


![](/assets/new_connection_2.765c422a4948f7cb67d23240dac5bce296858b4d2c4208c835979e37cc99b591.4ced5e4f.webp)

1. Optionally, select **Sign in with Google** and log in to Google.
2. Return to **Integrations Hub** > **Catalog**.
3. Search for and select **Google Campaign Manager Enhanced Conversions**.
4. The New Authentication dialog opens.
5. Select the OAuth connection with your account name in the dropdown list.
6. Select **Continue**.
7. Name the connection.
8. Select **Done**.


### Define your Query

The Treasure Console supports multiple ways to export data. Complete the following steps to export data from Data Workbench.

1. Navigate to **Data Workbench > Queries**.
2. Select **New Query** and define your query.
3. Select **Export Results** to configure the data export.
4. Select an existing Google CM360 Enhanced Conversions authentication or create a new one as described previously.
5. Configure the export parameters.
6. Select **Done**.


#### Connector Configuration Parameters

| Field | Description | Required | Default |
|  --- | --- | --- | --- |
| **Profile ID** | Your CM360 User Profile ID. Must be a positive numeric value. | Yes |  |
| **Mode** | Upload mode. `ADD` inserts new conversions via `batchinsert`. `UPDATE` modifies existing conversions via `batchupdate`. | No | `ADD` |
| **Include Encrypted** | Enable this when your query contains `encrypted_user_id` or `encrypted_user_id_candidates` columns. When enabled, `Encryption Entity ID` is required. | No | `false` |
| **Encryption Entity Type** | The entity type associated with the encryption key. Only used when **Include Encrypted** is enabled. Accepted values:- ENCRYPTION_ENTITY_TYPE_UNKNOWN
- DCM_ACCOUNT
- DCM_ADVERTISER
- DBM_PARTNER
- DBM_ADVERTISER
- ADWORDS_CUSTOMER
- DFP_NETWORK_CODE

 | No | `ENCRYPTION_ENTITY_TYPE_UNKNOWN` |
| **Encryption Entity ID** | The ID of the entity matching the encryption type. | Yes when **Include Encrypted** is checked. |  |
| **Encryption Source** | The source of encryption. Only used when **Include Encrypted** is enabled. Accepted values:- ENCRYPTION_SCOPE_UNKNOWN
- AD_SERVING
- DATA_TRANSFER

 | Yes when **Include Encrypted** is checked. | `ENCRYPTION_SCOPE_UNKNOWN` |
| **Skip Invalid Records** | When enabled, invalid records are skipped and the job continues. When disabled, the job stops on the first invalid record. | No | `true` |


## Query Data Specifications

To upload conversion data to Campaign Manager, your export query must include a combination of required and optional columns. Column names are matched **case-insensitively** and whitespace is trimmed. Columns with `NULL` values are skipped for that record; if the column is required, the record is considered invalid.

### Export Query Specifications

| Specification | Description |
|  --- | --- |
| **Required Fields** | Every conversion record must include all of the following columns:- `floodlight_configuration_id`
- `floodlight_activity_id`
- `timestamp_micros`
- `value`
- `quantity`
- `ordinal`

 |
| **Required Identifier (Exactly one)**
 | The schema must include exactly one conversion identifier. This is enforced at schema validation time — having zero or more than one identifier column group causes the job to fail before processing any records.
Include exactly one of the following in your query:
- `encrypted_user_id`
- `gclid`
- `mobile_device_id`
- `match_id`
- `dclid`
- `impression_id`
- One or more `encrypted_user_id_candidates` columns (e.g., `encrypted_user_id_candidates`, `encrypted_user_id_candidates1`, `encrypted_user_id_candidates2`, ...) — all such columns together count as one identifier group.

For example, having both `gclid` and `match_id` in the same query schema is invalid.
 |
| **Custom Variables** | Custom Floodlight variable pairs require both columns for each numeric suffix:- `custom_variable_type` / `custom_variable_type[N]` (Example `custom_variable_type1`, `custom_variable_type2`...)
- `custom_variable_value` / `custom_variable_value[N]` (Example `custom_variable_value1`, `custom_variable_value2`...)

 |
| **Cart Data Items**
 | Cart data item entries require all three columns for each numeric suffix:
- `cart_data_item_id` / `cart_data_item_id[N]` (Example `cart_data_item_id1`, `cart_data_item_id2`...)
- `cart_data_item_quantity` / `cart_data_item_quantity[N]` (Example `cart_data_item_quantity1`, `cart_data_item_quantity2`...)
- `cart_data_item_unit_price` / `cart_data_item_unit_price[N]` (Example `cart_data_item_unit_price1`, `cart_data_item_unit_price2`...)

When any cart data item column is present, the top-level cart data fields (`merchant_id`, `merchant_feed_label`, `merchant_feed_language`) are also required.
 |
| **UserIdentifier Address Completeness** | When any address field is present for a given numeric suffix, all seven address fields for that suffix must be present:- `first_name` / `first_name[N]`
- `last_name` / `last_name[N]`
- `city` / `city[N]`
- `state` / `state[N]`
- `country_code` / `country_code[N]`
- `postal_code` / `postal_code[N]`
- `street_address` / `street_address[N]`

 |
| **Duplicate Columns** | Duplicate column names are not allowed. |
| **Null Value Handling** | Columns with NULL values are skipped for that record. |
| **PII Hashing** | The following fields are normalized and SHA-256 hashed automatically if raw (unhashed) values are provided. If a value is already a 64-character hex string, it is used as-is:- `email` / `email[N]`
- `phone_number` / `phone_number[N]`
- `first_name` / `first_name[N]`
- `last_name` / `last_name[N]`
- `street_address` / `street_address[N]`

 |
| **UserIdentifier Limit** | Each conversion may contain a maximum of 5 `userIdentifiers` entries across all email, phone number, and address identifier columns. |
| **UserIdentifier Type Exclusivity** | A single `userIdentifier` entry (grouped by numeric suffix) may contain only one type of identifier: email, phone number, or address. Mixing types within the same suffix is not allowed.
Example:
Valid — each suffix contains only one type:- email1: "user@example.com"
- email2: "user@example.com"
- phone_number3: "+1-555-0100"
Invalid - suffix 1 mixes email and phone:
- email1: "user@example.com"
- phone_number1: "+1-555-0100"

 |


### Field/Column-Level Specifications

#### Required Conversion Fields

| Field (Column Name) | Description | Required | Data Type | Notes |
|  --- | --- | --- | --- | --- |
| `floodlight_configuration_id` | The ID of the Floodlight configuration associated with this conversion. | Yes | String (int64 format) or Long | Must be a positive numeric value. |
| `floodlight_activity_id` | The ID of the Floodlight activity. | Yes | String (int64 format) or Long | Must be a positive numeric value. |
| `timestamp_micros` | The timestamp of the conversion event in microseconds since the Unix epoch. | Yes | Long | Must be a positive numeric value. |
| `value` | The monetary value of the conversion. | Yes | Double or Long |  |
| `quantity` | The number of items converted. | Yes | Long | Must be a positive numeric value. |
| `ordinal` | A unique string used to deduplicate multiple conversions for the same click. | Yes | String |  |


#### Conversion Identifier Fields (Only one required)

| Field (Column Name) | Description | Required | Data Type | Notes |
|  --- | --- | --- | --- | --- |
| `encrypted_user_id` | An encrypted cookie user ID. | Conditional* | String | Requires `include_encrypted: true` in the connector configuration. |
| `encrypted_user_id_candidates`, `encrypted_user_id_candidates1`, `encrypted_user_id_candidates2`, ... | A list of encrypted user ID candidates. Multiple columns are combined into a single list. | Conditional* | String | Each non-blank value is added to the candidates list. Requires `include_encrypted: true` in the connector configuration. |
| `gclid` | Google Click ID associated with the conversion. | Conditional* | String |  |
| `mobile_device_id` | Mobile device ID associated with the conversion. | Conditional* | String |  |
| `match_id` | Custom match ID. | Conditional* | String |  |
| `dclid` | Display Click ID. | Conditional* | String |  |
| `impression_id` | Impression ID for view-through conversions. | Conditional* | String |  |


*Only one of these fields must have a non-null value per record.

#### Optional Conversion Fields

| Field (Column Name) | Description | Data Type | Notes |
|  --- | --- | --- | --- |
| `limit_ad_tracking` | Whether ad tracking is limited for this device. | Boolean |  |
| `child_directed_treatment` | Whether the conversion is for a child-directed site. | Boolean |  |
| `non_personalized_ad` | Whether the conversion is associated with a non-personalized ad. | Boolean |  |
| `treatment_for_underage` | Whether the conversion should apply treatment for underage users. | Boolean |  |
| `ad_user_data_consent` | Consent status for user data. Accepted values: `GRANTED`, `DENIED`. | String |  |
| `session_attributes_encoded` | Base64-encoded session attributes. | String |  |


#### User Identifier (PII) Fields

These columns populate the `userIdentifiers` array on each conversion, which is used for enhanced user matching. Multiple identifiers can be provided using numeric suffixes (e.g., `email`, `email1`, `email2`). Each suffix groups related fields into a single `UserIdentifier` entry. A record may contain at most 5 `userIdentifiers` entries total.

Each `UserIdentifier` entry must be one of the following types:

**Email**

| Column Name | Data Type | Normalization and Hashing |
|  --- | --- | --- |
| `email`, `email1`, `email2`, ... | String | Converted to lowercase. For Gmail and Googlemail addresses, dots (`.`) are removed from the local part. Then SHA-256 hashed. If already a 64-character hex string, used as-is. |


**Phone Number**

| Column Name | Data Type | Normalization and Hashing |
|  --- | --- | --- |
| `phone_number`, `phone_number1`, `phone_number2`, ... | String | Must be in E.164 format. Otherwise Non-digit characters removed, then `+` prepended. Then SHA-256 hashed. If already a 64-character hex string, used as-is. |


**Address Info (all seven fields required per suffix)**

| Column Name | Data Type | Normalization and Hashing |
|  --- | --- | --- |
| `first_name`, `first_name1`, `first_name2`, ... | String | Converted to lowercase, whitespace removed. Then SHA-256 hashed. |
| `last_name`, `last_name1`, `last_name2`, ... | String | Converted to lowercase, punctuation removed. Then SHA-256 hashed. |
| `street_address`, `street_address1`, `street_address2`, ... | String | Converted to lowercase. Then SHA-256 hashed. |
| `city`, `city1`, `city2`, ... | String | Not hashed. |
| `state`, `state1`, `state2`, ... | String | Not hashed. |
| `country_code`, `country_code1`, `country_code2`, ... | String | Not hashed. Use 2-letter ISO 3166-1 alpha-2 code. |
| `postal_code`, `postal_code1`, `postal_code2`, ... | String | Not hashed. |


#### Cart Data Fields

Cart data enriches conversion records with shopping cart information. When any cart data column is present, the three top-level cart data fields are required.

**Top-level cart data fields (required when any cart data is used)**

| Column Name | Description | Data Type |
|  --- | --- | --- |
| `merchant_id` | Merchant Center ID. | String or Long |
| `merchant_feed_label` | The feed label associated with the Merchant Center account. | String |
| `merchant_feed_language` | The language of the Merchant Center feed. | String |


**Cart data item fields (use numeric suffixes for multiple items)**

| Column Name | Description | Data Type |
|  --- | --- | --- |
| `cart_data_item_id`, `cart_data_item_id1`, ... | The shopping ID of the item. | String |
| `cart_data_item_quantity`, `cart_data_item_quantity1`, ... | Number of items sold. | Long |
| `cart_data_item_unit_price`, `cart_data_item_unit_price1`, ... | Unit price excluding tax, shipping, and any transaction level discounts. | Double or Long |


Each set of three item fields grouped by the same numeric suffix represents one cart item. All three fields must be present for each suffix.

#### Custom Floodlight Variable Fields

Custom variables can be attached to each conversion to pass additional data to Floodlight.

| Column Name | Description | Data Type |
|  --- | --- | --- |
| `custom_variable_type`, `custom_variable_type1`, `custom_variable_type2`, ... | The type key for the custom Floodlight variable (e.g., `U1`). | String |
| `custom_variable_value`, `custom_variable_value1`, `custom_variable_value2`, ... | The value for the custom Floodlight variable. | String |


Both `custom_variable_type` and `custom_variable_value` must be present for each numeric suffix.

### Example Query


```sql
SELECT
    floodlight_configuration_id,
    floodlight_activity_id,
    timestamp_micros,
    value,
    quantity,
    ordinal,
    gclid,
    email,
    phone_number1,
    first_name2,
    last_name2,
    city2,
    state2,
    country_code2,
    postal_code2,
    street_address2,
    ad_user_data_consent,
    merchant_id,
    merchant_feed_label,
    merchant_feed_language,
    cart_data_item_id1,
    cart_data_item_quantity1,
    cart_data_item_unit_price1,
    custom_variable_type1,
    custom_variable_value1
FROM conversions_tbl
```

### (Optional) Schedule Query Export Jobs

You can use Scheduled Jobs with Result Export to periodically write the output result to a target destination that you specify.

Treasure Data's scheduler feature supports periodic query execution to achieve high availability.

When two specifications provide conflicting schedule specifications, the specification requesting to execute more often is followed while the other schedule specification is ignored.

For example, if the cron schedule is `'0 0 1 * 1'`, then the 'day of month' specification and 'day of week' are discordant because the former specification requires it to run every first day of each month at midnight (00:00), while the latter specification requires it to run every Monday at midnight (00:00). The latter specification is followed.

#### Scheduling your Job Using Treasure Console

1. Navigate to **Data Workbench > Queries**
2. Create a new query or select an existing query.
3. Next to **Schedule**, select None.
![](/assets/image2021-1-15_17-28-51.f1b242f6ecc7666a0097fdf37edd1682786ec11ef80eff68c66f091bc405c371.0f87d8d4.png)
4. In the drop-down, select one of the following schedule options:
![](/assets/image2021-1-15_17-29-47.45289a1c99256f125f4d887e501e204ed61f02223fde0927af5f425a89ace0c0.0f87d8d4.png)
| Drop-down Value | Description |
|  --- | --- |
| Custom cron... | Review [Custom cron... details](#custom-cron-details). |
| @daily (midnight) | Run once a day at midnight (00:00 am) in the specified time zone. |
| @hourly (:00) | Run every hour at 00 minutes. |
| None | No schedule. |


#### Custom cron... Details

![](/assets/image2021-1-15_17-30-23.0f94a8aa5f75ea03e3fec0c25b0640cd59ee48d1804a83701e5f2372deae466c.0f87d8d4.png)

| **Cron Value** | **Description** |
|  --- | --- |
| `0 * * * *` | Run once an hour. |
| `0 0 * * *` | Run once a day at midnight. |
| `0 0 1 * *` | Run once a month at midnight on the morning of the first day of the month. |
| "" | Create a job that has no scheduled run time. |



```
 *    *    *    *    *
 -    -    -    -    -
 |    |    |    |    |
 |    |    |    |    +----- day of week (0 - 6) (Sunday=0)
 |    |    |    +---------- month (1 - 12)
 |    |    +--------------- day of month (1 - 31)
 |    +-------------------- hour (0 - 23)
 +------------------------- min (0 - 59)
```

The following named entries can be used:

- Day of Week: sun, mon, tue, wed, thu, fri, sat.
- Month: jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec.


A single space is required between each field. The values for each field can be composed of:

div
| Field Value  | Example  | Example Description  |
|  --- | --- | --- |
| A single value, within the limits displayed above for each field. |  |  |
| A wildcard `'*'` to indicate no restriction based on the field. | `'0 0 1 * *'` | Configures the schedule to run at midnight (00:00) on the first day of each month. |
| A range `'2-5'`, indicating the range of accepted values for the field. | `'0 0 1-10 * *'` | Configures the schedule to run at midnight (00:00) on the first 10 days of each month. |
| A list of comma-separated values `'2,3,4,5'`, indicating the list of accepted values for the field. | `'0 0 1,11,21 * *'` | Configures the schedule to run at midnight (00:00) every 1st, 11th, and 21st day of each month. |
| A periodicity indicator `'*/5'` to express how often based on the field's valid range of values a schedule is allowed to run. | `'30 */2 1 * *'` | Configures the schedule to run on the 1st of every month, every 2 hours starting at 00:30. `'0 0 */5 * *'` configures the schedule to run at midnight (00:00) every 5 days starting on the 5th of each month. |
| A comma-separated list of any of the above except the `'*'` wildcard is also supported `'2,*/5,8-10'`. | `'0 0 5,*/10,25 * *'` | Configures the schedule to run at midnight (00:00) every 5th, 10th, 20th, and 25th day of each month. |


1. (Optional) You can delay the start time of a query by enabling the Delay execution.


### Execute the Query

Save the query with a name and run, or just run the query. Upon successful completion of the query, the query result is automatically exported to the specified destination.

Scheduled jobs that continuously fail due to configuration errors may be disabled on the system side after several notifications.

(Optional) You can delay the start time of a query by enabling the Delay execution.

## Activate a Segment in Audience Studio

You can also send segment data to the target platform by creating an activation in the Audience Studio.

1. Navigate to **Audience Studio**.
2. Select a parent segment.
3. Open the target segment, right-mouse click, and then select **Create Activation.**
4. In the **Details** panel, enter an Activation name and configure the activation according to the previous section on Configuration Parameters.
5. Customize the activation output in the **Output Mapping** panel.


![](/assets/ouput.b2c7f1d909c4f98ed10f5300df858a4b19f71a3b0834df952f5fb24018a5ea78.8ebdf569.png)

- Attribute Columns
  - Select **Export All Columns** to export all columns without making any changes.
  - Select **+ Add Columns** to add specific columns for the export. The Output Column Name pre-populates with the same Source column name. You can update the Output Column Name. Continue to select **+ Add Columns**to add new columns for your activation output.
- String Builder
  - **+ Add string** to create strings for export. Select from the following values:
    - String: Choose any value; use text to create a custom value.
    - Timestamp: The date and time of the export.
    - Segment Id: The segment ID number.
    - Segment Name: The segment name.
    - Audience Id: The parent segment number.


1. Set a **Schedule**.


![](/assets/snippet-output-connector-on-audience-studio-2024-08-28.a99525173709da1eb537f839019fa7876ffae95045154c8f2941b030022f792c.8ebdf569.png)

- Select the values to define your schedule and optionally include email notifications.


1. Select **Create**.


If you need to create an activation for a batch journey, review [Creating a Batch Journey Activation](/products/customer-data-platform/journey-orchestration/batch/creating-a-batch-journey-activation).

## (Optional) Export Integration Using the CLI

The [TD Toolbelt](https://toolbelt.treasuredata.com/) can trigger the Query Result exporting from a CLI. You need to specify the parameters for the exporting job using the `--result` option of the `td query` command. For more information, please refer to [this article](/tools/cli-and-sdks/querying-and-importing-data-to-treasure-data-from-the-command-line).

The format of the option is JSON, and the general structure is as follows.


```json
{
  "type": "google_cm360_enhanced_conversions",
  "td_authentication_id": "${authentication_id_from_td_console}",
  "profile_id": "123456789",
  "mode": "ADD",
  "include_encrypted": true,
  "encryption_entity_type": "ENCRYPTION_ENTITY_TYPE_UNKNOWN",
  "encryption_entity_id": "123",
  "encryption_source": "ENCRYPTION_SCOPE_UNKNOWN",
  "skip_invalid_records": true
}
```

### Parameters

| Name | Description | Value | Default | Required |
|  --- | --- | --- | --- | --- |
| `type` | Connector type identifier. | `google_cm360_enhanced_conversions` |  | Yes |
| `td_authentication_id` | This is the ID of the existing Google Campaign Manager Enhanced Conversions authentication on the Treasure Console. | Number |  | Yes |
| `profile_id` | Campaign Manager User Profile ID. Must be a positive numeric value. | String |  | Yes |
| `mode` | Upload mode. `ADD` uses `batchinsert`, `UPDATE` uses `batchupdate`. | `ADD` / `UPDATE` | `ADD` | No |
| `include_encrypted` | Enable when using encrypted user ID columns (`encrypted_user_id` or `encrypted_user_id_candidates[N]`). | `true` / `false` | `false` | No |
| `encryption_entity_type` | Encryption entity type. | String. Accept values:- ENCRYPTION_ENTITY_TYPE_UNKNOWN
- DCM_ACCOUNT
- DCM_ADVERTISER
- DBM_PARTNER
- DBM_ADVERTISER
- ADWORDS_CUSTOMER
- DFP_NETWORK_CODE

 | `ENCRYPTION_ENTITY_TYPE_UNKNOWN` | No |
| `encryption_entity_id` | ID of the entity matching the encryption type. | String |  | Yes if `include_encrypted` is true |
| `encryption_source` | Source of encryption. | String. Accept values:- ENCRYPTION_SCOPE_UNKNOWN
- AD_SERVING
- DATA_TRANSFER

 | `ENCRYPTION_SCOPE_UNKNOWN` | No |
| `skip_invalid_records` | Skip invalid records and continue the job instead of stopping. | `true` / `false` | `true` | No |


### Example Usage

**ADD mode (insert new conversions)**


```bash
td query \
  --result '{"type":"google_cm360_enhanced_conversions","td_authentication_id": "xxxx","profile_id":"123456789","mode":"ADD","skip_invalid_records":true}' \
  -d my_database \
  "SELECT floodlight_configuration_id, floodlight_activity_id, timestamp_micros, value, quantity, ordinal, gclid FROM conversions" \
  -T presto
```

**UPDATE mode**


```bash
td query \
  --result '{"type":"google_cm360_enhanced_conversions","td_authentication_id": "xxxx","profile_id":"123456789","mode":"UPDATE","skip_invalid_records":true}' \
  -d my_database \
  "SELECT floodlight_configuration_id, floodlight_activity_id, timestamp_micros, value, quantity, ordinal, gclid FROM conversions" \
  -T presto
```