Developer docs

Tag your ad campaigns for Campaign data

One URL parameter template on your ads is all datataste needs to join spend, clicks and impressions to the sessions, conversions and revenue it already measures — automatically, down to ad level.

v3.0Updated May 2026

How matching works

datataste matches imported ad-platform campaigns to your first-party website sessions using the UTM parameters both systems share. The join happens at up to three levels:

  • Campaign level — utm_campaign equals the campaign name. Spend, sessions and conversions line up per campaign; CPA and ROAS become available.
  • Ad-set level — utm_term carries the ad-set name. Sessions and conversions break down per ad set inside the campaign.
  • Ad level — utm_content carries the ad name. The deepest view: every creative shows the sessions and conversions it actually drove.

The Campaign matching table shows the level each campaign reached as a badge, and expanding a matched campaign reveals its ad sets and ads with a mapped/unmapped indicator per row.

The Meta template (recommended)

Meta fills the double-brace placeholders at delivery time, so one template works for every campaign, ad set and ad — no manual editing per ad. Add it once at ad level under Ad → Tracking → URL parameters, or set it as the default in your ad account settings:

URL parameters
utm_source={{site_source_name}}&utm_medium=paid_social&utm_campaign={{campaign.name}}&utm_term={{adset.name}}&utm_content={{ad.name}}

That's the whole setup. After the next sync (automatic every ~3 hours, or press Sync in Connections) your campaigns match at ad level.

Why placeholders beat hand-written values

Hand-written UTM values drift: someone renames a campaign, duplicates an ad set, or typos the value — and the join silently breaks. The {{...}} placeholders always emit the current name, so renames propagate on the next sync.

What each parameter does

ParameterValueWhat it does
utm_source{{site_source_name}}Identifies the placement the ad ran on (fb / ig / an / msg). Required join key.
utm_mediumpaid_socialThe channel. Required join key — keep it stable (paid_social).
utm_campaign{{campaign.name}}The primary join key: matches the imported campaign by name.
utm_term{{adset.name}}Enables ad-set level matching (name of the ad set).
utm_content{{ad.name}}Enables ad level matching (name of the ad).

Extra parameters (your own tracking IDs, placement macros, click IDs) are fine — datataste reads the five utm_* keys and ignores the rest.

Google Ads

Google's ValueTrack macros expose IDs, not names, so name-based placeholders like Meta's are not available. Set the UTM values statically in the campaign's tracking template and keep utm_campaign identical to the campaign name:

URL parameters
utm_source=google&utm_medium=cpc&utm_campaign=YOUR_CAMPAIGN_NAME

Auto-tagging (gclid) can stay enabled alongside manual UTMs — datataste matches on the UTMs and treats gclid-only traffic as partial. Ad-set and ad level matching for Google is on the roadmap.

No UTMs? Naming conventions

If your links carry no UTM parameters at all, datataste can parse structured campaign names instead — e.g. meta_paid-social_summer-sale becomes source, medium and campaign. Configure the separator and token order under Field mapping in the Campaign data section; a live preview shows how your imported campaign names parse.

Naming conventions match at campaign level only. For ad-set and ad level joins, use the URL template above.

Troubleshooting

Renamed the campaign? Sessions tagged before the rename carry the old name. The matching table flags renamed campaigns; the placeholder template picks up the new name on the next sync.

  • Ad set level shows fewer sessions than its ads? Meta truncates very long URL parameter blocks on some placements, cutting parameters near the end of the template (often utm_term). datataste compensates by matching truncated values as unambiguous name prefixes — but keep campaign and ad-set names reasonably short and avoid duplicated parameters so the template stays under the limit.
  • Case or separator mismatches? Summer-Sale does not equal summer_sale by default. Enable case-insensitive and ignore-separators matching under Field mapping — no renaming needed.
  • Spend imported but no sessions? Check that the ads actually link to a page with the datataste tracker, and that the template sits at ad level (not only on some ads). The Campaign matching row explains exactly which fields matched and which are missing.
  • Just connected? Imports run on connect and then every ~3 hours. Sessions only match from the moment your ads carry the template — historical traffic without UTMs cannot be joined retroactively.