From 1b78a43ef34b54f801c73b91559f1584ccf2fc98 Mon Sep 17 00:00:00 2001 From: julia-rabello <77292838+julia-rabello@users.noreply.github.com> Date: Tue, 14 Oct 2025 01:17:39 -0300 Subject: [PATCH 1/3] new(guides): VTEX Ads docs migration --- docs/localization/exporting-ads-events.md | 107 ++++++++ docs/localization/exporting-ads-reports.md | 177 +++++++++++++ ...exporting-aggregated-data-from-vtex-ads.md | 124 +++++++++ .../exporting-data-from-vtex-ads.md | 37 +++ docs/localization/integrating-audiences.md | 109 ++++++++ ...ing-vtex-ads-with-external-marketplaces.md | 246 ++++++++++++++++++ .../placement-naming-conventions.md | 34 +++ .../segmenting-campaigns-by-pii.md | 72 +++++ docs/localization/transferring-credit.md | 83 ++++++ docs/localization/transferring-credit.png | Bin 0 -> 54641 bytes docs/localization/vtex-ads-best-practices.md | 35 +++ docs/localization/vtex-ads-best-practices.png | Bin 0 -> 77889 bytes docs/localization/vtex-ads-script-agent.md | 88 +++++++ .../vtex-ads-single-sign-on-sso.md | 51 ++++ 14 files changed, 1163 insertions(+) create mode 100644 docs/localization/exporting-ads-events.md create mode 100644 docs/localization/exporting-ads-reports.md create mode 100644 docs/localization/exporting-aggregated-data-from-vtex-ads.md create mode 100644 docs/localization/exporting-data-from-vtex-ads.md create mode 100644 docs/localization/integrating-audiences.md create mode 100644 docs/localization/integrating-vtex-ads-with-external-marketplaces.md create mode 100644 docs/localization/placement-naming-conventions.md create mode 100644 docs/localization/segmenting-campaigns-by-pii.md create mode 100644 docs/localization/transferring-credit.md create mode 100644 docs/localization/transferring-credit.png create mode 100644 docs/localization/vtex-ads-best-practices.md create mode 100644 docs/localization/vtex-ads-best-practices.png create mode 100644 docs/localization/vtex-ads-script-agent.md create mode 100644 docs/localization/vtex-ads-single-sign-on-sso.md diff --git a/docs/localization/exporting-ads-events.md b/docs/localization/exporting-ads-events.md new file mode 100644 index 0000000000..4731f83097 --- /dev/null +++ b/docs/localization/exporting-ads-events.md @@ -0,0 +1,107 @@ +--- +title: "Exporting ads events" +slug: "exporting-ads-events" +excerpt: "Export raw advertising event data including impressions, clicks, views, and conversions for detailed analysis." +hidden: false +createdAt: "2025-10-13T00:00:00.000Z" +updatedAt: "2025-10-14T00:00:00.000Z" +--- +Event data export enables systematic and periodic integration of raw advertising events for detailed analysis and custom reporting. + +## Integration connection + +See more about the connection in [Exporting data from VTEX Ads](https://developers.vtex.com/docs/guides/exporting-data-from-vtex-ads). + +## Integration format + +- Data sent is always D-1 (previous day) +- Files are in [Parquet](https://parquet.apache.org/docs/overview/) format with [Snappy](https://parquet.apache.org/docs/file-format/data-pages/compression/) compression +- Files are always sent in a daily path format: `TYPE_REPORT/YYYY/MM/DD/TIMESTAMP_NS/RANDOM_FILE_NAMES.snappy.parquet` (one or more files may be sent) + +> 🚧 Event deduplication +> +> All events are guaranteed to be sent, but there is no guarantee that an event will be sent only once. Therefore, events must always be deduplicated. + +## Event data + +### Impressions + +| Attribute | Type | Description | +| :------------- | :------------ | :-------------------------------------------------------------- | +| event_id | String | Unique event identifier **(deduplication key)** | +| session_id | String | Unique user session identifier | +| user_id | String | Unique user identifier | +| ad_id | String | Advertisement identifier | +| campaign_id | String | Unique campaign identifier | +| request_id | String | Unique ad query request identifier | +| ad_type | String | Type of advertisement that generated the event | +| placement_name | String | Name of the placement where the ad was displayed | +| context | String | Context in which the ad was displayed | +| created_at | Timestamp UTC | Timestamp of when the event occurred | +| site | String | Site brand identifier | + +### Views + +| Attribute | Type | Description | +| :------------- | :------------ | :-------------------------------------------------------------- | +| event_id | String | Unique event identifier **(deduplication key)** | +| session_id | String | Unique user session identifier | +| user_id | String | Unique user identifier | +| ad_id | String | Advertisement identifier | +| campaign_id | String | Unique campaign identifier | +| request_id | String | Unique ad query request identifier | +| ad_type | String | Type of advertisement that generated the event | +| placement_name | String | Name of the placement where the ad was displayed | +| context | String | Context in which the ad was displayed | +| created_at | Timestamp UTC | Timestamp of when the event occurred | +| site | String | Site brand identifier | + +### Clicks + +| Attribute | Type | Description | +| :------------- | :------------ | :-------------------------------------------------------------- | +| event_id | String | Unique event identifier **(deduplication key)** | +| session_id | String | Unique user session identifier | +| user_id | String | Unique user identifier | +| ad_id | String | Advertisement identifier | +| campaign_id | String | Unique campaign identifier | +| request_id | String | Unique ad query request identifier | +| ad_type | String | Type of advertisement that generated the event | +| placement_name | String | Name of the placement where the ad was displayed | +| context | String | Context in which the ad was displayed | +| created_at | Timestamp UTC | Timestamp of when the event occurred | +| site | String | Site brand identifier | + +### Conversions + +| Attribute | Type | Description | +| :--------- | :------------ | :----------------------------------------------------- | +| event_id | String | Unique conversion event identifier | +| session_id | String | Unique user session identifier | +| user_id | String | Unique user identifier | +| order_id | String | Unique retail order identifier **(deduplication key)** | +| channel | String | Channel identifier | +| placed_at | Timestamp UTC | Order timestamp | +| site | String | Site brand identifier | + +### Conversion items + +| Attribute | Type | Description | +| :---------------- | :-------- | :-------------------------------------------------------------- | +| event_id | String | Unique identifier of the event that generated the conversion (view or click) | +| session_id | String | Unique user session identifier | +| user_id | String | Unique user identifier | +| order_id | String | Unique retail order identifier **(deduplication key)** | +| product_sku | String | Product identifier **(deduplication key)** | +| ad_id | String | Unique advertisement identifier | +| campaign_id | String | Unique campaign identifier | +| request_id | String | Unique ad query request identifier | +| ad_size | String | Size of the media used in the advertisement | +| ad_type | String | Type of advertisement that generated the conversion | +| placement_name | String | Name of the placement where the ad was displayed | +| context | String | Context in which the ad was displayed | +| event_created_at | Timestamp | Timestamp of when the event occurred | +| price | Float | Product price (regular) | +| promotional_price | Float | Product promotional price | +| quantity | Int | Quantity of items sold | +| total_value | Float | Total item value (quantity * min(price, promotional_price)) | diff --git a/docs/localization/exporting-ads-reports.md b/docs/localization/exporting-ads-reports.md new file mode 100644 index 0000000000..20b4fd2c40 --- /dev/null +++ b/docs/localization/exporting-ads-reports.md @@ -0,0 +1,177 @@ +--- +title: "Exporting ads reports" +slug: "exporting-ads-reports" +excerpt: "Access and download platform data automatically through API endpoints with JSON or XLSX export options." +hidden: false +createdAt: "2025-10-13T00:00:00.000Z" +updatedAt: "2025-10-14T00:00:00.000Z" +--- +Report export allows you to access and download platform information automatically, without the need for manual extraction through the interface. All report routes return data in JSON format by default, but can be exported as XLSX files by including the `download=true` parameter in the query. + +> â„šī¸ API Authentication +> +> To access the routes, users must be authenticated. See the [authentication documentation](https://newtail-media.readme.io/reference/autenticacao) for more details. + +> âš ī¸ Limited availability of some reports +> +> Export of certain reports may be restricted based on the account type associated with the authentication. Not all users will have access to all available reports. + +## Reports + +### Advertisers + +This endpoint allows you to search for information from all advertisers associated with a publisher account. Data is returned in JSON format by default, but can be exported as XLSX by adding the `download=true` parameter to the query string. + +> â„šī¸ Only available in publisher view. + +#### Request + +``` +GET https://api-retail-media.newtail.com.br/report/v2/advertisers?start_date=2025-01-01&end_date=2025-01-01 HTTP/1.1 +accept: application/json +content-type: application/json +x-app-id: +x-api-key: +``` + +#### Query parameters + +| Parameter | Required | Description | +| :----------- | :------- | :-------------------------------------------------------------------------------- | +| start_date | Yes | Metrics start date in `YYYY-MM-DD` format | +| end_date | Yes | Metrics end date in `YYYY-MM-DD` format | +| account_info | No | If true, includes detailed account information in the result. Default is `false` | +| page | No | Page number of results. Default is `1` | +| quantity | No | Number of items per page. Default is `100` | +| count | No | If `true`, returns the total number of available records. Default is `false` | +| download | No | If `true`, returns an XLSX file buffer ready for download instead of JSON | + +### Publishers + +This endpoint allows you to search for publisher information. Data is returned in JSON format by default, but can be exported as XLSX by including the `download=true` parameter in the query string. + +> â„šī¸ Only available in advertiser view. + +#### Request + +``` +GET https://api-retail-media.newtail.com.br/report/v2/publishers?start_date=2025-01-01&end_date=2025-01-01 HTTP/1.1 +accept: application/json +content-type: application/json +x-app-id: +x-api-key: +``` + +#### Query parameters + +| Parameter | Required | Description | +| :-------------- | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| start_date | Yes | Metrics start date in `YYYY-MM-DD` format | +| end_date | Yes | Metrics end date in `YYYY-MM-DD` format | +| publisher_name | No | Filters results by publisher name | +| account_info | No | If true, includes detailed account information in the result. Default is `false` | +| page | No | Page number of results. Default is `1` | +| quantity | No | Number of items per page. Default is `100` | +| count | No | If `true`, returns the total number of available records. Default is `false` | +| order_by | No | Defines the field for sorting results. Possible values: `name, balance, total_daily_budget, total_campaigns, impressions, clicks, ctr, total_spent, conversions, conversion_rate, income, roas` | +| order_direction | No | Defines the sorting direction. Possible values: `asc` (ascending) or `desc` (descending) | +| download | No | If `true`, returns an XLSX file buffer ready for download instead of JSON | + +### Network publishers + +This endpoint allows you to search for information about publishers associated with a **Network** type Publisher account. Data is returned in JSON format by default, but can be exported as XLSX by including the `download=true` parameter in the query string. + +> â„šī¸ Only publishers operating in Network format have permission to access this report. + +#### Request + +``` +GET https://api-retail-media.newtail.com.br/report/network/publishers?start_date=2025-01-01&end_date=2025-01-01 HTTP/1.1 +accept: application/json +content-type: application/json +x-app-id: +x-api-key: +``` + +#### Query parameters + +| Parameter | Required | Description | +| :-------------- | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------------- | +| start_date | Yes | Metrics start date in `YYYY-MM-DD` format | +| end_date | Yes | Metrics end date in `YYYY-MM-DD` format | +| publisher_name | No | Filters results by publisher name | +| account_info | No | If true, includes detailed account information in the result. Default is `false` | +| page | No | Page number of results. Default is `1` | +| quantity | No | Number of items per page. Default is `100` | +| count | No | If `true`, returns the total number of available records. Default is `false` | +| order_by | No | Defines the field for sorting results. Possible values: `name, impressions, clicks, ctr, conversions, conversion_rate, income, roas, requests` | +| order_direction | No | Defines the sorting direction. Possible values: `asc` (ascending) or `desc` (descending) | +| download | No | If `true`, returns an XLSX file buffer ready for download instead of JSON | + +### Campaigns + +This endpoint allows you to search for all available campaigns, applying filters as needed. Data is returned in JSON format by default, but can be exported as XLSX by including the `download=true` parameter in the query string. + +#### Request + +``` +GET https://api-retail-media.newtail.com.br/campaign/v2?start_date=2025-01-01&end_date=2025-01-01 HTTP/1.1 +accept: application/json +content-type: application/json +x-app-id: +x-api-key: +``` + +#### Query parameters + +| Parameter | Required | Description | +| :-------------- | :------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| start_date | Yes | Metrics start date in `YYYY-MM-DD` format | +| end_date | Yes | Metrics end date in `YYYY-MM-DD` format | +| status | No | Filters by campaign status | +| advertiser_id | No | Filters campaigns by advertiser ID | +| ad_type | No | Filters by ad type | +| name | No | Searches campaigns by name | +| account_info | No | If true, includes detailed account information in the result. Default is `false` | +| page | No | Page number of results. Default is `1` | +| quantity | No | Number of items per page. Default is `100` | +| count | No | If `true`, returns the total number of available records. Default is `false` | +| order_by | No | Defines the field for sorting results. Possible values: `name, impressions, clicks, ctr, conversions, conversion_rate, income, roas, created_at, start_at, daily_budget, ad_type, advertiser_name, status` | +| order_direction | No | Defines the sorting direction. Possible values: `asc` (ascending) or `desc` (descending) | +| download | No | If `true`, returns an XLSX file buffer ready for download instead of JSON | + +### Ads + +This endpoint allows you to search for all available ads, applying filters as needed. Data is returned in JSON format by default, but can be exported as XLSX by including the `download=true` parameter in the query string. + +#### Request + +``` +GET https://api-retail-media.newtail.com.br/ad/results/v2?start_date=2025-01-01&end_date=2025-01-01 HTTP/1.1 +accept: application/json +content-type: application/json +x-app-id: +x-api-key: +``` + +#### Query parameters + +| Parameter | Required | Description | +| :-------------- | :------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| start_date | Yes | Metrics start date in `YYYY-MM-DD` format | +| end_date | Yes | Metrics end date in `YYYY-MM-DD` format | +| campaign_name | No | Filters ads by campaign name | +| campaign_id | No | Filters ads by campaign ID | +| advertiser_id | No | Filters ads by advertiser ID | +| product_sku | No | Filters ads by product SKU | +| ad_status | No | Filters ads by status | +| ad_type | No | Filters by ad type | +| targeting_type | No | Filters by targeting type | +| show_inactive | No | If `true`, includes paused ads | +| account_info | No | If `true`, includes detailed account information in the result. Default is `false` | +| page | No | Page number of results. Default is `1` | +| quantity | No | Number of items per page. Default is `100` | +| count | No | If `true`, returns the total number of available records. Default is `false` | +| order_by | No | Defines the field for sorting results. Possible values: `ad_type, ad_status, impressions, conversion_rate, ctr, income, total_spent, roas, conversions, total_conversions_item_quantity` | +| order_direction | No | Defines the sorting direction. Possible values: `asc` (ascending) or `desc` (descending) | +| download | No | If `true`, returns an XLSX file buffer ready for download instead of JSON | diff --git a/docs/localization/exporting-aggregated-data-from-vtex-ads.md b/docs/localization/exporting-aggregated-data-from-vtex-ads.md new file mode 100644 index 0000000000..3456f8f528 --- /dev/null +++ b/docs/localization/exporting-aggregated-data-from-vtex-ads.md @@ -0,0 +1,124 @@ +--- +title: "Exporting aggregated data from VTEX Ads" +slug: "exporting-aggregated-data-from-vtex-ads" +excerpt: "Export pre-processed performance metrics and campaign statistics for business intelligence and reporting purposes." +hidden: false +createdAt: "2025-10-13T00:00:00.000Z" +updatedAt: "2025-10-14T00:00:00.000Z" +--- +Aggregated data export enables systematic and periodic integration of pre-processed advertising performance metrics for business intelligence and reporting purposes. + +## Integration connection + +See more about the connection in [Exporting data from VTEX Ads](https://developers.vtex.com/docs/guides/exporting-data-from-vtex-ads). + +## Integration format + +- Data sent is always D-1 (previous day) +- Data is always sent D-1 with the publisher's timezone +- Files are sent in CSV format: + - UTF-8 encoding + - Comma-separated values + - All numbers follow American format with decimal point (".") +- Files are always sent in a daily path format: `TYPE_REPORT/YYYY/MM/DD/TIMESTAMP_NS/RANDOM_FILE_NAMES.csv` (one or more files may be sent) + +## Data to be exported + +> 📘 File examples +> +> Examples of files that will be sent: +> +> +> +> + +### Advertisers + +`advertisers/YYYY/MM/DD/CURRENT_DELIVERY_TIME/RANDOM_FILE_NAME.csv` + +| Column | Type | Description | +| :------------- | :----- | :------------------------------------------------------- | +| advertiser | String | Advertiser name | +| advertiser_id | String | Unique advertiser identifier | +| seller_id | String | Seller identifier | +| wallet_balance | Float | Current balance in the advertiser's wallet | +| daily_budget | Float | Total daily budget sum of all active campaigns | +| currency | String | Currency format the advertiser is operating in (e.g., BRL, USD) | + +### Campaigns + +`campaigns/YYYY/MM/DD/CURRENT_DELIVERY_TIME/RANDOM_FILE_NAME.csv` + +| Column | Type | Description | +| :---------------- | :---------------- | :------------------------------------------------------- | +| day | date YYYY-DD-MM | Day is always sent in the publisher's timezone | +| name | String | Campaign name | +| campaign_id | String | Unique campaign identifier | +| campaign_type | String | Campaign type: `product`, `banner`, `sponsored_brands`, `video` | +| campaign_status | String | Campaign operating status | +| impressions_total | int | Total impressions | +| clicks_total | int | Total clicks | +| ctr | float | Campaign CTR | +| ad_revenue | Float | Ad revenue | +| conversions_total | int | Total conversions | +| conversion_rate | float | Order conversion rate | +| sales_revenue | float | Revenue from sold items | +| start_date | date YYYY-DD-MM | Campaign start date | +| end_date | date YYYY-DD-MM | Campaign end date | +| advertiser_id | String | Unique advertiser identifier | + +### Ads + +`ads/YYYY/MM/DD/CURRENT_DELIVERY_TIME/RANDOM_FILE_NAME.csv` + +| Column | Type | Description | +| :---------------- | :---------------- | :------------------------------------------------------- | +| day | date YYYY-DD-MM | Day is always sent in the publisher's timezone | +| ad_id | String | Unique ad identifier | +| campaign_id | String | Unique campaign identifier | +| ad_status | String | Ad operating status | +| ad_media_url | String | Ad media URL | +| cpm | float | CPM value | +| cpc | float | CPC value | +| impressions_total | int | Total impressions | +| clicks_total | int | Total clicks | +| ctr | float | Ad CTR | +| ad_revenue | float | Ad revenue | +| conversions_total | int | Total conversions generated by the ad | +| conversion_rate | float | Conversion rate | +| sales_revenue | float | Revenue from product sales | +| product_sku | String | List of SKUs separated by semicolon. Note: Product campaigns always have only 1 product per ad | + +### Product ads + +`product_ads/YYYY/MM/DD/CURRENT_DELIVERY_TIME/RANDOM_FILE_NAME.csv` + +| Column | Type | Description | +| :---------------- | :---------------- | :------------------------------------------------------- | +| day | date YYYY-DD-MM | Day is always sent in the publisher's timezone | +| ad_id | String | Unique ad identifier | +| campaign_id | String | Unique campaign identifier | +| advertiser_id | String | Unique advertiser identifier | +| product_sku | String | Product SKU | +| ad_type | String | Ad type | +| ad_media_url | String | Ad media URL | +| cpm | float | CPM value | +| cpc | float | CPC value | +| impressions_total | int | Total impressions | +| clicks_total | int | Total clicks | +| ctr | float | Ad CTR | +| ad_revenue | float | Ad revenue | +| conversions_total | int | Total conversions generated by the ad | +| conversion_rate | float | Conversion rate | +| sales_revenue | float | Revenue from product sales | + +### Catalog + +`catalog/YYYY/MM/DD/CURRENT_DELIVERY_TIME/RANDOM_FILE_NAME.csv` + +| Column | Type | Description | +| :---------- | :----- | :------------------------------------------------------- | +| product_sku | String | Product SKU | +| name | String | Product name | +| categories | String | List of product categories separated by semicolon (e.g., Cat1 > Cat2; ...) | +| image_url | String | Product image URL | diff --git a/docs/localization/exporting-data-from-vtex-ads.md b/docs/localization/exporting-data-from-vtex-ads.md new file mode 100644 index 0000000000..3dc5fa5978 --- /dev/null +++ b/docs/localization/exporting-data-from-vtex-ads.md @@ -0,0 +1,37 @@ +--- +title: "Exporting data from VTEX Ads" +slug: "exporting-data-from-vtex-ads" +excerpt: "Learn how to export data from VTEX Ads using S3-compatible connections for events and aggregated data." +hidden: false +createdAt: "2025-10-13T00:00:00.000Z" +updatedAt: "2025-10-13T00:00:00.000Z" +--- +VTEX Ads provides data export capabilities that allow you to extract campaign events and aggregated performance data. Integration always occurs using an S3-compatible connection that must be provided by the data receiver. + +## Prerequisites + +Before setting up data export, ensure you have: + +- An S3-compatible storage solution configured. +- Proper access credentials for your chosen storage provider. +- Network connectivity between VTEX Ads and your storage endpoint. + +## Credentials + +Credentials must be securely shared with the VTEX team through agreed-upon secure channels. The integration supports the following cloud storage providers: + +- **AWS S3**: Requires `Access Key ID` and `Access Key Secret` +- **Google Cloud Storage**: Requires `Service Account` credentials +- **Azure Blob Storage**: Requires connection string or account key + +> âš ī¸ **Security**: Never share credentials through unsecured channels. Use encrypted communication methods as agreed between parties. + +## Export Types + +VTEX Ads supports three types of data export: + +- **[Event Export](https://developers.vtex.com/docs/guides/exporting-ads-events)**: Export raw event data including clicks, impressions, and conversions for detailed analysis and custom reporting. + +- **[Aggregated Data Export](https://developers.vtex.com/docs/guides/exporting-aggregated-data-from-vtex-ads)**: Export pre-processed performance metrics and campaign statistics for business intelligence and reporting purposes. + +- **[Ads Reports Export](https://developers.vtex.com/docs/guides/exporting-ads-reports)**: Export comprehensive advertising reports with campaign performance data, conversion metrics, and ROI analysis. diff --git a/docs/localization/integrating-audiences.md b/docs/localization/integrating-audiences.md new file mode 100644 index 0000000000..88a9758e5b --- /dev/null +++ b/docs/localization/integrating-audiences.md @@ -0,0 +1,109 @@ +--- +title: "Integrating audiences" +slug: "integrating-audiences" +excerpt: "Integrate customer audience data with VTEX Ads using secure S3-based file delivery and PII hashing." +hidden: false +createdAt: "2025-10-13T00:00:00.000Z" +updatedAt: "2025-10-14T00:00:00.000Z" +--- +## Integration connection + +> 📘 The integration connection will occur through: +> +> - Periodic audience delivery as agreed between parties +> - Delivery to our S3 (access credentials must be requested from your Newtail contact) +> - Files must be sent in `Parquet` format with `Snappy` compression +> - Newtail will provide S3 credentials + +> 🚧 Delivery recommendation +> +> In the initial integration, it is essential that all data be sent. This data can be sent in multiple files (depending on the database size. A good number is 1 million rows per file). +> +> After the first integration, ideally only the delta of rows that have been modified should be sent. + +Files must be written following this directory pattern: + +``` +PREFIX/audiences/YYYY/mm/dd/TIMESTAMP.parquet.snappy +``` + +| Attribute | Description | Example | +| :-------- | :------------------------------------------------------- | :--------- | +| PREFIX | The prefix will be provided by Newtail | xyz | +| YYYY | Generation year with 4 digits | 2023 | +| mm | Generation month with two digits (January = 01, December = 12) | 09 | +| dd | Generation day with two digits (from 01 to 31) | 31 | +| TIMESTAMP | Timestamp is the number of seconds since 1970 (filename can be anything, timestamp is just a suggestion that will never repeat) | 1694812122 | + + +## Audience file + +### Attributes + +Most attributes are not required; however, the more complete this information is, the better the relevance will be. + +> 📘 Columns are case sensitive +> +> Keep the column names exactly as they are presented. + +| Column | Type | Required | Description | +| :---------------- | :----- | :------- | :------------------------------------------------------- | +| CUSTOMER_ID | String | Yes | Unique customer identifier | +| EMAIL_HASHED | String | No | PII based on customer email | +| PHONE_HASHED | String | No | PII based on customer primary phone number | +| SOCIAL_ID_HASHED | String | No | PII based on customer CPF (tax ID) | +| FIRST_NAME_HASHED | String | No | PII based on customer first name | +| LAST_NAME_HASHED | String | No | PII based on customer last name | +| GENDER | String | No | Customer gender: `F` (female), `M` (male), `O` (other), `NULL` (not identified) | +| AGE | Int | No | Customer age | +| CEP | String | No | Customer address postal code | +| COUNTRY | String | No | Customer country | +| STATE | String | No | Customer state of residence | +| CITY | String | No | Customer city of residence | +| NEIGHBORHOOD | String | No | Customer neighborhood of residence | +| AUDIENCES | String | No | List of audiences separated by semicolon (;) | +| NBO_PRODUCTS | String | No | List of product SKUs separated by semicolon (;) | +| NBO_CATEGORIES | String | No | List of categories separated by semicolon (;). Category lists can include category trees using " > " as separator. Example: `Tablets;Beverages > Non-Alcoholic Beverages;Books > Gastronomy > Bar and Restaurant Guides` | + + +### Field hashing + +Confidential data must be encrypted before being sent using the SHA256 algorithm. + +- EMAIL_HASHED +- PHONE_HASHED +- SOCIAL_ID_HASHED +- FIRST_NAME_HASHED +- LAST_NAME_HASHED + +> 📘 Before generating data hash, you must remove all SPACES and convert values to **LOWERCASE**. + +> 🚧 For the PHONE_HASHED attribute, you must format it to the E.164 standard and include the country calling code. + +#### E.164 format + +1. Remove all non-numeric characters, such as spaces, dashes, parentheses, and symbols. +2. Add the country code with a plus sign (+) at the beginning. The country code is a 1 to 3-digit code that identifies the country of the phone number. You can find a list of country codes in the ISO 3166-1 standard. +3. Add the area code (if applicable) without the leading zero. For example, in the United States, the area code consists of three digits and should not start with zero. +4. Include the local phone number without the leading zero (if applicable). + +Examples: + +- A United States phone number with area code 212 and local number 555-1234 would be formatted as: +12125551234 +- A Brazilian phone number with area code 11 and local number 98765-4321 would be formatted as: +5511987654321 + +#### Creating a hash of a formatted attribute using Python + +```python +import re +import hashlib + +hash_obj = hashlib.sha256() + +def create_hash(x): + cleaned = re.sub('\s+', '', x.lower()) + hash_obj.update(cleaned.encode('utf-8')) + return hash_obj.hexdigest() + +create_hash(' Allan ') #=> 8c01ade3cb71d3ac7c718ed5a0c565155a4c05a216d9e59013c5d7b49e916914 +``` diff --git a/docs/localization/integrating-vtex-ads-with-external-marketplaces.md b/docs/localization/integrating-vtex-ads-with-external-marketplaces.md new file mode 100644 index 0000000000..57b76dad17 --- /dev/null +++ b/docs/localization/integrating-vtex-ads-with-external-marketplaces.md @@ -0,0 +1,246 @@ +--- +title: "Integrating VTEX Ads with external marketplaces" +slug: "integrating-vtex-ads-with-external-marketplaces" +excerpt: "Learn how to integrate VTEX Ads with external marketplaces through authentication, catalog management, campaign operations, and SSO implementation." +hidden: false +createdAt: "2025-10-13T00:00:00.000Z" +updatedAt: "2025-10-13T00:00:00.000Z" +--- + +This document describes how to integrate VTEX Ads with external marketplaces through bidirectional authentication, catalog synchronization, and unified campaign management. + +## Authentication + +Authentication occurs bidirectionally, both from the marketplace to VTEX Ads and from VTEX Ads to the marketplace. + +### Marketplace to VTEX Ads + +The connection requires adding two parameters in the request headers sent to VTEX Ads. + +| Header | Description | +| --- | --- | +| `x-app-id` | The App ID identifies the API user | +| `x-api-key` | The API Key identifies the API "password" | + +>â„šī¸ Access credentials must be requested from our [Support](https://support.vtex.com/hc/en-us/requests) team. + +### VTEX Ads to marketplace + +In this scenario, the connection will be from VTEX Ads to the marketplace. To standardize this integration, we will use **Basic Authentication** format in the request. + +| Authentication | Description | +| --- | --- | +| `username` | Username for authentication | +| `password` | User password | + +>â„šī¸ For more information about Basic Authentication functionality, see the [RFC 7617 specification](https://datatracker.ietf.org/doc/html/rfc7617). + +## Catalog + +The catalog API enables product synchronization between marketplaces and VTEX Ads. All product data must include the following attributes: + +| Attribute | Description | Type | Required | +| --- | --- | --- | --- | +| `product_sku` | Unique identifier of the parent product | String | Yes | +| `name` | Product title | String | Yes | +| `image_url` | Public product image URL, can be just a thumbnail | String | No | +| `categories` | List of categories | String | Yes | +| `brand` | Product brand name | String | Yes | +| `gtins` | List of EANs | Array | No | +| `urls` | Product URL information | Array | Yes | +| `urls.site` | Site brand name | String | No | +| `urls.url` | Product URL | String | Yes | +| `stocks` | Product stock information | Array | Yes | +| `stocks.site` | Site brand name | String | No | +| `stocks.seller_id` | Seller ID identifier | String | No | +| `stocks.quantity` | Stock quantity | Float | Yes | +| `metadata` | Information returned during ad queries without modification | Object | No | + +For this step, we need an API to query the retailer's catalog, and this catalog must contain: + +|Attribute|Description| +|:--------|:----------| +|seller_id|Filter by seller identifier.| +|name|Partial search by product name.| +|skus|Filter by a list of SKUs.| +|eans|Filter by a list of EANs.| +|quantity|Number of items that should be returned.| +|page|Current page number. Starts at 0 (zero).| + +```http +GET PREFIX/search?name=&seller_id=&skus=sku1,sku2,...,skuN&eans=ean1,ean2,...,eanN&quantity=&page= +``` + +### Response example - Status 200 + +```json +[ + { + "product_sku": "sku123", + "name": "Red Sneakers", + "image_url": "https://example.com/image.jpg", + "categories": "Sports/Shoes", + "brand": "Nike", + "gtins": ["1234567890123"], + "urls": [ + { + "site": "example-store", + "url": "https://example.com/product/red-sneakers" + } + ], + "stocks": [ + { + "site": "example-store", + "seller_id": "seller123", + "quantity": 10 + } + ], + "metadata": { + "color": "red", + "size": "42" + } + } +] +``` + +> âš ī¸ Any status other than 200 is considered an error. + +## Advertiser (seller) + +The Advertiser entity manages sellers and their associated data. + +| Endpoints | Description | Filters | +| --- | --- | --- | +| GET /api/v1/advertisers | Search advertisers | quantity, page, name, seller_id | +| POST /api/v1/advertisers | Create advertiser | - | +| GET /api/v1/advertisers/:seller_id | Get advertiser by seller ID | - | +| PATCH /api/v1/advertisers/:seller_id | Update advertiser by seller ID | - | + +## Campaigns + +The Campaigns entity manages advertising campaign creation and updates. + +| Endpoints | Description | Filters | +| --- | --- | --- | +| GET /api/v1/campaigns | List campaigns | seller_id, page, quantity, name, status, ad_type | +| POST /api/v1/campaigns | Create campaign | - | +| GET /api/v1/campaigns/:campaign_id | Get campaign by ID | - | +| PATCH /api/v1/campaigns/:campaign_id | Update campaign by ID | - | + +## Metrics + +The Metrics entity provides macro and historical performance data for campaigns. + +| Endpoints | Description | Filters | +| --- | --- | --- | +| GET /api/v1/metrics/macro/campaigns | Get macro metrics | start_at, end_at, campaign_id, seller_id | +| GET /api/v1/metrics/history/campaigns | Get historical metrics | start_at, end_at, campaign_id, seller_id | + +## Credits + +The Credits entity manages advertiser account balances and transactions. + +| Endpoints | Description | Filters | +| --- | --- | --- | +| GET /api/v1/checking_accounts | List advertiser credit accounts | seller_id, page, quantity | +| GET /api/v1/checking_accounts/:seller_id/transactions | List credits for an account | page, quantity | +| POST /api/v1/checking_accounts/:seller_id/transactions | Add credits to an account | - | + +### Credit purchase with credit card/PIX + +| Endpoints | Description | Filters | +| --- | --- | --- | +| GET /api/v1/payments | List payments | seller_id, page, quantity | +| POST /api/v1/payments/:payment_type | Create a new payment that will add credits | - | +| GET /api/v1/payments/:payment_id | Query a payment | - | + +## SSO (VTEX Ads authentication) + +The idea is that once the customer is connected to the marketplace platform, they can reuse this login to connect to the Retail Media platform. + +> âš ī¸ Any status other than 200 is considered an error. + +### Login + +Authentication uses a JWT token with a shared secret. The token must contain: + +- `publisher_id`: Retailer ID in VTEX Ads. +- `seller_id`: Seller ID in the marketplace. +- `user_id`: User ID in the marketplace. +- 24h expiration time + +```http +GET https://app.newtail.com.br/login/marketplace?sso=JWT +``` + +### User information query + +The marketplace must provide an endpoint to query user information by user ID that returns the following fields: + +- `name` +- `email` + +```http +GET PREFIX/users/:user_id?seller_id&=publisher_id= +``` + +### Seller information query + +The marketplace must provide an endpoint to query seller information that returns the following fields: + +- `name` +- `cnpj` (tax ID) + +```http +GET PREFIX/sellers/:seller_id?publisher_id= +``` + +## SSO v2 (VTEX Ads authentication) + +SSO v2 allows retailers to send seller and user information to the VTEX Ads authentication API. VTEX Ads returns a redirect URL for the end user. + +> âš ī¸ Authentication follows the same model described in the [Authentication](#authentication) section. + +```http +POST https://api-retail-media.newtail.com.br/sso/marketplace +``` + +### Request example + +```json +{ + "seller_id": "xyz", + "seller_name": "Seller Name", + "user_email": "user@example.com", + "user_name": "User Name" +} +``` + +### Response examples + +**Success** - Status 200 + +```json +{ + "url_redirect": "https://app.newtail.com.br/login/marketplace?token=JWT" +} +``` + +**Failure** + +* Status 400 - Validation error + + ```json + { + "message": "ValidationError", + "errors": [] + } + ``` + +* Status 500 - Internal application error + + ```json + { + "message": "InternalServerError" + } + ``` diff --git a/docs/localization/placement-naming-conventions.md b/docs/localization/placement-naming-conventions.md new file mode 100644 index 0000000000..f1d51cd8c3 --- /dev/null +++ b/docs/localization/placement-naming-conventions.md @@ -0,0 +1,34 @@ +--- +title: "Placement naming conventions" +slug: "placement-naming-conventions" +excerpt: "Learn the standardized naming conventions for VTEX Ads placements to ensure accurate metrics tracking and reporting." +hidden: false +createdAt: "2025-10-13T00:00:00.000Z" +updatedAt: "2025-10-13T00:00:00.000Z" +--- + +When implementing VTEX Ads on your storefront, placement names are essential for accurate measurement and reporting of advertising metrics for each ad region on your site. + +VTEX Ads uses placement identifiers to track performance, attribution, and revenue across different locations and contexts within your store. Use the following standardized naming convention to ensure consistent tracking and analytics across your VTEX Ads implementation: + +```json +{platform}_{context}_{position}_{type} +``` + +## Naming convention components + +- **Platform**: The medium where the ad is displayed (`site`, `msite`, `app`). +- **Context**: The page or section context (`home`, `product`, `search`, `category`). +- **Position**: The specific location within the page layout. +- **Type**: The advertisement format (`banner`, `product`). + +## Examples + +| Platform | Context | Position | Type | Complete placement name | +| :------- | :--------- | :--------------- | :-------- | :------------------------------------ | +| `site` | `home` | `middle` | `banner` | `site_home_middle_banner` | +| `msite` | `product` | `top-vitrine` | `product` | `msite_product_top-vitrine_product` | +| `app` | `search` | `top-vitrine` | `product` | `app_search_top-vitrine_product` | +| `app` | `search` | `top-vitrine` | `banner` | `app_search_top-vitrine_banner` | +| `site` | `category` | `bottom-vitrine` | `banner` | `site_category_bottom-vitrine_banner` | +| `site` | `product` | `filter-bar` | `product` | `site_product_filter-bar_product` | diff --git a/docs/localization/segmenting-campaigns-by-pii.md b/docs/localization/segmenting-campaigns-by-pii.md new file mode 100644 index 0000000000..c2c773f950 --- /dev/null +++ b/docs/localization/segmenting-campaigns-by-pii.md @@ -0,0 +1,72 @@ +--- +title: "Segmenting campaigns by PII" +slug: "segmenting-campaigns-by-pii" +excerpt: "Create targeted campaigns using personally identifiable information through secure CSV file integration." +hidden: false +createdAt: "2025-10-13T00:00:00.000Z" +updatedAt: "2025-10-14T00:00:00.000Z" +--- +PII segmentation must be done via CSV and will allow the creation of campaigns with users known by the advertiser. + +## Audience file + +The integration file will be a **CSV** file in **UTF-8** encoding. + +### Attributes + +Most attributes are not required; however, the more complete this information is, the better the relevance will be. + +| Column | Type | Required | Description | +| :---------------- | :----- | :------- | :------------------------------------------- | +| CUSTOMER_ID | String | Yes | Unique customer identifier | +| EMAIL_HASHED | String | No | PII based on customer email | +| PHONE_HASHED | String | No | PII based on customer primary phone number | +| SOCIAL_ID_HASHED | String | No | PII based on customer CPF (tax ID) | +| FIRST_NAME_HASHED | String | No | PII based on customer first name | +| LAST_NAME_HASHED | String | No | PII based on customer last name | + +### Field hashing + +Confidential data must be encrypted before being sent using the SHA256 algorithm. + +- EMAIL_HASHED +- PHONE_HASHED +- SOCIAL_ID_HASHED +- FIRST_NAME_HASHED +- LAST_NAME_HASHED + +> 📘 Before generating data hash, you must remove all SPACES and convert values to **LOWERCASE**. + +> 🚧 For the PHONE_HASHED attribute, you must format it to the E.164 standard and include the country calling code. + +#### E.164 format + +1. Remove all non-numeric characters, such as spaces, dashes, parentheses, and symbols. +2. Add the country code with a plus sign (+) at the beginning. The country code is a 1 to 3-digit code that identifies the country of the phone number. You can find a list of country codes in the ISO 3166-1 standard. +3. Add the area code (if applicable) without the leading zero. For example, in the United States, the area code consists of three digits and should not start with zero. +4. Include the local phone number without the leading zero (if applicable). + +Examples: + +- A United States phone number with area code 212 and local number 555-1234 would be formatted as: +12125551234 +- A Brazilian phone number with area code 11 and local number 98765-4321 would be formatted as: +5511987654321 + +#### Creating a hash of a formatted attribute using Python + +```python +import re +import hashlib + +hash_obj = hashlib.sha256() + +def create_hash(x): + cleaned = re.sub('\s+', '', x.lower()) + hash_obj.update(cleaned.encode('utf-8')) + return hash_obj.hexdigest() + +create_hash(' Allan ') #=> 8c01ade3cb71d3ac7c718ed5a0c565155a4c05a216d9e59013c5d7b49e916914 +``` + +### File delivery + +The file must be sent as a ZIP file via email to your Newtail contact. diff --git a/docs/localization/transferring-credit.md b/docs/localization/transferring-credit.md new file mode 100644 index 0000000000..2eafb626bb --- /dev/null +++ b/docs/localization/transferring-credit.md @@ -0,0 +1,83 @@ +--- +title: "Transferring credit" +slug: "transferring-credit" +excerpt: "Learn how to implement credit transfer flow between marketplaces and sellers in VTEX Ads." +hidden: false +createdAt: "2025-10-13T00:00:00.000Z" +updatedAt: "2025-10-13T00:00:00.000Z" +--- +Credit transfer is the flow that allows marketplaces to transfer advertising credits to their sellers. This documentation details the endpoints that marketplaces must implement and the webhook they must consume to integrate with VTEX Ads. + +> â„šī¸ The Authentication model follows [Basic Auth](https://developers.vtex.com/docs/guides/integrating-vtex-ads-with-external-marketplaces#vtex-ads-to-marketplace). + +![transferring-credit](https://cdn.jsdelivr.net/gh/vtexdocs/dev-portal-content@main/docs/guides/VTEX%20Ads/transferring-credit.png) + +## Endpoints to be implemented by the marketplace + +Authentication: Basic Auth + +### 1. Balance inquiry (`GET /checking_account`) + - **Purpose:** Check the seller's available balance. + - **Query parameters:** `seller_id`, `publisher_id` (optional, used only when an entity manages multiple publishers). + - **Success response (200 OK):** + ```json + { "total": "1111.00" } + ``` + +### 2. Transfer request (`POST /checking_account/transfer`) + - **Purpose:** Request the transfer of an amount. + - **Request body:** + ```json + { + "amount": "10.00", + "seller_id": "SELLER_ID", + "publisher_id": "PUBLISHER_ID", + "transfer_identity_id": "uuid" + } + ``` + - **Responses:** + - **Synchronous (Success):** `201 Created` + ```json + { + "transaction_id": "TRANSACTION_ID", + "status": "success" + } + ``` + - **Synchronous (Failure):** `400 Bad Request` + ```json + { + "transaction_id": "TRANSACTION_ID", + "status": "failure", + "message": "Reason for rejection" + } + ``` + - **Asynchronous:** `202 Accepted` + ```json + { + "transaction_id": "TRANSACTION_ID", + "status": "processing" + } + ``` + +## Webhook to be consumed by the marketplace + +- **Purpose:** Notify VTEX Ads about the final status of the transfer. +- **Endpoint:** `POST https://api-retail-media.newtail.com.br/webhook/marketplace/transfers/:publisher_id` +- **Authentication:** `x-api-key` and `x-secret-key`. +- **Payload:** + ```json + { + "transaction_id": "TRANSACTION_ID", + "status": "success" + } + ``` + or + ```json + { + "transaction_id": "TRANSACTION_ID", + "status": "failure", + "message": "Problem description" + } + ``` +- **Retry logic:** In case of webhook call failure, the marketplace must retry. +- **Expected response:** `204 No Content` diff --git a/docs/localization/transferring-credit.png b/docs/localization/transferring-credit.png new file mode 100644 index 0000000000000000000000000000000000000000..f926b74b9175d37af5ec9023b5522fb198eba6bc GIT binary patch literal 54641 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 literal 0 HcmV?d00001 diff --git a/docs/localization/vtex-ads-best-practices.md b/docs/localization/vtex-ads-best-practices.md new file mode 100644 index 0000000000..319c8aff85 --- /dev/null +++ b/docs/localization/vtex-ads-best-practices.md @@ -0,0 +1,35 @@ +--- +title: "VTEX Ads best practices" +slug: "vtex-ads-best-practices" +excerpt: "Learn best practices for integrating with the VTEX Ads API to ensure optimal performance and reliability." +hidden: false +createdAt: "2025-10-13T00:00:00.000Z" +updatedAt: "2025-10-13T00:00:00.000Z" +--- +To optimize integration performance with the VTEX Ads API, implement the following practices. + +## HTTP persistence + +For server-side integrations, use persistent HTTP connections to minimize connection overhead per API request. + +HTTP connection reuse allows multiple requests to share the same TCP connection, eliminating the performance cost of establishing and tearing down connections for each request. This approach prevents network resource degradation during high-traffic periods on both client and server sides. + +The following diagram illustrates the performance difference between multiple connections and persistent connections: + +![vtex-ads-best-practices](https://cdn.jsdelivr.net/gh/vtexdocs/dev-portal-content@main/docs/guides/VTEX%20Ads/getting-started-with-vtex-ads-api/vtex-ads-best-practices.png) + +To implement HTTP persistence, configure your HTTP client to include the following header: + +```curl +Connection: keep-alive +``` + +This header instructs the client to maintain the connection for subsequent requests from the same origin. + +> â„šī¸ Learn more about HTTP persistence in the [Mozilla Developer documentation](https://developer.mozilla.org/en-US/docs/Web/HTTP/Connection_management_in_HTTP_1.x). + +## Timeout implementation + +While the VTEX Ads API maintains high availability standards, network conditions and processing loads can affect response times. Extended response delays may degrade user experience during ad display. + +Implement request timeouts between 500-600ms for all VTEX Ads API calls to maintain optimal performance. This range balances response time requirements with network variability considerations. diff --git a/docs/localization/vtex-ads-best-practices.png b/docs/localization/vtex-ads-best-practices.png new file mode 100644 index 0000000000000000000000000000000000000000..624298fca4539b7914768a8b3203e5c6f1cae480 GIT binary patch literal 77889 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 M(N!zBWc}d(0cH930RR91 literal 0 HcmV?d00001 diff --git a/docs/localization/vtex-ads-script-agent.md b/docs/localization/vtex-ads-script-agent.md new file mode 100644 index 0000000000..79327c6c1c --- /dev/null +++ b/docs/localization/vtex-ads-script-agent.md @@ -0,0 +1,88 @@ +--- +title: "VTEX Ads Script Agent" +slug: "vtex-ads-script-agent" +excerpt: "Learn how to implement the VTEX Ads tracking script across your site using Google Tag Manager for optimal campaign performance and audience segmentation." +hidden: false +createdAt: "2025-10-13T00:00:00.000Z" +updatedAt: "2025-10-13T00:00:00.000Z" +--- + +This document details the procedure for installing the **VTEX Ads** tracking script on all site pages (except checkout pages) through Google Tag Manager (GTM). Proper implementation of this script is essential for collecting navigation data that enables optimization and targeting of Retail Media campaigns. + +## Data collection + +The VTEX Ads script is designed to collect exclusively non-sensitive navigation data, with the objective of personalizing user experience and optimizing campaigns. + +Learn more about the collected data below: + +- **For off-site campaigns:** + + - `session_id`: Anonymous navigation session identifier. + - `ad_id`: Identifier of the ad that originated the traffic. + +- **For audience segmentation (Page View):** + + - `session_id`: Anonymous navigation session identifier. + - **Page information:** URL, title (``), and description (`<meta name="description">`). + +>âš ī¸ The script **does not collect** any personally identifiable information (PII), such as name, email, CPF, phone, address, or payment data. Data collection complies with major data protection laws. + +## Script details + +The script must be loaded asynchronously to avoid impacting page loading time. + +**Script URL:** + +```http +https://cdn.newtail.com.br/retail-media/scripts/vtexads-agent.1.0.0.js +``` + +## Implementation via Google Tag Manager (GTM) + +To ensure the script executes as early as possible during page loading, we recommend using the **Initialization** trigger. + +### Step 1: Create the custom HTML tag + +1. Access your GTM container and go to the **Tags** section. +2. Click **New** to create a new tag. +3. Give the tag a recognizable name, for example: **Custom HTML - VTEX Ads Agent**. +4. Click **Tag Configuration** and select the **Custom HTML** tag type. +5. In the HTML field, insert the following code: + + ```html + <script type="text/javascript" async src="https://cdn.newtail.com.br/retail-media/scripts/vtexads-agent.1.0.0.js"></script> + ``` + +### Step 2: Configure the main trigger + +1. Below the tag configuration, click **"Triggering"**. +2. Select the **"Initialization - All Pages"** trigger. This trigger ensures the script fires before most other tags, on all pages. + +### Step 3: Create and add a trigger exception + +To prevent the script from executing on checkout pages, we'll create an exception. + +1. Still in the tag configuration, in the **"Triggering"** section, click **"Add Exception"**. +2. Click the **"+"** icon in the upper right corner to create a new exception trigger. +3. Name the trigger, for example: **"Trigger Exception - Checkout Pages"**. +4. Click **"Trigger Configuration"** and choose the **"Initialization"** type. +5. Under **"This trigger fires on"**, select **"Some Initialization Events"**. +6. Configure the condition to identify checkout pages. The condition may vary depending on your site's URL structure. Common examples: + - `Page Path` | `contains` | `/checkout` + - `Page URL` | `matches RegEx (ignore case)` | `/checkout/|/orderPlaced/` +7. Save the new exception trigger. It will be automatically added to your tag. + +### Step 4: Save and publish + +1. Save the newly created tag. +2. Submit and publish the changes in your GTM container. + +## User session configuration + +For the VTEX Ads platform to correctly correlate user interactions, you must specify which session identifier is used by your ecommerce. + +>âš ī¸ **Required action:** The ecommerce team must inform the VTEX Ads team about the **name of the attribute in the `cookie` or `sessionStorage`** that stores the user's session ID. +> +> For example: If the session ID is stored in a cookie called `vtex_session`, this information must be provided. +> +> This configuration allows the script to read the correct identifier and associate it with navigation events. diff --git a/docs/localization/vtex-ads-single-sign-on-sso.md b/docs/localization/vtex-ads-single-sign-on-sso.md new file mode 100644 index 0000000000..b64e6bf871 --- /dev/null +++ b/docs/localization/vtex-ads-single-sign-on-sso.md @@ -0,0 +1,51 @@ +--- +title: "VTEX Ads Single Sign On (SSO)" +slug: "vtex-ads-single-sign-on-sso" +excerpt: "Enable seamless user authentication across environments with VTEX Ads SSO integration." +hidden: false +createdAt: "2025-10-13T00:00:00.000Z" +updatedAt: "2025-10-13T00:00:00.000Z" +--- +The purpose of Single Sign On is to allow users to switch between environments without having to log in again. + +> 📘 API Authentication +> +> <https://dash.readme.com/project/newtail-media/v1.0/refs/autenticacao> + +## 1. Request redirect URL + +| Attribute | Description | Type | Required | +| :---------- | :--------------------------------------------- | :----- | :------- | +| seller_id | Unique identifier of the advertiser/seller | String | Yes | +| seller_name | Name of the advertiser/seller | String | Yes | +| user_email | User email | String | Yes | +| user_name | User name | String | Yes | + +```json +curl --location --request POST 'https://api-retail-media.newtail.com.br/sso/marketplace' +--header 'x-api-key: XXX' +--header 'x-app-id: YYY' +--header 'Content-Type: application/json' +--data-raw '{ + "seller_id": "1", + "seller_name": "Store Example", + "user_email": "example@example.com.br", + "user_name": "User Example" +}' +``` + +Response: + +```json +{ + "url_redirect": "https://app.newtail.com.br/login/marketplace?token=xxxxx" +} +``` + +## 2. User redirection to the redirect URL + +Once you have the redirect URL, simply redirect the user to this URL and the user will be logged into the platform without requiring any login integration. + +## Login URL (user disconnection) + +Optionally, we can redirect the user to a previously provided URL that will be used when the user is disconnected. From 80c8e03c00ed005e4de9792322b1212aa7526592 Mon Sep 17 00:00:00 2001 From: Pedro Antunes <47991446+PedroAntunesCosta@users.noreply.github.com> Date: Wed, 3 Jun 2026 19:15:58 -0300 Subject: [PATCH 2/3] fix callout emojis --- .../enabling-manual-prices-for-subscriptions-v3.md | 2 +- .../ads-events/ads-events-notification.md | 2 +- .../getting-started-with-vtex-ads-api/ads-events/clicks.md | 2 +- .../ads-events/conversion.md | 2 +- .../ads-events/impressions.md | 2 +- .../getting-started-with-vtex-ads-api/ads-events/views.md | 2 +- .../getting-started-with-vtex-ads-api/retrieving-ads.md | 2 +- .../retrieving-ads/digital-signage.md | 4 ++-- .../retrieving-ads/segmenting-campaigns.md | 4 ++-- .../synchronizing-inventory-information.md | 2 +- .../synchronizing-product-information.md | 2 +- docs/localization/exporting-ads-events.md | 2 +- docs/localization/exporting-aggregated-data-from-vtex-ads.md | 2 +- docs/localization/segmenting-campaigns-by-pii.md | 4 ++-- docs/localization/vtex-ads-single-sign-on-sso.md | 2 +- 15 files changed, 18 insertions(+), 18 deletions(-) diff --git a/docs/guides/Subscriptions/enabling-manual-prices-for-subscriptions-v3.md b/docs/guides/Subscriptions/enabling-manual-prices-for-subscriptions-v3.md index 999b1affa1..4a0d187319 100644 --- a/docs/guides/Subscriptions/enabling-manual-prices-for-subscriptions-v3.md +++ b/docs/guides/Subscriptions/enabling-manual-prices-for-subscriptions-v3.md @@ -79,7 +79,7 @@ You can manually modify the price when: Read the following sections for details on the endpoints you must use and their request body examples. -> 🚧 You can only apply a manual price to a subscription item if the `manualPriceAllowed` configuration is set to `true`, as described in the [Configuration](#configuration) section. +> âš ī¸ You can only apply a manual price to a subscription item if the `manualPriceAllowed` configuration is set to `true`, as described in the [Configuration](#configuration) section. ### Adding an item to a subscription diff --git a/docs/guides/VTEX Ads/getting-started-with-vtex-ads-api/ads-events/ads-events-notification.md b/docs/guides/VTEX Ads/getting-started-with-vtex-ads-api/ads-events/ads-events-notification.md index f9991f0b6b..c0a2759c62 100644 --- a/docs/guides/VTEX Ads/getting-started-with-vtex-ads-api/ads-events/ads-events-notification.md +++ b/docs/guides/VTEX Ads/getting-started-with-vtex-ads-api/ads-events/ads-events-notification.md @@ -12,7 +12,7 @@ This guide explains how to send event notifications to VTEX Ads. You can send ev - Through a web browser using the `sendBeacon()` API - Server-side or through native apps using REST endpoints -> 🚧 Don't construct event URLs manually. Always use the URL provided from the `POST` [Get ads](https://developers.vtex.com/docs/api-reference/vtex-ads-api#post-/v1/rma/-publisher_id-) request. +> âš ī¸ Don't construct event URLs manually. Always use the URL provided from the `POST` [Get ads](https://developers.vtex.com/docs/api-reference/vtex-ads-api#post-/v1/rma/-publisher_id-) request. > > This is extremely important to ensure long-term stability of the integration, because the parameters of the event URL may change over time, but the integration itself does not. diff --git a/docs/guides/VTEX Ads/getting-started-with-vtex-ads-api/ads-events/clicks.md b/docs/guides/VTEX Ads/getting-started-with-vtex-ads-api/ads-events/clicks.md index 80ecb5bbca..72e5759c3c 100644 --- a/docs/guides/VTEX Ads/getting-started-with-vtex-ads-api/ads-events/clicks.md +++ b/docs/guides/VTEX Ads/getting-started-with-vtex-ads-api/ads-events/clicks.md @@ -16,7 +16,7 @@ Click tracking is essential for measuring ad performance in VTEX Ads. This guide - Click events require both `user_id` and `session_id` for proper attribution. - Click URLs are unique to each ad and should be obtained from the [Get ads](https://developers.vtex.com/docs/api-reference/vtex-ads-api#post-/v1/rma/-publisher_id-) response. -> 🚧 Don't construct event URLs manually. Always use the URL provided from the `POST` [Get ads](https://developers.vtex.com/docs/api-reference/vtex-ads-api#post-/v1/rma/-publisher_id-) request. +> âš ī¸ Don't construct event URLs manually. Always use the URL provided from the `POST` [Get ads](https://developers.vtex.com/docs/api-reference/vtex-ads-api#post-/v1/rma/-publisher_id-) request. > > This is extremely important to ensure long-term stability of the integration, because the parameters of the event URL may change over time, but the integration itself does not. diff --git a/docs/guides/VTEX Ads/getting-started-with-vtex-ads-api/ads-events/conversion.md b/docs/guides/VTEX Ads/getting-started-with-vtex-ads-api/ads-events/conversion.md index e9a85df038..46a90a3d65 100644 --- a/docs/guides/VTEX Ads/getting-started-with-vtex-ads-api/ads-events/conversion.md +++ b/docs/guides/VTEX Ads/getting-started-with-vtex-ads-api/ads-events/conversion.md @@ -17,7 +17,7 @@ Conversion tracking is crucial for measuring ad campaign effectiveness in VTEX A - Prices must be sent per unit. Don't multiply the `price` or `promotional_price` by the `quantity`. - All customer identifiers (email, phone, etc.) must be hashed for privacy. -> 🚧 Don't construct event URLs manually. Always use the URL provided from the `POST` [Get ads](https://developers.vtex.com/docs/api-reference/vtex-ads-api#post-/v1/rma/-publisher_id-) request. +> âš ī¸ Don't construct event URLs manually. Always use the URL provided from the `POST` [Get ads](https://developers.vtex.com/docs/api-reference/vtex-ads-api#post-/v1/rma/-publisher_id-) request. > > This is extremely important to ensure long-term stability of the integration, because the parameters of the event URL may change over time, but the integration itself does not. diff --git a/docs/guides/VTEX Ads/getting-started-with-vtex-ads-api/ads-events/impressions.md b/docs/guides/VTEX Ads/getting-started-with-vtex-ads-api/ads-events/impressions.md index 51d2a283cb..4d127070d2 100644 --- a/docs/guides/VTEX Ads/getting-started-with-vtex-ads-api/ads-events/impressions.md +++ b/docs/guides/VTEX Ads/getting-started-with-vtex-ads-api/ads-events/impressions.md @@ -16,7 +16,7 @@ Impression tracking is fundamental for measuring ad visibility in VTEX Ads. This - Impression events require both `user_id` and `session_id` for proper attribution. - Impression URLs are unique to each ad and should be obtained from the [Get ads](https://developers.vtex.com/docs/api-reference/vtex-ads-api#post-/v1/rma/-publisher_id-) response. -> 🚧 Don't construct event URLs manually. Always use the URL provided from the `POST` [Get ads](https://developers.vtex.com/docs/api-reference/vtex-ads-api#post-/v1/rma/-publisher_id-) request. +> âš ī¸ Don't construct event URLs manually. Always use the URL provided from the `POST` [Get ads](https://developers.vtex.com/docs/api-reference/vtex-ads-api#post-/v1/rma/-publisher_id-) request. > > This is extremely important to ensure long-term stability of the integration, because the parameters of the event URL may change over time, but the integration itself does not. diff --git a/docs/guides/VTEX Ads/getting-started-with-vtex-ads-api/ads-events/views.md b/docs/guides/VTEX Ads/getting-started-with-vtex-ads-api/ads-events/views.md index a7aa6d9106..ba50119e99 100644 --- a/docs/guides/VTEX Ads/getting-started-with-vtex-ads-api/ads-events/views.md +++ b/docs/guides/VTEX Ads/getting-started-with-vtex-ads-api/ads-events/views.md @@ -15,7 +15,7 @@ VTEX Ads uses view tracking to measure when banner advertisements are effectivel - View events require both `user_id` and `session_id` for proper attribution. - View URLs are unique to each ad and should be obtained from the [Get ads](https://developers.vtex.com/docs/api-reference/vtex-ads-api#post-/v1/rma/-publisher_id-) response. -> 🚧 Don't construct event URLs manually. Always use the URL provided from the `POST` [Get ads](https://developers.vtex.com/docs/api-reference/vtex-ads-api#post-/v1/rma/-publisher_id-) request. +> âš ī¸ Don't construct event URLs manually. Always use the URL provided from the `POST` [Get ads](https://developers.vtex.com/docs/api-reference/vtex-ads-api#post-/v1/rma/-publisher_id-) request. > > This is extremely important to ensure long-term stability of the integration, because the parameters of the event URL may change over time, but the integration itself does not. diff --git a/docs/guides/VTEX Ads/getting-started-with-vtex-ads-api/retrieving-ads.md b/docs/guides/VTEX Ads/getting-started-with-vtex-ads-api/retrieving-ads.md index fde9bb9b2f..e7f7d63324 100644 --- a/docs/guides/VTEX Ads/getting-started-with-vtex-ads-api/retrieving-ads.md +++ b/docs/guides/VTEX Ads/getting-started-with-vtex-ads-api/retrieving-ads.md @@ -146,7 +146,7 @@ The response is a dictionary where: Sponsored brands campaigns have a different response format that includes brand information and related products. -> 🚧 All events must be triggered for both the ad and its products. +> âš ī¸ All events must be triggered for both the ad and its products. Request example: diff --git a/docs/guides/VTEX Ads/getting-started-with-vtex-ads-api/retrieving-ads/digital-signage.md b/docs/guides/VTEX Ads/getting-started-with-vtex-ads-api/retrieving-ads/digital-signage.md index 2db9940f07..585995de67 100644 --- a/docs/guides/VTEX Ads/getting-started-with-vtex-ads-api/retrieving-ads/digital-signage.md +++ b/docs/guides/VTEX Ads/getting-started-with-vtex-ads-api/retrieving-ads/digital-signage.md @@ -13,7 +13,7 @@ The Digital Signage integration uses the `POST` [Get ads](https://developers.vte All ads that should be displayed will be returned. Once all ads have been displayed, the API must be called again to retrieve the next batch of items to be shown. ->🚧 Don't display the same items twice, as display metrics will only be counted once. +> âš ī¸ Don't display the same items twice, as display metrics will only be counted once. Request example: @@ -60,7 +60,7 @@ In some cases, it is possible to identify the user making a purchase, typically Once the user is identified, you can request a personalized ad for that user. ->🚧 For segmented campaigns, an audience integration is required. +> âš ī¸ For segmented campaigns, an audience integration is required. Request example: diff --git a/docs/guides/VTEX Ads/getting-started-with-vtex-ads-api/retrieving-ads/segmenting-campaigns.md b/docs/guides/VTEX Ads/getting-started-with-vtex-ads-api/retrieving-ads/segmenting-campaigns.md index 3c126b56a8..206eee96c0 100644 --- a/docs/guides/VTEX Ads/getting-started-with-vtex-ads-api/retrieving-ads/segmenting-campaigns.md +++ b/docs/guides/VTEX Ads/getting-started-with-vtex-ads-api/retrieving-ads/segmenting-campaigns.md @@ -9,7 +9,7 @@ updatedAt: "2025-05-21T22:18:24.684Z" Campaign targeting allows meta-information to be provided during an ad query, which can be used in real time to prioritize campaigns aimed at that specific audience. -> 🚧 Campaigns with targeting will have higher priority during the query process, meaning they are considered more relevant to the audience they were directed to. However, the presence of targeting does not prevent non-targeted campaigns from also being displayed. +> âš ī¸ Campaigns with targeting will have higher priority during the query process, meaning they are considered more relevant to the audience they were directed to. However, the presence of targeting does not prevent non-targeted campaigns from also being displayed. ## Targeting attributes @@ -56,7 +56,7 @@ Content-Type: application/json In this approach, targeting information is obtained based on the audiences associated with the `user_id`. These audiences must have been previously imported into the system. -> 🚧 When using this approach, don't send data in the `segmentation` field, since this field would take priority over `user_id`. The system will automatically fetch the audiences associated with the `user_id`. +> âš ī¸ When using this approach, don't send data in the `segmentation` field, since this field would take priority over `user_id`. The system will automatically fetch the audiences associated with the `user_id`. Request example: diff --git a/docs/guides/VTEX Ads/getting-started-with-vtex-ads-api/synchronizing-the-catalog-with-vtex-ads/synchronizing-inventory-information.md b/docs/guides/VTEX Ads/getting-started-with-vtex-ads-api/synchronizing-the-catalog-with-vtex-ads/synchronizing-inventory-information.md index a85f75ab7a..e62f345348 100644 --- a/docs/guides/VTEX Ads/getting-started-with-vtex-ads-api/synchronizing-the-catalog-with-vtex-ads/synchronizing-inventory-information.md +++ b/docs/guides/VTEX Ads/getting-started-with-vtex-ads-api/synchronizing-the-catalog-with-vtex-ads/synchronizing-inventory-information.md @@ -11,7 +11,7 @@ Inventory information defines the price, promotional price, and "stock." Regardi Learn more about each field on `POST` [Synchronize inventory information](https://developers.vtex.com/docs/api-reference/vtex-ads-api#post-/product/bulk/inventories). -> 🚧 Batch Insert / Update +> âš ī¸ Batch Insert / Update > > For each batch insert/update, a maximum of 500 objects per request and 3 simultaneous requests are allowed. > diff --git a/docs/guides/VTEX Ads/getting-started-with-vtex-ads-api/synchronizing-the-catalog-with-vtex-ads/synchronizing-product-information.md b/docs/guides/VTEX Ads/getting-started-with-vtex-ads-api/synchronizing-the-catalog-with-vtex-ads/synchronizing-product-information.md index 5d8a5ff798..b8542384c9 100644 --- a/docs/guides/VTEX Ads/getting-started-with-vtex-ads-api/synchronizing-the-catalog-with-vtex-ads/synchronizing-product-information.md +++ b/docs/guides/VTEX Ads/getting-started-with-vtex-ads-api/synchronizing-the-catalog-with-vtex-ads/synchronizing-product-information.md @@ -15,7 +15,7 @@ Learn more about each field on `POST` [Synchronize product information](https:// To update the basic product data, the following endpoint must be used: -> 🚧 Batch Insert / Update +> âš ī¸ Batch Insert / Update > > For each batch insert/update, a maximum of 500 objects per request and 3 simultaneous requests are allowed. > diff --git a/docs/localization/exporting-ads-events.md b/docs/localization/exporting-ads-events.md index 4731f83097..9ca5d7aaac 100644 --- a/docs/localization/exporting-ads-events.md +++ b/docs/localization/exporting-ads-events.md @@ -18,7 +18,7 @@ See more about the connection in [Exporting data from VTEX Ads](https://develope - Files are in [Parquet](https://parquet.apache.org/docs/overview/) format with [Snappy](https://parquet.apache.org/docs/file-format/data-pages/compression/) compression - Files are always sent in a daily path format: `TYPE_REPORT/YYYY/MM/DD/TIMESTAMP_NS/RANDOM_FILE_NAMES.snappy.parquet` (one or more files may be sent) -> 🚧 Event deduplication +> âš ī¸ Event deduplication > > All events are guaranteed to be sent, but there is no guarantee that an event will be sent only once. Therefore, events must always be deduplicated. diff --git a/docs/localization/exporting-aggregated-data-from-vtex-ads.md b/docs/localization/exporting-aggregated-data-from-vtex-ads.md index 3456f8f528..9cf6a3e6cd 100644 --- a/docs/localization/exporting-aggregated-data-from-vtex-ads.md +++ b/docs/localization/exporting-aggregated-data-from-vtex-ads.md @@ -24,7 +24,7 @@ See more about the connection in [Exporting data from VTEX Ads](https://develope ## Data to be exported -> 📘 File examples +> â„šī¸ File examples > > Examples of files that will be sent: > diff --git a/docs/localization/segmenting-campaigns-by-pii.md b/docs/localization/segmenting-campaigns-by-pii.md index c2c773f950..ac8c04787d 100644 --- a/docs/localization/segmenting-campaigns-by-pii.md +++ b/docs/localization/segmenting-campaigns-by-pii.md @@ -35,9 +35,9 @@ Confidential data must be encrypted before being sent using the SHA256 algorithm - FIRST_NAME_HASHED - LAST_NAME_HASHED -> 📘 Before generating data hash, you must remove all SPACES and convert values to **LOWERCASE**. +> â„šī¸ Before generating data hash, you must remove all SPACES and convert values to **LOWERCASE**. -> 🚧 For the PHONE_HASHED attribute, you must format it to the E.164 standard and include the country calling code. +> âš ī¸ For the PHONE_HASHED attribute, you must format it to the E.164 standard and include the country calling code. #### E.164 format diff --git a/docs/localization/vtex-ads-single-sign-on-sso.md b/docs/localization/vtex-ads-single-sign-on-sso.md index b64e6bf871..befa1815e8 100644 --- a/docs/localization/vtex-ads-single-sign-on-sso.md +++ b/docs/localization/vtex-ads-single-sign-on-sso.md @@ -8,7 +8,7 @@ updatedAt: "2025-10-13T00:00:00.000Z" --- The purpose of Single Sign On is to allow users to switch between environments without having to log in again. -> 📘 API Authentication +> â„šī¸ API Authentication > > <https://dash.readme.com/project/newtail-media/v1.0/refs/autenticacao> From 0e435672dff121d383ecf3b658024c6737aff80b Mon Sep 17 00:00:00 2001 From: Pedro Antunes <47991446+PedroAntunesCosta@users.noreply.github.com> Date: Wed, 3 Jun 2026 19:16:27 -0300 Subject: [PATCH 3/3] update audiences integration flow --- docs/localization/integrating-audiences.md | 156 ++++++++++++++------- 1 file changed, 108 insertions(+), 48 deletions(-) diff --git a/docs/localization/integrating-audiences.md b/docs/localization/integrating-audiences.md index 88a9758e5b..5e1a2b0ae4 100644 --- a/docs/localization/integrating-audiences.md +++ b/docs/localization/integrating-audiences.md @@ -1,84 +1,135 @@ --- title: "Integrating audiences" slug: "integrating-audiences" -excerpt: "Integrate customer audience data with VTEX Ads using secure S3-based file delivery and PII hashing." +excerpt: "Integrate customer audience data with VTEX Ads using a presigned S3 upload and PII hashing." hidden: false createdAt: "2025-10-13T00:00:00.000Z" -updatedAt: "2025-10-14T00:00:00.000Z" +updatedAt: "2026-06-03T00:00:00.000Z" --- -## Integration connection -> 📘 The integration connection will occur through: -> -> - Periodic audience delivery as agreed between parties -> - Delivery to our S3 (access credentials must be requested from your Newtail contact) -> - Files must be sent in `Parquet` format with `Snappy` compression -> - Newtail will provide S3 credentials +Audience integration lets you enrich **VTEX Ads** targeting with your own customer data, improving campaign segmentation and ad relevance. It is optional but highly recommended. -> 🚧 Delivery recommendation -> -> In the initial integration, it is essential that all data be sent. This data can be sent in multiple files (depending on the database size. A good number is 1 million rows per file). +You deliver an audience file through a short-lived presigned Amazon S3 upload. First you request an upload URL from the VTEX Ads API, then you upload the file directly to Amazon S3 using the signed fields returned in the response. The backend builds the destination path from your authenticated publisher, so no per-publisher credentials or manual paths are required. + +> â„šī¸ If you do not integrate audiences, open a ticket with your account manager to request pre-population of segmentation information with base data (`STATE`, `CITY`, `GENDER`, and `AGE`). You can also provide a list of audiences to be registered, and keep them updated periodically. + +## Before you begin + +- **Authentication:** the upload URL request requires the `X-App-Id` and `X-Api-Key` headers. Contact [VTEX support](https://help.vtex.com/en/tutorial/how-does-vtex-support-work--2eAT5EyOvaLoHdIWDVaxC3) to obtain credentials. +- **File format:** `Parquet` with `Snappy` compression. Column names are case-sensitive (see [Audience file](#audience-file)). + +> â„šī¸ Delivery recommendation > -> After the first integration, ideally only the delta of rows that have been modified should be sent. +> On the first integration, send all data. You can split it across multiple files (a good size is around 1 million rows per file). After the first integration, send only the delta of rows that changed. + +> â„šī¸ FTP/SFTP integration is no longer supported for new projects. If you have a legacy SFTP integration, contact the VTEX Ads team to plan the migration to this flow. + +## 1. Request an upload URL -Files must be written following this directory pattern: +Send an authenticated `POST` request to the `/audience/upload-url` endpoint. The endpoint returns a presigned Amazon S3 `POST` that is valid for `expires_in` seconds (900 by default, around 15 minutes). +Request example: + +```bash +curl -X POST "https://api-retail-media.newtail.com.br/audience/upload-url" \ + -H "X-App-Id: {your_app_id}" \ + -H "X-Api-Key: {your_api_key}" \ + -H "Accept: application/json" ``` -PREFIX/audiences/YYYY/mm/dd/TIMESTAMP.parquet.snappy + +Response example: + +```json +{ + "url": "https://newtail-data-clean-room.s3.amazonaws.com/", + "fields": { + "key": "0d675bf6-03f6-4b81-9617-e79dffddc3ab/audiences/2026/06/03/14/1780495200.parquet.snappy", + "Content-Type": "application/octet-stream", + "Policy": "eyJleHBpcmF0aW9uIjoiMjAyNi0wNi0wM1QxNDoxNTowMFoiLCJjb25kaXRpb25zIjpbXX0=", + "X-Amz-Signature": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2" + }, + "key": "0d675bf6-03f6-4b81-9617-e79dffddc3ab/audiences/2026/06/03/14/1780495200.parquet.snappy", + "bucket": "newtail-data-clean-room", + "expires_in": 900, + "max_bytes": 2147483648, + "upload": { + "method": "POST", + "enctype": "multipart/form-data" + } +} ``` -| Attribute | Description | Example | -| :-------- | :------------------------------------------------------- | :--------- | -| PREFIX | The prefix will be provided by Newtail | xyz | -| YYYY | Generation year with 4 digits | 2023 | -| mm | Generation month with two digits (January = 01, December = 12) | 09 | -| dd | Generation day with two digits (from 01 to 31) | 31 | -| TIMESTAMP | Timestamp is the number of seconds since 1970 (filename can be anything, timestamp is just a suggestion that will never repeat) | 1694812122 | +See the `POST` [Generate audience upload URL](https://developers.vtex.com/docs/api-reference/vtex-ads-api#post-/audience/upload-url) endpoint for the full response schema. The following table describes the response fields: + +| Field | Description | +| :--- | :--- | +| `url` | Amazon S3 endpoint to send the upload request to. | +| `fields` | Signed Amazon S3 form fields that must be sent with the upload, before the `file` field. | +| `key` | Object key the file will be stored under. Built by the backend from your authenticated publisher. | +| `bucket` | Amazon S3 bucket that receives the upload. | +| `expires_in` | Number of seconds the presigned `POST` remains valid. Defaults to `900`. | +| `max_bytes` | Maximum file size, in bytes, accepted by Amazon S3. Defaults to `2147483648` (2 GB). | +| `upload` | HTTP `method` and `enctype` to use for the upload request. | + +## 2. Upload the file to Amazon S3 + +Upload the audience file with a multipart `POST` request directly to the `url` returned in the previous step. Send every entry from `fields` first and the `file` field last. + +```bash +curl -X POST "{url}" \ + -F key={fields.key} \ + -F Content-Type=application/octet-stream \ + -F Policy={fields.Policy} \ + -F X-Amz-Signature={fields.X-Amz-Signature} \ + -F <remaining fields from the response, in order> \ + -F file=@my-audience.parquet.snappy +``` +> âš ī¸ The presigned `POST` expires after `expires_in` seconds. If it expires before the upload completes, request a new upload URL. Amazon S3 rejects files larger than `max_bytes` (2 GB by default). ## Audience file ### Attributes -Most attributes are not required; however, the more complete this information is, the better the relevance will be. +Most attributes are not required. However, the more complete this information is, the better the relevance will be. -> 📘 Columns are case sensitive +> â„šī¸ Columns are case-sensitive > > Keep the column names exactly as they are presented. | Column | Type | Required | Description | | :---------------- | :----- | :------- | :------------------------------------------------------- | -| CUSTOMER_ID | String | Yes | Unique customer identifier | -| EMAIL_HASHED | String | No | PII based on customer email | -| PHONE_HASHED | String | No | PII based on customer primary phone number | -| SOCIAL_ID_HASHED | String | No | PII based on customer CPF (tax ID) | -| FIRST_NAME_HASHED | String | No | PII based on customer first name | -| LAST_NAME_HASHED | String | No | PII based on customer last name | -| GENDER | String | No | Customer gender: `F` (female), `M` (male), `O` (other), `NULL` (not identified) | -| AGE | Int | No | Customer age | -| CEP | String | No | Customer address postal code | -| COUNTRY | String | No | Customer country | -| STATE | String | No | Customer state of residence | -| CITY | String | No | Customer city of residence | -| NEIGHBORHOOD | String | No | Customer neighborhood of residence | -| AUDIENCES | String | No | List of audiences separated by semicolon (;) | -| NBO_PRODUCTS | String | No | List of product SKUs separated by semicolon (;) | -| NBO_CATEGORIES | String | No | List of categories separated by semicolon (;). Category lists can include category trees using " > " as separator. Example: `Tablets;Beverages > Non-Alcoholic Beverages;Books > Gastronomy > Bar and Restaurant Guides` | +| `CUSTOMER_ID` | String | Yes | Unique customer identifier | +| `EMAIL_HASHED` | String | No | PII based on customer email | +| `PHONE_HASHED` | String | No | PII based on customer primary phone number | +| `SOCIAL_ID_HASHED` | String | No | PII based on customer CPF (tax ID) | +| `FIRST_NAME_HASHED` | String | No | PII based on customer first name | +| `LAST_NAME_HASHED` | String | No | PII based on customer last name | +| `GENDER` | String | No | Customer gender: `F` (female), `M` (male), `O` (other), `NULL` (not identified) | +| `AGE` | Int | No | Customer age | +| `CEP` | String | No | Customer address postal code | +| `COUNTRY` | String | No | Customer country | +| `STATE` | String | No | Customer state of residence | +| `CITY` | String | No | Customer city of residence | +| `NEIGHBORHOOD` | String | No | Customer neighborhood of residence | +| `AUDIENCES` | String | No | List of audiences using `;` as the separator | +| `NBO_PRODUCTS` | String | No | List of product SKUs using `;` as the separator | +| `NBO_CATEGORIES` | String | No | List of categories using `;` as the separator. Category lists can include category trees using ` > ` as separator. Example: `Tablets;Beverages > Non-Alcoholic Beverages;Books > Gastronomy > Bar and Restaurant Guides` | ### Field hashing -Confidential data must be encrypted before being sent using the SHA256 algorithm. +Confidential data must be encrypted before being sent using the SHA-256 algorithm. -- EMAIL_HASHED -- PHONE_HASHED -- SOCIAL_ID_HASHED -- FIRST_NAME_HASHED -- LAST_NAME_HASHED +- `EMAIL_HASHED` +- `PHONE_HASHED` +- `SOCIAL_ID_HASHED` +- `FIRST_NAME_HASHED` +- `LAST_NAME_HASHED` -> 📘 Before generating data hash, you must remove all SPACES and convert values to **LOWERCASE**. +> â„šī¸ Before generating the data hash, you must remove all SPACES and convert values to **LOWERCASE**. -> 🚧 For the PHONE_HASHED attribute, you must format it to the E.164 standard and include the country calling code. +> âš ī¸ For the `PHONE_HASHED` attribute, you must format it to the E.164 standard and include the country calling code. #### E.164 format @@ -107,3 +158,12 @@ def create_hash(x): create_hash(' Allan ') #=> 8c01ade3cb71d3ac7c718ed5a0c565155a4c05a216d9e59013c5d7b49e916914 ``` + +## Runtime alternative + +If you choose not to integrate audiences through file upload, you can still apply segmentation at query time by sending the data in the `segmentation` field of the ad query request. For more details, see [Segmenting campaigns](https://developers.vtex.com/docs/guides/segmenting-campaigns). + +## Next steps + +- [Segmenting campaigns](https://developers.vtex.com/docs/guides/segmenting-campaigns) +- `POST` [Generate audience upload URL](https://developers.vtex.com/docs/api-reference/vtex-ads-api#post-/audience/upload-url)