Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
28cf0b9
bug/last-touch-attribution
fivetran-catfritz Aug 25, 2025
40f2653
add tests
fivetran-catfritz Aug 25, 2025
6afd41b
bump version
fivetran-catfritz Aug 25, 2025
b9374ae
formatting
fivetran-catfritz Aug 26, 2025
de005bc
updates from review
fivetran-catfritz Aug 26, 2025
3475e10
round 2 suggestions
fivetran-catfritz Aug 26, 2025
a6d9f85
make breaking change
fivetran-catfritz Aug 26, 2025
4c638c9
add event_attribution
fivetran-catfritz Sep 2, 2025
aef4ad5
seed fixes
fivetran-catfritz Sep 2, 2025
10649bc
fix yml
fivetran-catfritz Sep 2, 2025
ec91c73
update fallback to false
fivetran-catfritz Sep 2, 2025
892444e
changelog
fivetran-catfritz Sep 2, 2025
906dc9a
fix bigquery
fivetran-catfritz Sep 2, 2025
47eb568
formatting
fivetran-catfritz Sep 2, 2025
b16ffc0
fix version
fivetran-catfritz Sep 2, 2025
446ac24
Update CHANGELOG.md
fivetran-catfritz Sep 2, 2025
e0c8271
fix seeds
fivetran-catfritz Sep 2, 2025
d161efd
add decision log and change var to using_native_attribution
fivetran-catfritz Sep 11, 2025
951cdde
changelog readme
fivetran-catfritz Sep 11, 2025
fccfba0
readme
fivetran-catfritz Sep 11, 2025
312af98
fix yml
fivetran-catfritz Sep 11, 2025
d00b7bc
updates
fivetran-catfritz Sep 11, 2025
4c91a1e
updates
fivetran-catfritz Sep 12, 2025
850c1d6
update
fivetran-catfritz Sep 12, 2025
970ac40
Generate dbt docs via GitHub Actions
github-actions[bot] Sep 12, 2025
6011453
fix yml
fivetran-catfritz Sep 12, 2025
55eee4a
Merge branch 'bug/last-touch-attribution' of https://github.com/fivet…
fivetran-catfritz Sep 12, 2025
4e3449f
Apply suggestions from code review
fivetran-catfritz Sep 16, 2025
a1ab7ee
fix union
fivetran-catfritz Sep 16, 2025
5d70634
fix join
fivetran-catfritz Sep 16, 2025
0118515
update ref for get_cols
fivetran-catfritz Sep 16, 2025
b56fa65
add depends
fivetran-catfritz Sep 16, 2025
6cf73b1
fix source relation again
fivetran-catfritz Sep 16, 2025
7346e05
fix comma
fivetran-catfritz Sep 16, 2025
ea2713e
review updates
fivetran-catfritz Sep 16, 2025
a853071
readme
fivetran-catfritz Sep 16, 2025
b15d2b4
Generate dbt docs via GitHub Actions
github-actions[bot] Sep 16, 2025
fd8de41
update comment
fivetran-catfritz Sep 16, 2025
718bfd7
Apply suggestions from code review
fivetran-catfritz Sep 17, 2025
0a62a8b
Generate dbt docs via GitHub Actions
github-actions[bot] Sep 17, 2025
57111ef
Update models/intermediate/int_klaviyo__event_attribution.sql
fivetran-catfritz Sep 17, 2025
e2acd53
Generate dbt docs via GitHub Actions
github-actions[bot] Sep 17, 2025
a29e52c
Apply suggestions from code review
fivetran-catfritz Sep 17, 2025
3c16f65
changelog
fivetran-catfritz Sep 17, 2025
77b09e0
Merge branch 'bug/last-touch-attribution' of https://github.com/fivet…
fivetran-catfritz Sep 17, 2025
2fa4985
changelog
fivetran-catfritz Sep 17, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .buildkite/scripts/run_models.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ cd integration_tests
dbt deps
dbt seed --target "$db" --full-refresh
dbt run --target "$db" --full-refresh
dbt run --target "$db"
dbt test --target "$db"
dbt run --vars '{using_native_attribution: false}' --target "$db" --full-refresh
dbt test --target "$db"
dbt source freshness --target "$db" || echo "...Only verifying freshness runs…"

dbt run-operation fivetran_utils.drop_schemas_automation --target "$db"
dbt run-operation fivetran_utils.drop_schemas_automation --target "$db"
48 changes: 48 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,51 @@
# dbt_klaviyo v1.1.0
[PR #53](https://github.com/fivetran/dbt_klaviyo/pull/53) includes the following updates:

## Schema/Data Change (--full-refresh required after upgrading)
**4 total changes • 1 possible breaking change**

| Data Model(s) | Change type | Old | New | Notes |
| ---------- | ----------- | -------- | -------- | ----- |
| `klaviyo__events`<br>`int_klaviyo__event_attribution`<br>`stg_klaviyo__event` | New column | | `event_attribution` | New field sourced from `property_attribution` in the `EVENT` source table. Contains Klaviyo's native attribution data for events, which is now used by default for attribution. |
| `EVENT` (source) | New column | | `property_attribution` | **Breaking change**: If you are already including this field through the [passthrough columns](https://github.com/fivetran/dbt_klaviyo?tab=readme-ov-file#passthrough-columns) variable `klaviyo__event_pass_through_columns`, remove it from the list to avoid duplicate column errors. |

## Breaking Changes
- **Primary Attribution Method Update**: The package now uses Klaviyo’s native `property_attribution` field (renamed `event_attribution` in staging) as the primary attribution method.
- Ensures consistency with Klaviyo’s platform reporting and UI
- Leverages Klaviyo’s internal attribution logic with no extra configuration required
- The previous session-based attribution remains available as an optional fallback by setting `using_native_attribution: false` in `dbt_project.yml`
- See the [README](https://github.com/fivetran/dbt_klaviyo/blob/main/README.md#event-attribution) for configuration details and the [DECISIONLOG](https://github.com/fivetran/dbt_klaviyo/blob/main/DECISIONLOG.md) for background on this decision

## Documentation Updates
- Added [DECISIONLOG.md](https://github.com/fivetran/dbt_klaviyo/blob/main/DECISIONLOG.md) explaining the rationale behind attribution methods and guidance on when to use each
- Updated [README.md](https://github.com/fivetran/dbt_klaviyo/blob/main/README.md#event-attribution) to clarify that `event_attribution` is now the primary attribution method
- Updated dbt documentation with newly added `property_attribution`/`event_attribution` field.

# dbt_klaviyo v1.1.0-a2
[PR #53](https://github.com/fivetran/dbt_klaviyo/pull/53) includes the following updates:

## Breaking Change
> A `--full-refresh` is required when upgrading to retroactively apply these updates.

- Updated attribution logic in `int_klaviyo__event_attribution` to use the `property_attribution` field from the `EVENT` source.
- This replaces the previous calculation method.
- If the `property_attribution` field is not available or you want a fallback for when it is null, set the variable `using_native_attribution: false` in your `dbt_project.yml` to coalesce the `last_touch_*` fields back with the previous package-calculated attribution method.
- Rolled back the updates from v1.1.0-a1.

# dbt_klaviyo v1.1.0-a1
[PR #53](https://github.com/fivetran/dbt_klaviyo/pull/53) includes the following updates:

## Breaking Change
> A `--full-refresh` is required when upgrading to ensure the updates are retroactively applied.
- Updated attribution logic for Shopify order lifecycle events. These events now inherit attribution from their associated `Placed Order` event rather than the nearest intervening event. If no `Placed Order` is found within 3 months, the default attribution behavior is applied.
- `Cancelled Order`
- `Confirmed Shipment`
- `Delivered Shipment`
- `Fulfilled Order`
- `Fulfilled Partial Order`
- `Marked Out for Delivery`
- `Refunded Order`

# dbt_klaviyo v1.0.0

[PR #51](https://github.com/fivetran/dbt_klaviyo/pull/51) includes the following updates:
Expand Down
71 changes: 71 additions & 0 deletions DECISIONLOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Decision Log

## Event Attribution Methods

This dbt Klaviyo package supports two attribution approaches: direct event attribution and a session-based fallback. This log explains the rationale, usage, and configuration for each method.

### Primary Attribution Method — Native attribution

If available, the package uses Klaviyo’s native `property_attribution` field (renamed to `event_attribution` during staging) from the EVENT source. This is the preferred method.

Why we prefer this option:
- **Accuracy**: Reflects Klaviyo’s platform logic
- **Consistency**: Matches reporting in the Klaviyo UI
- **Efficiency**: Faster than session-based calculations
- **Maintainability**: Avoids custom logic that could diverge from Klaviyo

#### Implementation
- Events with `property_attribution` are used directly
- If the `EVENT` table does not contain `property_attribution`, the following session-based attribution is used

### Session-Based Attribution Fallback

A session-based, package-calculated method can be enabled when `using_native_attribution: true` in `dbt_project.yml`, or if the package detects that `property_attribution` is unavailable.

Why we provide this option:
- **Backward Compatibility**: Preserve compatibility with earlier package versions
- **Data Gaps**: Fill in when `property_attribution` is missing
- **Custom Needs**: Support attribution use cases not covered by Klaviyo

Why we limit its use:
- **Performance Impact**: Requires window functions and complex logic
- **Potential Inconsistency**: Results may differ from Klaviyo’s native attribution
- **Not Needed**: Unnecessary when reliable `property_attribution` data exists

#### Implementation
When enabled, the session-based method:
- Groups events into "touch sessions" based on attributed campaign/flow events
- Applies configurable lookback windows (120 hours for email, 24 hours for SMS)
- Attributes only events within the lookback window to the session-starting event
- Filters attribution by `klaviyo__eligible_attribution_events` (defaults: email opens, clicks, SMS opens)

### Configuration Variables

| Variable | Default | Purpose |
|----------|---------|---------|
| `using_native_attribution` | `true` | Enable native or session based attribution |
| `klaviyo__email_attribution_lookback` | `120` | Lookback window (hours) for email attribution. Applies only when `using_native_attribution` is false. |
| `klaviyo__sms_attribution_lookback` | `24` | Lookback window (hours) for SMS attribution. Applies only when `using_native_attribution` is false. |
| `klaviyo__eligible_attribution_events` | `['email open', 'email click', 'sms open']` | Event types eligible for attribution. Applies only when `using_native_attribution` is false. |

### Recommendations

#### Use Direct Attribution (Default) When:
- Consistency with Klaviyo’s platform is required
- `property_attribution` data is present and reliable
- Performance and simplicity are priorities
- Starting a new implementation

#### Use Session-Based Fallback When:
- Migrating from an older package version
- Experiencing significant attribution data gaps
- Needing custom business-specific attribution logic
- Comparing attribution methods for validation

### Migration Notes
- **v1.0.0 → v1.1.0**: Preferred method changed from session-based to direct attribution
- **Enabling Fallback**: Set `using_native_attribution: true` in `dbt_project.yml` to restore prior behavior
- **Data Consistency**: Expect potential differences between methods; test thoroughly before production rollout

### References
- [Klaviyo Attribution Documentation](https://help.klaviyo.com/hc/en-us/articles/115005248128)
40 changes: 24 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ Include the following klaviyo package version in your `packages.yml` file:
```yaml
packages:
- package: fivetran/klaviyo
version: [">=1.0.0", "<1.1.0"]
version: [">=1.1.0", "<1.2.0"]
```

> All required sources and staging models are now bundled into this transformation package. Do not include `fivetran/klaviyo_source` in your `packages.yml` since this package has been deprecated.
Expand Down Expand Up @@ -91,35 +91,43 @@ vars:
klaviyo_union_databases: ['klaviyo_usa','klaviyo_canada'] # use this if the data is in different databases/projects but uses the same schema name
```

#### Attribution Lookback Window
#### Event Attribution

This package attributes events to campaigns and flows via a last-touch attribution model in line with Klaviyo's internal [attribution](https://help.klaviyo.com/hc/en-us/articles/115005248128). This is necessary to perform, as Klaviyo does not automatically send attribution data for certain metrics. Read more about how the package's attribution works [here](https://github.com/fivetran/dbt_klaviyo/blob/main/models/intermediate/int_klaviyo.yml#L4) and see the source code [here](https://github.com/fivetran/dbt_klaviyo/blob/main/models/intermediate/int_klaviyo__event_attribution.sql).
If available, the package uses Klaviyo’s native `property_attribution` field from the EVENT source for attributing events to campaigns and flows. This approach ensures consistency with Klaviyo's platform and provides the most accurate attribution data.

By default, the package will use a lookback window of **120 hours (5 days)** for email-events and a window of **24 hours** for SMS-events. For example, if an `'Ordered Product'` conversion is tracked on April 27th, and the customer clicked a campaign email on April 24th, their purchase order event will be attributed with the email they interacted with. If the campaign was sent and opened via SMS instead of email, the `'Ordered Product'` conversion would not be attributed to any campaign.
**Primary Attribution Method:**
- Uses Klaviyo's built-in `property_attribution` field when available
- Events inherit attribution from parent events via `attributed_event_id` references
- Aligns with Klaviyo's internal [attribution model](https://help.klaviyo.com/hc/en-us/articles/115005248128)
- No additional configuration required

To change either of these lookback windows, add the following configuration to your `dbt_project.yml` file:
**Session-Based Attribution Fallback:**
For users who need custom attribution logic or are migrating from older package versions, an optional session-based attribution method is available. This method is disabled by default if your EVENT source contains the `property_attribution` field but can be enabled by setting `using_native_attribution: false`. **If you do not have the `property_attribution` field, this method will be used by default.**

> If you would like to disable the package's attribution process completely, set these variables to `0`.
When enabled, this method uses configurable lookback windows:
- **120 hours (5 days)** for email events
- **24 hours** for SMS events

```yml
# dbt_project.yml

...
config-version: 2

vars:
klaviyo:
klaviyo__email_attribution_lookback: x_number_of_hours # default = 120 hours = 5 days. MUST BE INTEGER.
klaviyo__sms_attribution_lookback: y_number_of_hours # default = 24 hours. MUST BE INTEGER.
using_native_attribution: false # Disable native attribution to use session-based fallback
klaviyo__email_attribution_lookback: 120 # Hours for email attribution
klaviyo__sms_attribution_lookback: 24 # Hours for SMS attribution
```

> Note that events already associated with campaigns or flows in Klaviyo will never have their source attribution data overwritten by the package modeling.
> **Note:** For detailed information about attribution methods and when to use each approach, see the [DECISIONLOG.md](https://github.com/fivetran/dbt_klaviyo/blob/main/DECISIONLOG.md).

> Events already associated with campaigns or flows in Klaviyo will never have their source attribution data overwritten by the package modeling.

##### Attribution-Eligible Event Types (Session-Based Fallback Only)

#### Attribution-Eligible Event Types
> **Note:** This configuration only applies when session-based attribution is used. The primary attribution method uses Klaviyo's native attribution without additional filtering.

By default, this package will only credit email opens, email clicks, and SMS opens with conversions. That is, only flows and campaigns attached to these kinds of events will qualify for attribution in our package. This is aligned with Klaviyo's internal [attribution model](https://help.klaviyo.com/hc/en-us/articles/115005248128).
When using the session-based attribution fallback, the package will only credit email opens, email clicks, and SMS opens with conversions by default. This filter determines which event types can trigger new attribution sessions and is aligned with Klaviyo's internal [attribution model](https://help.klaviyo.com/hc/en-us/articles/115005248128).

However, this package allows for the customization of which events can qualify for attribution. To expand or otherwise change this filter on attribution, add the following configuration to your `dbt_project.yml` file:
To customize which events can qualify for attribution in the session-based method, add the following configuration to your `dbt_project.yml` file:

```yml
# dbt_project.yml
Expand Down
2 changes: 1 addition & 1 deletion dbt_project.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: 'klaviyo'
version: '1.0.0'
version: '1.1.0'
config-version: 2
require-dbt-version: [">=1.3.0", "<2.0.0"]

Expand Down
2 changes: 1 addition & 1 deletion docs/catalog.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/manifest.json

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion integration_tests/dbt_project.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: 'klaviyo_integration_tests'
version: '1.0.0'
version: '1.1.0'
config-version: 2
profile: 'integration_tests'

Expand Down Expand Up @@ -30,6 +30,9 @@ seeds:
PHONE_NUMBER: "{{ 'string' if target.type in ('bigquery', 'spark', 'databricks') else 'varchar' }}"
flow:
+quote_columns: "{{ true if target.type == 'redshift' else false }}"
event:
+column_types:
PROPERTY_ATTRIBUTION: "{{ 'string' if target.type in ('bigquery', 'spark', 'databricks') else 'varchar' }}"

flags:
send_anonymous_usage_stats: False
Expand Down
Loading