# StackAdapt Ads

## Getting Started

To connect the StackAdapt Ads integration, follow these steps:

1. **Sign In:** A StasckAdapt login window will appear, sign in and proceed to the next step of granting permissions
2. **Grant Permissions:** Review the requested permissions, such as access to your ad accounts and campaigns. Click **Allow** to grant the necessary permissions.
3. **Confirmation:** After granting permissions, you'll be redirected back to HockeyStack

## What Data Gets Tracked as Metadata

The following fields are tracked and stored during the integration process:

| **Field**             | **Description**                                                       |
| --------------------- | --------------------------------------------------------------------- |
| `account_id_hashed`   | A hashed version of the account ID for secure storage.                |
| `type`                | The type of tracked data, such as `paid-ads`.                         |
| `date`                | The date of the ad activity, formatted as `YYYY-MM-DD`.               |
| `id`                  | A unique identifier for each data row, generated as an MD5 hash.      |
| `metadata`            | A JSON object containing detailed metadata about the campaign and ad. |
| `account_id`          | The original account ID associated with the ad.                       |
| `network`             | The advertising network, such as `StackAdapt Ads`.                    |
| `campaign_id`         | The unique ID of the campaign.                                        |
| `campaign_group_id`   | The unique ID of the campaign group.                                  |
| `campaign_name`       | The name of the campaign.                                             |
| `campaign_group_name` | The name of the campaign group.                                       |
| `ad_id`               | The unique ID of the ad.                                              |
| `ad_name`             | The name of the ad.                                                   |
| `utm_source`          | The source of the traffic, such as `stackadapt`.                      |
| `utm_campaign`        | The campaign name, URL-encoded if necessary.                          |
| `utm_medium`          | The medium of the traffic, such as `paid`.                            |
| `utm_content`         | Content-specific identifier for the campaign.                         |
| `utm_term`            | The keyword associated with the campaign, if applicable.              |
| `impressions`         | The total number of impressions for the ad.                           |
| `clicks`              | The total number of clicks for the ad.                                |
| `cost`                | The total cost of the ad campaign in the specified currency.          |
| `currency`            | The currency in which the ad costs are measured (e.g., `USD`).        |

## High-Level Integration Flow

1. **Validation**:
   * We validate the `apiKey` to ensure it is associated with an advertiser account.
   * The start of the integration process is logged for debugging and tracking purposes.
2. **Ad Data Retrieval**:
   * We fetch ad delivery data using the `adsDelivery` query and campaign-level data using `campaignDelivery`.
   * Additional campaign insights are retrieved through the `campaignInsight` query.
3. **Analytics and Data Processing**:
   * Analytics data is merged with ad data to create a unified structure.
   * UTM parameters, impressions, clicks, and cost metrics are extracted and formatted.
4. **Data Formatting**:
   * The `formatData` function processes the raw data into a structured format, ensuring consistency in metadata.
   * Extracted URLs are parsed to gather UTM parameters, enhancing tracking precision.
5. **Data Insertion**:
   * Formatted data is stored in the metadata system using `insertToMetadata`.
   * The account’s `lastPulledDate` is updated to avoid duplicate data processing.

## How Impressions are Tracked

The following fields are tracked as part of the impressions tracking process:

**Action Properties**

| **Field**          | **Description**                                                                                                                         |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------- |
| `actionName`       | The name of the action, for this integration it will be `StackAdapt Ads Impressions Changed` or `StackAdapt Ads Ad Engagements Changed` |
| `actionDate`       | The date when the impression action was recorded.                                                                                       |
| `actionProperties` | Additional properties related to the action, including metrics.                                                                         |

**Company Properties**

| **Field**          | **Description**                                           |
| ------------------ | --------------------------------------------------------- |
| `company_name`     | The domain name of the company.                           |
| `company_domain`   | The domain associated with the company.                   |
| `company_industry` | The industry classification of the company, if available. |
| `company_id`       | A unique identifier for the company.                      |

**Shared Properties**

| **Field**                | **Description**                                                                  |
| ------------------------ | -------------------------------------------------------------------------------- |
| `company_id`             | Made from concatenating `stackadapt__`and the `b2bDomain` found from the results |
| `stackadapt__company_id` | Same as above                                                                    |

#### Notes and Caveats

* **Token Handling**:
  * The integration uses `apiKey` to authenticate all requests to the StackAdapt Ads API.
* **Data Splitting**:
  * Date ranges are processed in increments of up to 1 month to manage large datasets effectively.
* **Retry Logic**:
  * Failed API requests are retried up to 3 times with exponential backoff, starting at 10 seconds.
