# Quickstart guide

### Getting started with Roadway

1. Connect data source(s)
2. Configure your workspace
3. Learn to use Roadway

#### Connect data source(s)

Choose your path - Integrate Roadway on top of your existing data warehouse or connect directly to your data platforms.

**Warehouse-native**

* [Connect to Snowflake](/implement-roadway/warehouse-native/connect-snowflake)[**‍**](http://www.roadwayai.com/docs/bigquery)
* [Connect to BigQuery](/implement-roadway/warehouse-native/connect-bigquery)[**‍**](http://www.roadwayai.com/docs/clickhouse)

**Direct connection to data platforms**

Follow instructions in the app for direct connectors.

* Google Analytics
* Stripe
* Hubspot
* Salesforce
* Segment
* Meta Ads
* Linkedin Ads
* Google Ads
* Twitter Ads

Don’t see your data source? Contact us!

#### Configure your workspace

Customize your metrics, attribution, and verify metrics with the Roadway team.

1. Confirm metrics in your growth funnel
2. Customize your attribution logic
3. Choose your attribution model
4. Verify metric definitions and attribution rules

#### Learn to use Roadway

‍[**Check out the Roadway Guidebook →**](http://www.roadwayai.com/documentation/guidebook)

#### Not sure where to start?

‍[**Schedule time to talk with founders  →**](https://www.roadwayai.com/join-waitlist)


# How Roadway Works

## Modeling

The following diagram provides a high-level overview of the work Roadway conducts under the hood.

<img src="/files/G7cMwZD8EOmk22MAkqQl" alt="10,000 ft view of Roadway&#x27;s Data Modeling " class="gitbook-drawing">

The "Roadway Data Modeling" arrow above does a lot of heavy lifting, so what's going on there? Among other things, this means:

* cleaning and validating raw data&#x20;
* sessionizing page views and calculating your attribution model
* constructing historical revenue snapshots
* linking attribution to elements of your growth funnel

The above architecture drives Roadway's default metrics definitions, but if you have existing metric logic already modeled, you can share those definition with Roadway to be mirrored with the data available.


# Warehouse-native

{% content-ref url="/pages/n6DTPmezvrNhYKB3VTZj" %}
[Connect Snowflake](/implement-roadway/warehouse-native/connect-snowflake)
{% endcontent-ref %}

{% content-ref url="/pages/ud09n3edJLitSJIz9IsY" %}
[Connect BigQuery](/implement-roadway/warehouse-native/connect-bigquery)
{% endcontent-ref %}

Don’t see your warehouse? Contact us in slack!


# Connect Snowflake

### Connect Roadway to Snowflake

[Data Warehouse Requirements](/data-requirements/warehouse-requirements)

1\. Log in to the **Snowflake** web interface.

2\. Execute the following SQL. These `commands` create a roadway user, role, warehouse and schema and grants read and write permissions on this schema.

```sql
Copy/*
Create Database Objects:

Note that we use explicit CREATE statements with no additional clauses, which 
prevents us from overwriting any existing objects of the same name. In the event you already have objects with these names, change the names in this script accordingly, but notify us of these changes.
 */
CREATE USER roadway_user
		PASSWORD = <some password>
		DEFAULT_ROLE = 'roadway_role'
		DEFAULT_WAREHOUSE = 'roadway_warehouse'
		DEFAULT_NAMESPACE = 'your_db.roadway'
		EMAIL = 'service@roadwayai.com'
;
CREATE SCHEMA <your_db>.roadway;
CREATE WAREHOUSE roadway_warehouse
		AUTO_SUSPEND = 1
		WAREHOUSE_SIZE = XSMALL -- default to most conservative size, but change according to data volume and usage
;
CREATE ROLE roadway_role;

-- grant usages to roadway_role
GRANT USAGE ON DATABASE <your_db> TO ROLE roadway_role;
GRANT USAGE ON SCHEMA <your_db>.roadway TO ROLE roadway_role;
GRANT USAGE ON WAREHOUSE roadway_warehouse TO ROLE roadway_role;

-- grant limited read/write privileges to roadway_role within roadway schema
GRANT SELECT ON ALL VIEWS IN SCHEMA <your_db>.roadway TO ROLE roadway_role;
GRANT SELECT ON ALL TABLES IN SCHEMA  <your_db>.roadway TO ROLE roadway_role;
GRANT SELECT ON FUTURE TABLES IN SCHEMA <your_db>.roadway TO ROLE roadway_role;
GRANT SELECT ON FUTURE VIEWS IN SCHEMA <your_db>.roadway TO ROLE roadway_role;
GRANT CREATE TABLE, CREATE VIEW ON SCHEMA <your_db>.roadway TO ROLE roadway_role;

-- grant roadway_role to roadway_user
GRANT ROLE roadway_role TO USER roadway_user;
```

3\. Extend the above commands with readonly permissions on other databases and schemas according to your warehouse structure, e.g. GRANT SELECT ON ALL TABLES IN SCHEMA revenue\_db.stripe TO ROLE roadway\_role.

4\. Ensure the role has permissions to view and create as needed.

```sql
Copysql
Copy code
GRANT SELECT, INSERT ON ALL TABLES IN schema your_schema TO service@roadwayai.com;
```


# Connect BigQuery

### Connect Roadway to BigQuery

[Data Warehouse Requirements](/data-requirements/warehouse-requirements)

We have set up our service account in our Google Cloud project for you to connect to. Your company specific service account email will be provided by Roadway directly.

1. Go to the **Google Cloud Console** and select your project.
2. Navigate to **IAM & Admin > IAM**.
3. Click **Add**.
4. In the **New Members** field, enter the service email provided to you by Roadway
   1. **Assign the following roles:**
      * **BigQuery Data Viewer** – for read-only access to your BigQuery data.
      * **BigQuery Job User** – to allow for query execution.
   2. Click **Save** to apply the changes.
5. Using your own appropriately permissioned account, create a `roadway` dataset in your BigQuery project. For the above service email provided by Roadway, grant the following roles *on this dataset*:
6. Assign the following roles:
   * **BigQuery Data Editor** - for read and write permissions on this dataset
   * **BigQuery Job User** - to allow for query execution (this may be inherited via step 4a above)
7. Click **Save** to apply the changes.

**‍‍**

**Access Management**

Once access is granted, send us the project ID of the datasets you granted us permission to in Slack. Once received, we will securely connect to your BigQuery warehouse.


# Connect Redshift

[Data warehouse requirements](/data-requirements/warehouse-requirements)

1. Connect to your **Redshift Cluster**
2. Execute the following SQL. These commands create a roadway user and grant read and write permissions to the tables (view [Data warehouse requirements](/data-requirements/warehouse-requirements)) required by Roadway. Make sure to change the placeholders for the correct database and schema Roadway should use; we do not need access to your entire data warehouse.

```sql
CREATE USER roadway_user PASSWORD <'your_strong_password'>;

GRANT USAGE ON SCHEMA <your_database_name>.<your_schema_name> TO roadway_user;
GRANT CREATE ON SCHEMA <your_database_name>.<your_schema_name> TO roadway_user;
GRANT SELECT, INSERT ON ALL TABLES IN SCHEMA <your_database_name>.<your_schema_name> TO roadway_user;
ALTER DEFAULT PRIVILEGES FOR USER <your_internal_management_user> IN SCHEMA <your_database_name>.<your_schema_name>
GRANT SELECT ON TABLES TO roadway_user;
```

Next you need to Configure Network Accessibility (Using AWS Management Console)

1. Go to AWS Management Console > Redshift and select your cluster
2. Make sure the cluster security settings allow for inbound connections. For this, you can follow [this AWS Tutorial](https://docs.aws.amazon.com/redshift/latest/mgmt/rs-security-group-public-private.html).

Afterwards, share connection credentials with Roadway:

* cluster name / endpoint, e.g. `example_cluster.<account_id>.<your-cluster-region>.redshift-serverless.amazonaws.com`
* database
* schema
* user&#x20;
* password&#x20;
* region, e.g. `us-west-2`
* port (if not provided, we assume the default - `5439` )

We recommend sharing these credentials via [sharing mechanisms](https://support.1password.com/share-items/?mac#share-an-item) in password management systems.


# Direct connectors

### Integrate data sources directly to Roadway

Follow instructions in the app for direct connectors

Direct connections

* Google Analytics
* Stripe
* Hubspot
* Salesforce
* Segment

Ad platforms

* Meta Ads
* Linkedin Ads
* Google Ads
* Twitter Ads

Don’t see your data source? Contact us in slack!


# Warehouse Requirements

When integrating a native warehouse, Roadway will use your existing data. For different sources, data in your warehouse must be modeled to adhere to the following requirements.&#x20;

{% content-ref url="/pages/UytYk547ZbKhMD98Wk3V" %}
[Page Views](/data-requirements/warehouse-requirements/page-views)
{% endcontent-ref %}

{% content-ref url="/pages/dxcMBW2nU5DHuwC2osJB" %}
[Users](/data-requirements/warehouse-requirements/users)
{% endcontent-ref %}

{% content-ref url="/pages/Nc0Uhr1osdv8TZ3tLyhx" %}
[Revenue](/data-requirements/warehouse-requirements/revenue)
{% endcontent-ref %}

{% content-ref url="/pages/TqQSbg6WzMIT9mxxJDEz" %}
[Ad Spend](/data-requirements/warehouse-requirements/ad-spend)
{% endcontent-ref %}

{% content-ref url="/pages/MNIzxh1jmT7QOQnbOMY9" %}
[CRMs](/data-requirements/warehouse-requirements/crms)
{% endcontent-ref %}


# Page Views

Tracking how people interact with your site

## Page Views Data Requirements

### Overview

Page-views are the foundation of attribution analysis. They represent individual website visits and page interactions that capture the customer journey from first touch to conversion. Roadway supports three different methods for providing page-view data: **Segment**, **Google Analytics 4 (GA4)**, and **Custom** data sources.

A page view represents a single page visit by a visitor, containing attribution parameters and referral information necessary for attribution modeling.

### Conceptual Requirements

Roadway expects page-view data to conform to the following schema, regardless of your chosen data source method:

| **Column Name**      | **Data Type**      | **Description**                                                                                                                                                                                                    |
| -------------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `visitor_id`         | varchar            | Unique identifier for the visitor (anonymous or identified). This is typically the anonymous\_id from Segment, user\_pseudo\_id from GA4, or a similar visitor identifier from your tracking system. **Required.** |
| `page_viewed_at`     | timestamp          | UTC timestamp of when the page view occurred. **Required.**                                                                                                                                                        |
| `user_id`            | varchar            | Unique identifier for authenticated users. This should be NULL for anonymous visitors and populated when a visitor becomes an identified user. Optional but recommended for complete attribution.                  |
| `landing_page_url`   | varchar            | The full URL of the page that was visited, including query parameters. **Required.**                                                                                                                               |
| `referring_page_url` | varchar            | The full URL of the page that referred the visitor to this page. This can be NULL for direct traffic or when referrer information is not available. Optional.                                                      |
| city                 | varchar (nullable) | (Optional) The city in which the visit occurred, often provided by your tracking implementation library.                                                                                                           |
| region               | varchar (nullable) | (Optional) The region (i.e. state, in U.S. locales) in which the visit occurred, often provided by your tracking implementation library.                                                                           |
| country              | varchar (nullable) | (Optional) The country in which the visit occurred, often provided by your tracking implementation library.                                                                                                        |
| continent            | varchar (nullable) | (Optional) The continent in which the visit occurred, often provided by your tracking implementation library.                                                                                                      |

***

## Data Source Options

### Option 1: Segment

If you already import page-view data via Segment to your warehouse, Roadway can leverage the Segment schema to transparently process page-views.

**Source Table**: Your complete Segment `pages` table. See [Segment's pages table documentation](https://segment.com/docs/connections/storage/warehouses/schema/#pages) for the complete schema.&#x20;

### Option 2: Google Analytics 4 (GA4)

Alternatively, Roadway can transparently process GA4 tracking data. Use this method if you're already landing GA4 data in your warehouse.

**Source**: GA4 `page_view` events collected for an analytics property, exposed via [GA4 Export tables](https://support.google.com/analytics/answer/7029846?hl=en).

{% hint style="info" %}
Often, GA4 data is managed via a [GA4 Export for BigQuery](https://support.google.com/analytics/answer/9823238?hl=en#zippy=%2Cin-this-article), but there are other methods for managing GA4 data.
{% endhint %}

### Option 3: Custom Data Source

{% hint style="info" %}
We highly recommend providing pages information directly from Segment or GA4 schemas. See the above sections for more details.
{% endhint %}

In rare cases, customers may set up their own tracking systems, or they may have custom data modeling downstream of exports from tracking solutions like Segment or GA4.&#x20;

Use this method for cases in which you have custom page-view tracking data or downstream custom models already landed in your warehouse.

**Required Table Schema**:

```sql
create table <your_schema>.page_views (
    visitor_id varchar not null,       -- your visitor identifier
    page_viewed_at timestamp not null, -- utc timestamp of page view
    user_id varchar,                   -- user identifier (nullable)
    landing_page_url varchar not null, -- full page url with parameters
    referring_page_url varchar,        -- referring page url (nullable)
    city varchar,
    region varchar,
    country varchar,
    continent varchar
);
```

#### Data Validation

* **Non-null visitor\_id**: Every page view must have a visitor identifier
* **Non-null page\_viewed\_at**: Every page view must have a timestamp
* **Non-null landing\_page\_url**: Every page view must have a URL
* **Unique page views**: The combination of `visitor_id` + `page_viewed_at` should be unique
* **Valid timestamps**: `page_viewed_at` should be a valid UTC timestamp

#### Data Integrity Expectations

* **Page view volume**: Expect 10-1000x more page views than users depending on your product
* **Anonymous vs. identified traffic**: A significant portion of page views will have `user_id` as NULL (anonymous visitors)
* **URL quality**: URLs should be well-formed

***

#### Coming Soon

If your traffic- or events-analytics stack is based on the following technologies:

* Amplitude
* Mixpanel
* Rudderstack

Please reach out; we'll be happy to quickly accommodate your needs.


# Users

Recording user signups and descriptive information

## Overview

A `users`table is a comprehensive record of users of your product, along with relevant segmentation information that might be useful when analyzing growth metrics. To that end, Roadway uses three broad categories of user data:

* internal identifiers (e.g. `user_id`and `visitor_id`)&#x20;
* sign up dates
* segmentation dimensions, e.g. (\`persona\`, \`usecase\`, etc.)

{% hint style="warning" %}
As a reminder, Roadway does not use PII (e.g. name, address, phone number, email, etc.), even for users.
{% endhint %}

Internally, Roadway uses this `users`table to not only provide metrics concerning users but also to link [visits](/data-requirements/warehouse-requirements/page-views) data to down- or cross-stream elements of your growth funnel, such as revenue or leads.

## Core Schema Requirements

The table you expose to Roadway should adhere to the following schema:

| **Column Name**                | **Data Type**                        | **Description**                                                                                                                                            |
| ------------------------------ | ------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `user_id`                      | varchar                              | Unique identifier for the user. This should be consistent with the user\_id used in your page views data. **Required.**                                    |
| `signed_up_at`                 | timestamp                            | UTC timestamp of when the user first registered or signed up for your product/service. This represents the conversion event for attribution. **Required.** |
| `<optional_custom_dimensions>` | `varchar` or `boolean` (recommended) | See below section. **Optional.**                                                                                                                           |

### Additional Constraints

The following constraints apply to the above table:

* user\_id is the primary key
* Do ***NOT*** provide PII in custom user dimensions

### Custom User Dimensions

When analyzing metrics, it is useful to group or filter by specific user segments that provide meaningful business context. Custom dimensions enable these kinds of high-specificity workflows within Roadway. The specific nature (and backing logic) of these dimensions is up to you.&#x20;

#### Example Custom Dimensions

Here are some examples of custom dimensions that might be applicable for your business:

| Attribute       | Data Type | Description                  | Possible Values                                    |
| --------------- | --------- | ---------------------------- | -------------------------------------------------- |
| `persona`       | varchar   | User segment or persona type | `enterprise`, `smb`, `individual`, `student`       |
| `plan_type`     | varchar   | Subscription or plan level   | `free`, `pro`, `enterprise`, `trial`               |
| `signup_source` | varchar   | Primary signup channel       | `organic`, `paid`, `referral`, `direct`            |
| `industry`      | varchar   | User's industry category     | `technology`, `healthcare`, `finance`, `education` |
| `company_size`  | varchar   | Organization size bracket    | `1-10`, `11-50`, `51-200`, `200+`                  |

#### Best Practices for Custom Dimensions

1. **Avoid PII**: Scrub emails, names, phone numbers, etc. by providing VIEWs on top of internal tables.
2. **Use categorical data**: Avoid high-cardinality fields like specific company names
3. **Standardize values**: Ensure consistent naming (e.g., always use lowercase)
4. **Handle NULL values**: Design your analysis to handle missing dimension data
5. **Limit dimension count**: Where possible, limit a custom dimensions to fewer than 20 values to maintain query performance and practical usability (despite this, Roadway supports displaying up to 100 values per dimension).

#### Example Custom Dimension Queries

```sql
-- good: low-cardinality categorical field
select 
    user_id
    , case 
        when annual_revenue < 1000000 then 'smb'
        when annual_revenue < 10000000 then 'mid_market'  
        else 'enterprise'
    end as company_size
from user_data;

-- avoid: high-cardinality or pii fields
select 
    user_id
    , company_name  -- too specific, could be pii
    , exact_revenue -- too high cardinality
    , full_email  -- pii
from user_data;
```

***

## Data Source Options

### Option 1: Segment

In cases where you are using Segment to land user data in your warehouse, use this method.

**Source Table**: Your Segment `identifies` table. See [Segment's identifies table documentation](https://segment.com/docs/connections/storage/warehouses/schema/#identifies) for the complete schema. Roadway uses the following fields:

* `anonymous_id` - Visitor identifier before signup
* `user_id` - User identifier after signup
* `timestamp` - When the identify call was made
* Custom traits (optional) - Additional user attributes (see [Segment traits documentation](https://segment.com/docs/connections/spec/identify/#traits)) which become custom user dimensions

**Key Notes**:

* Follows Segment's recommended pattern for user identification
* The first identify call per user\_id represents the signup/conversion event
* Additional identify calls for the same user\_id are ignored for signup timing
* Custom user traits can be included if available in your Segment implementation

### Option 2: Google Analytics 4 (GA4)

In cases where you are landing GA4 data in your warehouse and have configured signup event tracking, use this method.

**Source**: GA4 signup events (default: `sign_up`)&#x20;

**Required GA4 Setup**: See [GA4 documentation](https://developers.google.com/analytics/devguides/collection/ga4) for further context. Key requirements:

* `sign_up` events being tracked (or custom signup event configured; see below)
* [User ID tracking enabled in GA4](https://developers.google.com/analytics/devguides/collection/ga4/user-id?client_type=gtag)

**Custom User Properties**: GA4 allows you to capture additional user properties during signup events. See [GA4 custom event parameters documentation](https://developers.google.com/analytics/devguides/collection/ga4/custom-events) for implementation details. Common user properties include:

* User demographics (age range, gender)
* Geographic information (country, region, city)
* Device and platform information (device category, platform, browser) - automatically captured
* Custom business attributes sent as event parameters (plan\_type, persona, etc. - see above for examples)

**Custom Signup Events**: If you're not using the standard `sign_up` event, please provide us with the name of the event you are using to track user sign-ups.

**Key Notes**:

* Signup events must include a user\_id parameter in GA4
* Geographic and device information is automatically captured
* Multiple signup events for the same user\_id are deduplicated by taking the earliest timestamp

### Option 3: Custom Data Source

When you have a custom users table (directly from your application tables or via internal data modeling) in your warehouse, use this method

**Your Table Schema**:

```sql
create table your_schema.users (
    user_id varchar primary key,      -- unique user identifier
    signed_up_at timestamp not null,  -- utc signup timestamp
    
    -- optional: custom user dimensions
    custom_user_dimension_1 varchar,
    custom_user_dimension_2 varchar,
    -- ...
);
```

**Key Notes**:

* You have full control over user identification and custom dimensions
* Ensure user\_id values match those used in your page views data
* Custom dimensions should be categorical with reasonable cardinality (< 50 unique values)

#### Data Validation

* **Unique user\_id**: Each user should appear only once in the users table
* **Non-null user\_id**: Every user record must have a unique identifier
* **Non-null signed\_up\_at**: Every user must have a signup timestamp
* **Valid timestamps**: `signed_up_at` should be a valid UTC timestamp
* **User ID consistency**: user\_id values should match those used in page views data


# Revenue

Modeling your company's revenue

## Overview

Revenue data represents the financial transactions and subscription metrics that track your business's financial performance. This data is essential for understanding customer lifetime value, monthly recurring revenue (MRR), annual recurring revenue (ARR), churn analysis, and overall financial health.

Roadway AI's revenue analytics supports ingesting Stripe data from **Airbyte**, **Fivetran**, and **Custom**. This guide outlines the required tables and setup for integrating Stripe revenue data with our revenue analytics models.

## Data Source Options

Finer details about each integration option can be found below. As a note, for customers who have existing definitions (and modeling) for revenue metrics (such as MRR, New Customer ARR, etc.), we recommend using the [Custom Revenue Models option.](#custom-revenue-models)

### Airbyte Stripe Connector

Use this method if you're already using Airbyte for data integration. We officially support the [Airbyte Stripe source connector](https://docs.airbyte.com/integrations/sources/stripe) for extracting Stripe payment and subscription data into your data warehouse to then be consumed in Roadway.

#### Airbyte Stripe Streams

To use Roadway AI's revenue analytics with Airbyte, you must configure your Airbyte Stripe connector to sync the following tables to your data warehouse:

| **Table Name**                | **Description**                                          | **Required**                     |
| ----------------------------- | -------------------------------------------------------- | -------------------------------- |
| `stripe_customers`            | Customer information and metadata                        | Required                         |
| `stripe_subscriptions`        | Subscription lifecycle and billing details               | Required                         |
| `stripe_subscription_items`   | Individual items within subscriptions                    | Required                         |
| `stripe_charges`              | Payment transactions and charge details                  | Required                         |
| `stripe_invoices`             | Invoice records and billing information                  | Required                         |
| `stripe_invoice_line_items`   | Detailed line items for each invoice                     | Required                         |
| `stripe_products`             | Product catalog and definitions                          | Required                         |
| `stripe_prices`               | Pricing information for products                         | Required                         |
| `stripe_plans`                | Legacy subscription plans (if using older Stripe setups) | Required                         |
| `stripe_balance_transactions` | Financial transaction records                            | Required                         |
| `stripe_payment_intents`      | Payment intent tracking                                  | Optional                         |
| `stripe_refunds`              | Refund transaction details                               | Optional                         |
| `stripe_coupons`              | Discount and coupon information                          | Required                         |
| `stripe_checkout_sessions`    | Checkout session data                                    | Conditional Required (see below) |
| `stripe_events`               | Stripe webhook events                                    | Required                         |

**Key Notes**:

* ⚠️ `stripe_checkout_sessions` is conditionally required if you bill via [Stripe Payment Links](https://stripe.com/docs/payment-links)
* The [sync mode](https://docs.airbyte.com/understanding-airbyte/connections#sync-modes) for these tables should include a deduplication method. We recommend `Incremental - Append + Deduped`
* Airbyte allows for table prefixing. We recommend prefixing with `stripe_`

### Fivetran Stripe Connector

Use this method if you're using Fivetran as your data integration platform. We also support the [Fivetran Stripe source connector](https://fivetran.com/docs/connectors/applications/stripe) for extracting Stripe payment and subscription data into your data warehouse to then be consumed in Roadway.

#### Fivetran Stripe Tables

To use Roadway AI's revenue analytics with Fivetran, you must configure your Fivetran Stripe connector to sync the following tables to your data warehouse:

| **Table Name**        | **Description**                                          | **Required**                       |
| --------------------- | -------------------------------------------------------- | ---------------------------------- |
| `customer`            | Customer information and metadata                        | Required                           |
| `subscription`        | Subscription lifecycle and billing details               | Required                           |
| `subscription_item`   | Individual items within subscriptions                    | Required                           |
| `charge`              | Payment transactions and charge details                  | Required                           |
| `invoice`             | Invoice records and billing information                  | Required                           |
| `invoice_line_item`   | Detailed line items for each invoice                     | Required                           |
| `product`             | Product catalog and definitions                          | Required                           |
| `price`               | Pricing information for products                         | Required                           |
| `plan`                | Legacy subscription plans (if using older Stripe setups) | Required                           |
| `balance_transaction` | Financial transaction records                            | Required                           |
| `payment_intent`      | Payment intent tracking                                  | Optional                           |
| `refund`              | Refund transaction details                               | Optional                           |
| `coupon`              | Discount and coupon information                          | Required                           |
| `checkout_session`    | Checkout session data                                    | Conditionally Required (see below) |
| `event`               | Stripe webhook events                                    | Required                           |

**Key Notes**:

* ⚠️ `checkout_session` is conditionally required if you bill via [Stripe Payment Links](https://stripe.com/docs/payment-links)
* Fivetran automatically handles incremental syncing and deduplication
* Tables are synced using Fivetran's naming convention (singular form without `stripe_` prefix)
* We can also support [Fivetran's Stripe Data Model](https://fivetran.com/docs/transformations/data-models/stripe-data-model/stripe-transform-model?utm_source=erd)

### Custom Revenue Models

Use this method for maximum flexibility or when integrating with existing data infrastructure. This **custom connector option** allows you to implement your own Stripe data extraction and define your own revenue metrics while maintaining compatibility with our revenue analytics models.

#### Custom Revenue Analytics Tables

**`dim__customers`**

Customer dimension table containing customer metadata and segmentation information.

| **Column Name**                 | **Data Type** | **Description**                             | **Required** |
| ------------------------------- | ------------- | ------------------------------------------- | ------------ |
| `customer_id`                   | varchar       | Unique customer identifier (primary key)    | Required     |
| `user_id`                       | varchar       | Internal user identifier                    | Required     |
| `first_payment_date`            | date          | Date of customer's first successful payment | Required     |
| `created_date`                  | date          | Customer account creation date              | Required     |
| `currency`                      | varchar       | Customer's primary currency                 | Required     |
| `<optional_custom_dimension_1>` | varchar       | Custom customer segmentation field          | Optional     |
| ...                             | ...           | ...                                         | ...          |

**Primary Key:** `customer_id`

**Table Constraints:**

* `customer_id` must be unique across all records
* Supports custom customer dimension columns for business-specific segmentation
* Enables flexible customer analysis and cohort tracking

<details>

<summary><strong>DDL Example</strong></summary>

```sql
create table dim__customers (
    customer_id varchar(255) primary key,
    user_id varchar(255),
    first_payment_date date not null,
    created_date date not null,
    currency varchar(3) not null,
    custom_dimension_1 varchar(255),
    custom_dimension_2 varchar(255),
    custom_dimension_3 varchar(255)
);
```

</details>

**`fact__customer_arr_snapshot`**

Daily snapshot of customer Annual Recurring Revenue (ARR) and subscription metrics.

| **Column Name**       | **Data Type** | **Description**                                            | **Required** |
| --------------------- | ------------- | ---------------------------------------------------------- | ------------ |
| `customer_id`         | varchar       | Customer identifier                                        | ✅            |
| `subscription_id`     | varchar       | Subscription identifier                                    | ✅            |
| `date_day`            | date          | Date of the snapshot                                       | ✅            |
| `implied_arr`         | float         | Annualized recurring revenue based on current subscription | ✅            |
| `paid_arr`            | float         | ARR based on actual payments received                      | ✅            |
| `new_arr`             | float         | New ARR from new subscriptions on this date                | ✅            |
| `churn_arr`           | float         | ARR lost from canceled subscriptions                       | ✅            |
| `expansion_arr`       | float         | ARR gained from subscription upgrades/expansions           | ✅            |
| `contraction_arr`     | float         | ARR lost from subscription downgrades/contractions         | ✅            |
| `reactivation_arr`    | float         | ARR gained from reactivated subscriptions                  | ✅            |
| `num_seats`           | integer       | Number of seats/licenses in subscription                   | ⚠️           |
| `plan_type`           | varchar       | Subscription plan identifier                               | ✅            |
| `billing_period`      | varchar       | Billing frequency (monthly, annual, etc.)                  | ✅            |
| `subscription_status` | varchar       | Current subscription status                                | ✅            |

**Primary Key:** `(customer_id, subscription_id, date_day)`

**Table Constraints:**

* Must contain continuous daily records from first payment date to current date (or churn date)
* ARR calculations are automatically computed based on subscription pricing and billing cycles
* Enables comprehensive revenue trend analysis and customer lifecycle tracking
* Supports multi-subscription customers with separate records per subscription

<details>

<summary><strong>DDL Example</strong></summary>

```sql
create table fact__customer_arr_snapshot (
    customer_id varchar(255) not null,
    subscription_id varchar(255) not null,
    date_day date not null,
    implied_arr float not null,
    paid_arr float not null,
    new_arr float not null,
    churn_arr float not null,
    expansion_arr float not null,
    contraction_arr float not null,
    reactivation_arr float not null,
    num_seats integer,
    plan_type varchar(255) not null,
    billing_period varchar(50) not null,
    subscription_status varchar(50) not null,
    primary key (customer_id, subscription_id, date_day),
    foreign key (customer_id) references dim__customers(customer_id)
);
```

</details>

#### Data Validation

* **Unique customer\_id**: Each customer should appear only once in the customers dimension table
* **Non-null customer\_id**: Every customer record must have a unique identifier
* **Non-null subscription\_id**: Every ARR snapshot record must have a subscription identifier
* **Non-null date\_day**: Every ARR snapshot record must have a date
* **Valid timestamps**: All date fields should be valid dates
* **Non-negative ARR values**: All ARR metrics should be >= 0
* **Valid currency codes**: Customer currency should be valid 3-character ISO codes
* **Continuous date series**: ARR snapshots should contain continuous daily records from first payment to current date (or churn date)

#### Data Integrity Expectations

* **Customer consistency**: `customer_id` values should be consistent across all tables
* **Subscription lifecycle**: ARR snapshots should accurately reflect subscription state changes
* **Revenue calculations**: ARR calculations should be based on actual subscription pricing and billing cycles
* **Multi-subscription support**: Customers with multiple subscriptions should have separate ARR records per subscription
* **Data freshness**: Revenue data should be updated regularly to reflect current subscription states


# CRMs

Tracking your sales-led growth funnel

## Intro

In order to track the progression of prospects through your sales funnels, Roadway needs access to tables that track Leads/Contacts, Opportunities/Deals, and Pipeline ARR. With these tables, it is possible to attribute prospects to their causal growth levers.

Roadway treats the progression of prospects through Marketing and Sales pipelines as shown in the following diagram:

<img src="/files/DioCZM9F2cAoHQAusGK2" alt="Lead Lifecycle Stages and Opportunity/Deal Stages" class="gitbook-drawing">

In order to drive analysis of these pipelines, Roadway requires the following tables:

* `dim__contacts`
* `dim__opportunities`(`dim__deals`)&#x20;
* `fact__pipeline_arr_snapshot`

## Schema

### dim\_\_contacts

This table tracks the evolution of your Leads as they progress through the stages of your sales process. The schema is as follows:

| Column Name                               | Type                                                                                        | Description                                                                                                                                                                                                                                                                                              |
| ----------------------------------------- | ------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| contact\_id                               | varchar                                                                                     | Identifier of the contact, from Salesforce or Hubspot                                                                                                                                                                                                                                                    |
| visitor\_id                               | varchar (nullable)                                                                          | The anonymous visitor id associated with the form fill (or other process) that led to contact/lead creation. See [Add Anonymous IDs to CRM Contacts](https://app.gitbook.com/o/Nu4l1RKbmRqUw9cj7Aqp/s/QMBFYr0uPV4dZtHhcYRX/~/changes/26/required-ids-for-attribution/add-anonymous-ids-to-crm-contacts). |
| created\_date                             | date                                                                                        | UTC date that the contact was created                                                                                                                                                                                                                                                                    |
| \<lead\_lifecyclestage\_i>\_reached\_date | date                                                                                        | UTC date that the Lead reached the I-th lifecylce stage                                                                                                                                                                                                                                                  |
| ...                                       | ...                                                                                         | ...                                                                                                                                                                                                                                                                                                      |
| \<custom\_lead/contact\_dimension\_1>     | See the notes on [Custom User Dimensions](/data-requirements/warehouse-requirements/users). | Any custom contact/lead-segmentation dimension, such as \`pipeline\_name\`, \`opportunity\_type\`, \`country\`, etc.                                                                                                                                                                                     |
| ...                                       | ...                                                                                         | ...                                                                                                                                                                                                                                                                                                      |

#### Additional Constraints

* `contact_id`is the primary key
* Where possible, Roadway uses `visitor_id`to join to relevant attribution.  See [Add Anonymous IDs to CRM Contacts](https://app.gitbook.com/o/Nu4l1RKbmRqUw9cj7Aqp/s/QMBFYr0uPV4dZtHhcYRX/~/changes/26/required-ids-for-attribution/add-anonymous-ids-to-crm-contacts) for more details.
* The columns denoted as `<lead_lifecyclestage_i>_reached_date` are custom columns that map to your specific Lead Lifecycle Stages (akin to the diagram above).

### dim\_\_opportunities (dim\_\_deals)

This table tracks the evolution of your Leads after they graduate to Opportunities (Salesforce) or Deals (Hubspot). The schema is as follows:

| Column Name                             | Type                                                                                        | Description                                                                                                                                                 |
| --------------------------------------- | ------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| opportunity\_id (deal\_id)              | varchar                                                                                     | Unique identifier of the opportunity (SFDC) or deal (Hubspot)                                                                                               |
| contact\_id                             | varchar                                                                                     | Identifier for the owning (or oldest) contact associated with the opportunity or deal. This contact will be used to drive attribution for this opportunity. |
| created\_date                           | date                                                                                        | UTC date that the opportunity or deal was created                                                                                                           |
| \<opportunity\_stage\_i>\_reached\_date | date                                                                                        | UTC date that the opportunity reached the I-th stage of the opportunity pipeline.                                                                           |
| ...                                     | ...                                                                                         | ...                                                                                                                                                         |
| closed\_date                            | date (nullable)                                                                             | UTC date that the opportunity or deal was closed, null if not yet closed                                                                                    |
| is\_closed\_won                         | boolean                                                                                     | Whether the deal was closed with the opportunity converting to a customer                                                                                   |
| \<custom\_opportunity\_dimension\_1>    | See the notes on [Custom User Dimensions](/data-requirements/warehouse-requirements/users). | Any custom opportunity-segmentation dimension, such as \`pipeline\_name\`, \`opportunity\_type\`, \`country\`, etc.                                         |
| ...                                     | ...                                                                                         | ...                                                                                                                                                         |

#### Additional Constraints

* `opportunity_id`is the primary key
* The columns denoted as `<opportunity_stage_i>_reached_date` are custom columns that map to your specific Opportunity (Deal) Stages (akin to the diagram above).

### fact\_\_pipeline\_arr\_snapshot

Very similar to \`fact\_\_customer\_arr\_snapshot\`, this table tracks the evolution of Pipeline ARR attributed to your sales processes. The schema is as follows:

| Column Name                | Type    | Description                                                                                                                                                         |
| -------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| opportunity\_id (deal\_id) | varchar | Unique identifier of the opportunity (SFDC) or deal (Hubspot)                                                                                                       |
| date\_day                  | date    | An "as\_of-style" date                                                                                                                                              |
| pipeline\_arr              | float   | The annualized recurring revenue value as implied by opportunity (deal) revenue, multiplied by the probability of the opportunity (deal) closing, for the given row |

#### Additional Constraints

* The primary key of this table is `(opportunity_id, date_day).`&#x20;
* It is expected that from the date of an opportunity's creation to the date of its closure (inclusive), there exists a row for each (opportunity, date).


# Ad Spend

A record of Performance Marketing outcomes

## Overview

Ads data represents the marketing campaigns and performance metrics from various advertising platforms that drive traffic and conversions to your business. This data is essential for understanding campaign effectiveness, optimizing marketing spend, and attributing conversions back to specific marketing touchpoints.

This document outlines the various options available for integrating ads data from different platforms into Roadway.&#x20;

## Supported Advertising Platforms

The package currently supports the following advertising platforms:

* **Google Ads** - Search, display, video, and shopping campaigns
* **Meta Ads (Facebook/Instagram)** - Social media advertising campaigns
* **LinkedIn Ads** - Professional network advertising campaigns
* **Reddit Ads** - Community-based advertising campaigns
* **TikTok Ads -** Social media advertising campaigns

## Data Connector Options

When providing ad-platform data to Roadway, you may use any of the supported connector-platform combinations found below:

| **Connector** | **Google Ads** | **Meta Ads** | **LinkedIn Ads** | **Reddit Ads** | **TikTok Ads** | **Bing Ads** | **X (Twitter) Ads** | **Snapchat Ads** | **Pinterest Ads** |
| ------------- | -------------- | ------------ | ---------------- | -------------- | -------------- | ------------ | ------------------- | ---------------- | ----------------- |
| **Airbyte**   | ✅              | ✅            | ✅                | ❌              | ✅              | ❌            | ❌                   | ❌                | ❌                 |
| **Stitch**    | ✅              | ❌            | ❌                | ❌              | ❌              | ❌            | ❌                   | ❌                | ❌                 |
| **Polytomic** | ❌              | ❌            | ❌                | ✅              | ❌              | ❌            | ❌                   | ❌                | ❌                 |
| **Fivetran**  | ✅              | ✅            | ✅                | ❌              | ✅              | ❌            | ❌                   | ❌                | ❌                 |
| **Custom**    | ✅              | ✅            | ✅                | ✅              | ✅              | ✅            | ✅                   | ✅                | ✅                 |

### Airbyte

Airbyte is an open-source data integration platform that supports multiple advertising platforms through their connector library.

**Google Ads via Airbyte**

* **Documentation**: [Airbyte Google Ads Connector](https://docs.airbyte.com/integrations/sources/google-ads)
* **Tables Used**:
  * `google_ads_campaigns` - Campaign metadata and daily performance metrics
* **Key Fields**: `campaign_id`, `campaign_name`, `campaign_status`, `segments_date`, `metrics_cost_micros`

**Meta Ads via Airbyte**

* **Documentation**: [Airbyte Facebook Marketing Connector](https://docs.airbyte.com/integrations/sources/facebook-marketing)
* **Tables Used**:
  * `meta_ads_campaigns` - Campaign metadata
  * `meta_ads_ads_insights` - Performance metrics and insights
* **Key Fields**: `campaign_id`, `campaign_name`, `account_id`, `started_at`, `stopped_at`, `campaign_status`

**LinkedIn Ads via Airbyte**

* **Documentation**: [Airbyte LinkedIn Ads Connector](https://docs.airbyte.com/integrations/sources/linkedin-ads)
* **Tables Used**:
  * `linkedin_ads_campaigns` - Campaign metadata
  * `linkedin_ads_ad_campaign_analytics` - Performance analytics
* **Key Fields**: `campaign_id`, `campaign_name`

### Stitch

Stitch is a cloud-based ETL service that provides managed data pipelines.

**Google Ads via Stitch**

* **Documentation**: [Stitch Google Ads Integration](https://www.stitchdata.com/docs/integrations/saas/google-ads)
* **Tables Used**:
  * `google_ads_campaigns` - Campaign metadata and daily performance metrics
* **Key Fields**: `campaign_id`, `campaign_name`, `campaign_status`, `segments_date`, `metrics_cost_micros`

### Polytomic

Polytomic specializes in reverse ETL and API integrations, particularly useful for platforms not covered by other connectors.

**Reddit Ads via Polytomic**

* **Documentation**: [Polytomic Reddit Ads Integration](https://docs.polytomic.com/integrations/reddit-ads)
* **Tables Used**:
  * `campaign` - Reddit campaign metadata
  * `report_campaign_id` - Campaign performance reports
* **Key Fields**: `id`, `name`, `campaign_id`, `spend`, `impressions`, `clicks`, `date`

### Fivetran

Fivetran provides enterprise-grade data connectors with automatic schema handling.

**Google Ads via Fivetran**

* **Documentation**: [Fivetran Google Ads Connector](https://fivetran.com/docs/applications/google-ads)
* **Tables Used**: `campaign_stats`, `campaign_history`

**Meta Ads via Fivetran**

* **Documentation**: [Fivetran Facebook Ads Connector](https://fivetran.com/docs/applications/facebook-ads)
* **Tables Used**: `campaign`, `ads_insights`

**LinkedIn Ads via Fivetran**

* **Documentation**: [Fivetran LinkedIn Ads Connector](https://fivetran.com/docs/applications/linkedin-ads)
* **Tables Used**: `campaigns`, `ad_analytics_by_campaign`

### Custom Data Source

If you have already aggregated ad spend and wish to expose custom, internal models, use this method.

**Required Output Schema**

> NOTE: This schema is "downstream" of the tables that would be exported by 3rd-party ETL providers.

Your custom connector must provide data that conforms to the final reporting table schemas:

**Campaign Dimension Schema** (`dim__marketing_campaigns`):

```sql
create table dim__marketing_campaigns (
    campaign_id varchar not null,        -- unique identifier from source platform
    campaign_name varchar not null,      -- campaign name from source platform  
    platform_name varchar not null,      -- name of advertising platform, e.g. 'Google Ads', 'LinkedIn Ads'
    unique (campaign_id, platform_name)  -- composite unique constraint
);
```

**Ad Group Dimension Schema** (`dim__marketing_ad_groups`):

```sql
create table dim__marketing_ad_groups (
    ad_group_id varchar not null,        -- unique identifier from source platform
    ad_group_name varchar not null,      -- ad group name from source platform  
    platform_name varchar not null,      -- name of advertising platform, e.g. 'Google Ads', 'LinkedIn Ads'
    unique (campaign_id, platform_name)  -- composite unique constraint
);
```

**Ad Dimension Schema** (`dim__marketing_ads`):

```sql
create table dim__marketing_ads (
    ad_id varchar not null,        -- unique identifier from source platform
    ad_name varchar not null,      -- ad name from source platform  
    platform_name varchar not null,      -- name of advertising platform, e.g. 'Google Ads', 'LinkedIn Ads'
    unique (campaign_id, platform_name)  -- composite unique constraint
);
```

**Campaign Performance Schema** (`fact__marketing_campaign_performance`):

```sql
create table fact__marketing_campaign_performance (
    date_day date not null,              -- performance date (YYYY-MM-DD)
    campaign_id varchar not null,        -- matches campaign dimension
    ad_group_id varchar, -- matches ad_group dimension (assumed unvailable if null)
    ad_id varchar not null, -- matches ad dimension (assumed unavailable if null)
    spend decimal(18,2) not null check (spend >= 0), -- cost in currency units (not micros)
    platform_name varchar not null,      -- name of advertising platform
    unique (date_day, campaign_id, ad_group_id, ad_id, platform_name)    -- composite unique constraint
);
```

#### Data Validation

* **Non-null campaign\_id**: Every campaign must have a unique identifier
* **Non-null campaign\_name**: Every campaign must have a name
* **Non-null platform\_name**: Every record must specify the advertising platform
* **Non-null date\_day**: Every performance record must have a date
* **Non-null spend**: Every performance record must have spend data
* **Valid date format**: `date_day` should be in YYYY-MM-DD format
* **Positive spend values**: `spend` must be >= 0 and in actual currency units (not micros)
* **Unique campaigns**: The combination of `campaign_id` + `platform_name` should be unique
* **Unique performance records**: The combination of `date_day` + `campaign_id` + `platform_name` should be unique

#### Data Integrity Expectations

* **campaign\_id**: Must be unique within platform and consistent across time
* **platform\_name**: Should match the `platform_name` configured in variables
* **Deduplication**: Handle any duplicate records from your source system
* **Freshness**: Implement appropriate freshness checks for your data source

## Joining Campaigns to UTMs

Internally, Roadway attempts to join campaigns in ads performance reports to UTMs from visit data with the following rules:

1. On `campaign_name = utm_campaign`, falling back to
2. On `campaign_id = utm_campaign`


# Required IDs for attribution

Roadway requires different IDs across data sources (direct implementations) and within tables (warehouse-native) in order provide custom attribution across all metrics and data sources.

## Required & Optional IDs

| Data source / tables | Required IDs                                                  | Optional IDs                                               |
| -------------------- | ------------------------------------------------------------- | ---------------------------------------------------------- |
| Sessions             | <p><code>anonymousID</code></p><p><code>userID</code></p>     | `customerID`                                               |
| Users                | `userID`                                                      | <p><code>anonymousID</code><br><code>customerID</code></p> |
| Revenue              | <p><code>customerID</code></p><p><code>userID</code></p>      | `anonymousID`                                              |
| CRM                  | <p><code>contactID</code> </p><p><code>anonymousID</code></p> | <p><code>userID</code><br><code>customerID</code></p>      |

### Roadway solutions

We provide simple solutions for you to add missing and hard-to-route IDs to make it easy for you.

#### [Add Anonymous IDs to CRM contacts](/required-ids-for-attribution/implementing-the-roadway-tag)


# Implementing the Roadway Tag

Follow the steps below (15-45 mins) to enable marketing attribution on metrics derived from CRM data through Anonymous IDs from Sessions on CRM contacts.

## Overview

Add Attribution IDs to CRM contacts via Roadway tag.

### **1.** [**Add Roadway tag**](#id-1.-add-roadway-tag-1)

### 2. [Choose your Form provider & complete mapping](#id-2.-choose-your-form-provider-and-complete-id-mapping)

***

## **1. Add Roadway Attribution Tag**

Growth marketing teams need to attribute customers across all key growth metrics in order to effectively spend time and budgets. The lack of tools and integrations to pass the right IDs across data platforms to attribute every customer touchpoint across those metrics is the main reason why companies rarely do this. The **Roadway Attribution Tag** bridges the gap—starting with passing anonymousIDs to CRMs to enable end-to-end marketing attribution on sales funnel metrics. It works like this:

* **Before the form** – captures the anonymous ID your analytics tool (GA4 or Segment) assigns to each browser.
* **During the form** – writes that ID into hidden form fields automatically.
* **After the form** – when the submission becomes a CRM contact and lands in your data warehouse, you can join the visitor’s pre-signup behavior to the new customer record.

**Result:** full-funnel reporting that shows *which channels and campaigns actually turn visitors into revenue.*

#### Setup

Add the following script tag to the `<head>` section of your website or on Google Tag Manager to All Pages:

```
<script defer src="//analytics.roadwayai.com/tag.js"></script>
```

For more information, visit <https://github.com/RoadwayAI/roadway-attribution-tag>&#x20;

***

## 2. Choose your form provider & complete ID mapping

* [**Hubspot Forms**](/required-ids-for-attribution/implementing-the-roadway-tag/add-anonymous-ids-to-crm-with-hubspot-forms)
* [**Custom Forms**](/required-ids-for-attribution/implementing-the-roadway-tag/add-anonymous-ids-to-crm-with-custom-forms)


# Add Anonymous IDs to CRM with Custom Forms

Choose your Sessions data source.

* [**Segment**](/required-ids-for-attribution/implementing-the-roadway-tag/add-anonymous-ids-to-crm-with-custom-forms/segment-with-custom-forms)
* [**Google Analytics**](/required-ids-for-attribution/implementing-the-roadway-tag/add-anonymous-ids-to-crm-with-custom-forms/google-analytics-with-custom-forms)


# Segment with Custom Forms

## Segment with Custom Forms

## **1. Add Roadway Tag**

Add the following script tag to the `<head>` section of your website or on Google Tag Manager to All Pages:

```
<script defer src="//analytics.roadwayai.com/tag.js"></script>
```

## **2. Salesforce CRM**

If you’re using Salesforce for your CRM, you need to add a hidden field, custom property, and map those in your integration. Roadway tag will take care of the rest.

* **Add Hidden Field to Form:**
  1. Navigate to your form
  2. Add a hidden field named `segment_anon_id`.
* **Create Salesforce Property:**

  1. Log into Salesforce and enter the Setup menu.
  2. Navigate to Object Manager and select the "Contact" object.
  3. Click "Fields & Relationships" then select "New."
  4. Choose "Text" as the field type and set the field label to `segment_anon_id`.
  5. Specify the field length and visibility settings as needed.
  6. Confirm the settings and click "Save."

  Detailed instructions are available in the [Salesforce Custom Field Guide](https://help.salesforce.com/s/articleView?id=platform.adding_fields.htm\&type=5).
* **Map Form field to Salesforce:**
  1. Navigate to your Salesforce account settings.
  2. Click on "Integrations" and select your form integration
  3. Add the new `segment_anon_id` field mapping to the mapping
  4. Click "Save" to apply the mapping.

## **2. Hubspot CRM**

* **Add Hidden Field to Form:**
  1. Navigate to your form
  2. Add a hidden field named `segment_anon_id`.
* **Add Hidden Field to HubSpot Form:**

  1. Log into HubSpot, navigate to your Forms
  2. Click on the "Edit" button for the form(s) you want to edit
  3. On the "existing fields" section, search for and add the `segment_anon_id` contact property you just created
  4. On the new `segment_anon_id` input field, click on the "Edit" button and click the "Make this field hidden" box
  5. Click the "Update" button in top right corner

  For details, see [HubSpot Forms Guide](https://knowledge.hubspot.com/forms/create-forms#customize-your-form-options).
* **Create Hubspot contact Property:**
  * Log into HubSpot and select account "Settings" from the dropdown menu.
  * In the left sidebar menu, go to "Properties" under the "Data Management" section.
  * Click the "Create property" button in the upper right corner.
  * Configure Property Details:
    * Object Type: Select "Contact" to ensure the property is associated with contact records.
    * Group: Choose an existing property group (e.g., "Contact Information") or create a new group to organize your properties.
    * Label: Enter `segment_anon_id` as the property name.
    * Field Type: Select "Single-line text" to match the Salesforce "Text" field type.
    * Configure field to be "Hidden".
  * Save the Property: After verifying the details, click "Create" to finalize the new contact property.


# Google Analytics with Custom Forms

## Google Analytics with Custom Forms

## **1. Add Roadway Tag**

Add the following script tag to the `<head>` section of your website or on Google Tag Manager to All Pages:

```
<script defer src="//analytics.roadwayai.com/tag.js"></script>
```

## **2. Salesforce CRM**

If you’re using Salesforce for your CRM, you need to add a hidden field, custom property, and map those in your integration. Roadway tag will take care of the rest.

* **Add Hidden Field to Form:**
  1. Navigate to your form
  2. Add a hidden field named `ga4_pseudo_user_id`.
* **Create Salesforce Property:**
  1. Log into Salesforce and enter the Setup menu.
  2. Navigate to Object Manager and select the "Contact" object.
  3. Click "Fields & Relationships" then select "New."
  4. Choose "Text" as the field type and set the field label to `ga4_pseudo_user_id`.
  5. Specify the field length to 255.
  6. Confirm the settings and click "Next."
  7. Click "Next" again on step 3 "Establish field-level security".
  8. Click "Save" on step 4 "Add to page layouts".
* Detailed instructions are available in the [Salesforce Custom Field Guide](https://help.salesforce.com/s/articleView?id=platform.adding_fields.htm\&type=5).
* **Map Form field to Salesforce:**
  1. Navigate to your Salesforce account settings.
  2. Click on "Integrations" and select your form integration
  3. Add the new `ga4_pseudo_user_id` field mapping to the mapping
  4. Click "Save" to apply the mapping.

## **2. Hubspot CRM**

* **Add Hidden Field to Form:**
  1. Navigate to your form
  2. Add a hidden field named `ga4_pseudo_user_id`.
* **Add Hidden Field to HubSpot Form:**

  1. Log into HubSpot, navigate to your Forms
  2. Click on the "Edit" button for the form(s) you want to edit
  3. On the "existing fields" section, search for and add the `ga4_pseudo_user_id` contact property you just created
  4. On the new `ga4_pseudo_user_id` input field, click on the "Edit" button and click the "Make this field hidden" box
  5. Click the "Update" button in top right corner

  For details, see [HubSpot Forms Guide](https://knowledge.hubspot.com/forms/create-forms#customize-your-form-options).
* **Create Hubspot contact Property:**
  * Log into HubSpot and select account "Settings" from the dropdown menu.
  * In the left sidebar menu, go to "Properties" under the "Data Management" section.
  * Click the "Create property" button in the upper right corner.
  * Configure Property Details:
    * Object Type: Select "Contact" to ensure the property is associated with contact records.
    * Group: Choose an existing property group (e.g., "Contact Information") or create a new group to organize your properties.
    * Label: Enter `ga4_pseudo_user_id` as the property name.
    * Field Type: Select "Single-line text" to match the Salesforce "Text" field type.
    * Configure field to be "Hidden".
  * Save the Property: After verifying the details, click "Create" to finalize the new contact property.


# Add Anonymous IDs to CRM with Hubspot Forms

Choose your Session data source:

* [**Google Analytics**](/required-ids-for-attribution/implementing-the-roadway-tag/add-anonymous-ids-to-crm-with-hubspot-forms/google-analytics-with-hubspot-forms)


# Segment with Hubspot Forms


# Google Analytics with Hubspot Forms

You must first add the Roadway tag

## **1. Add Roadway Tag**

Add the following script tag to the `<head>` section of your website or on Google Tag Manager to All Pages:

```
<script defer src="//analytics.roadwayai.com/tag.js"></script>
```

## Complete ID mapping

### Hubspot Forms

#### **Choose your CRM provider**

* [**Hubspot**](#hubspot)
* [**Salesforce**](#salesforce)

***

### **Hubspot**

#### Choose your Google Analytics implementation method:

* [**Google Analytics**](#google-analytics)
* [**Google Tag Manager**](#google-tag-manager)

***

### **Google Analytics**

If you have Google Analytics 4 implemented directly on your website, you’re all set! The tag will automatically send HubSpot form submissions to GA4.

***

### **Google Tag Manager**

If you’re using Google Tag Manager, you need to add a custom event and variable. You can skip all the instructions below and we can do it for you (if you prefer)

* [**Have Roadway add event and variable**](#have-roadway-add-event-and-variable)
* [**Add event and variable myself**](#add-event-and-variable-myself)

***

#### **Have Roadway add event and variable:**

<mark style="color:orange;">📌</mark> <mark style="color:orange;"></mark><mark style="color:orange;">**This is for Google Tag Manager only.**</mark>

1. In **Admin**, under the **Account** column, click **User Management**.
2. In the **User Management** panel, click the **+** button, then click **Add users**.
3. Enter **<service@roadwayai.com>** in the email field.
4. Select **Notify new users by email** to send an invitation to the user.
5. Assign the following permissions:
   * **Account Permissions**: Choose **User** or **Administrator** as needed.
   * **Container Permissions**: Select **Publish** for the relevant container(s).
6. Click **Invite** to send the invitation.

***

#### **Add event and variable myself:**

* **Create and configure Custom Event Trigger:**
  1. Click on **"Triggers"** in the left-hand menu.
  2. Click **"New"**.
  3. Name your trigger `Roadway Custom Event - hubspot_form_submission` on the top left
  4. Click on **"Trigger Configuration"**.
  5. Select **"Custom Event"**.
  6. In the **"Event Name"** field, enter `hubspot_form_submission`.
  7. Choose **"All Custom Events"**.
  8. Click **"Save"** to finalize the trigger.
* **Create the hubspot\_utk Variable:**
  1. Go to **"Variables"**, Click **"New"**.
  2. Select **"Data Layer Variable",** Name it `DL - hubspot_utk` on the top left
  3. Set the **"Data Layer Variable Name"** field to `hubspot_utk`.
  4. Save the variable.
* **Create and configure GA4 Event Tag:**
  1. In GTM, click on **"Tags"** in the left-hand menu.
  2. Click **"New",** Name your tag `Roadway GA4 - HubSpot Form Submission`.
  3. Click on **"Tag Configuration"**.
  4. Select **"Google Analytics: GA4 Event"**.
  5. In the **"Configuration Tag"** dropdown, select your existing GA4 Configuration tag.
     1. If you don’t have one, set it up first by inputting your [**Measurement ID**](https://support.google.com/analytics/answer/9539598?hl=en).
  6. In the **"Event Name"** field, enter the exact name of your custom event: `hubspot_form_submission`.
  7. Scroll down to the **"Event Parameters"** section, Click **"Add Row"** to add two new parameters.

     <table data-header-hidden><thead><tr><th width="418"></th><th></th></tr></thead><tbody><tr><td><strong>Parameter Name</strong></td><td><strong>Value</strong></td></tr><tr><td>hubspot_utk</td><td><code>{{DL - hubspot_utk}}</code></td></tr></tbody></table>
  8. Click on **"Triggering",** select the custom event trigger `Roadway Custom Event - hubspot_form_submission`.
  9. Click **"Save",** submit and publish the GTM container.

### Salesforce

### Google Analytics/Tag Manager/Segment (JS embed)

If you’re using Salesforce for your CRM, you need to add a hidden field, custom property, and map those in your integration. Roadway tag will take care of the rest. You can skip all the instructions below and we can do it for you (if you prefer).

* [**Have Roadway add hidden field, property, and mapping for me**](#have-roadway-add-hidden-field-property-and-mapping-for-me)
* [**Add hidden field, property, and mapping myself**](#add-hidden-field-property-and-mapping-myself)

***

#### Have Roadway add hidden field, property, and mapping for me:

<mark style="color:orange;">📌</mark> <mark style="color:orange;"></mark><mark style="color:orange;">**This is for Salesforce only.**</mark>

* In **Setup**, under the **Administration** section, click **Users**.
* In the **Users** panel, click the **New User** button, enter **<service@roadwayai.com>** in the email field.
* Check **Generate new password and notify user immediately** to send an email invitation to the user.
* Set the following permissions:
  * **Profile**: Choose **System Administrator** access level.
  * **Role**: Assign an appropriate role if your organization uses roles.
* Click **Save** to create the user account and send the invitation.

***

#### Add hidden field, property, and mapping myself:

* **Create Hubspot contact Property:**
  * Log into HubSpot and select account "Settings" from the dropdown menu.
  * In the left sidebar menu, go to "Properties" under the "Data Management" section.
  * Click the "Create property" button in the upper right corner.
  * Configure Property Details:
    * Object Type: Select "Contact" to ensure the property is associated with contact records.
    * Group: Choose an existing property group (e.g., "Contact Information") or create a new group to organize your properties.
    * Label: Enter `ga4_pseudo_user_id` as the property name.
    * Field Type: Select "Single-line text" to match the Salesforce "Text" field type.
  * Save the Property: After verifying the details, click "Create" to finalize the new contact property.
* **Add Hidden Field to HubSpot Form:**

  1. Log into HubSpot, navigate to your Forms
  2. Click on the "Edit" button for the form(s) you want to edit
  3. On the "existing fields" section, search for and add the `ga4_pseudo_user_id` contact property you just created
  4. On the new `ga4_pseudo_user_id` input field, click on the "Edit" button and click the "Make this field hidden" box
  5. Click the "Update" button in top right corner

  For details, see [HubSpot Forms Guide](https://knowledge.hubspot.com/forms/create-forms#customize-your-form-options).
* **Create Salesforce contact Property:**

  1. Log into Salesforce and enter the Setup menu.
  2. Navigate to Object Manager and select the "Contact" object.
  3. Click "Fields & Relationships" then select "New."
  4. Choose "Text" as the field type and set the field label to `ga4_pseudo_user_id`.
  5. Specify the field length to 255.
  6. Confirm the settings and click "Next."
  7. Click "Next" again on step 3 "Establish field-level security".
  8. Click "Save" on step 4 "Add to page layouts".

  Detailed instructions are available in the [Salesforce Custom Field Guide](https://help.salesforce.com/s/articleView?id=platform.adding_fields.htm\&type=5).
* **Map HubSpot contact field to Salesforce contact field:**

  1. Navigate to your HubSpot account settings.
  2. Click on "Integrations" and select "Salesforce."
  3. Confirm that "contact created or updated in (hubspot) -> create or update the contact (in salesforce)
  4. Navigate to Contacts property mappings
  5. Under the "Field Mappings" section, click select "Add new field mapping”
  6. Select `ga4_pseudo_user_id` from the HubSpot form fields list and map it to `ga4_pseudo_user_id` in Salesforce contact properties.
  7. Click "Save" to apply the mapping.

  Guidance can be found here: [HubSpot-Salesforce Integration Field Mapping](https://knowledge.hubspot.com/salesforce/set-up-and-use-salesforce-custom-object-sync?hubs_content=knowledge.hubspot.com%2Fsalesforce%2Finstall-the-hubspot-salesforce-integration\&hubs_content-cta=Salesforce%2520integration%2520settings).


