What marketing attribution should tell you
Ad platforms report clicks and their own idea of conversions. What you actually want to know is simpler: which campaign brought the people who became real leads, and what each of those leads cost. That needs three things joined together:
- Where each visitor came from, kept until they convert.
- Which conversions turned into leads worth a follow up.
- What each campaign spent.
Orwel joins all three. The SDK records the source, the lead score says which leads are qualified, and the Google Ads and Meta Ads integrations bring in the spend.
What the SDK captures
When a visitor lands, the SDK reads campaign parameters from the URL. You do not have to parse the query string or pass UTMs yourself.
| Group | Parameters |
|---|---|
| UTMs | utm_source, utm_medium, utm_campaign, utm_term, utm_content, utm_id |
| Ad click IDs (SDK 1.7.0 and newer) | gclid, gbraid, wbraid (Google), fbclid (Meta), ttclid (TikTok), msclkid (Microsoft), li_fat_id (LinkedIn) |
It looks in the query string first, then in a query inside the hash (for hash routers like /#/?utm_source=...), then in the referrer. Within a session the values live in session storage, so they survive client side navigation and redirects.
First touch and last touch attribution
Across sessions, the SDK keeps an attribution object in local storage:
- First touch and the first click IDs are written once. They record the campaign that first brought the visitor.
- Last touch and the last click IDs are overwritten on every new tagged visit.
Every orwel.conversion() call carries both. So if someone clicks a Google search ad on Monday, comes back from a Meta retargeting ad on Wednesday and signs up from a bookmark on Friday, the lead keeps both campaigns instead of being filed under "direct".
const { success } = await orwel.conversion('demo_request', { email: form.email });
// first and last touch UTMs and click IDs are attached automatically
For the lead source, Orwel uses an explicit source property on the conversion if you send one. Otherwise it uses the last touch utm_source, then the first touch, then the UTMs of the session. The guide to UTM tracking and marketing attribution covers the trade offs between first and last touch in more depth.
Google Ads attribution
Connect Google Ads from Integrations by signing in with a Google account that can see your ad account. Orwel syncs campaigns, daily impressions, clicks, cost and conversions, keywords and search terms, and the gclid of each click. The sync runs every 3 hours, and a Sync button runs it on demand.
To tie leads to campaigns:
- Keep auto tagging on in Google Ads, so a
gclid(orgbraidandwbraidon iOS) is added to the landing URL. - Use SDK 1.7.0 or newer, which sends the click ID with the conversion.
- The sync maps each click ID to its campaign and links the lead. A lead that arrives before its click is synced gets linked on the next sync.
Add utm_id={campaignid} to your tracking template as well, so leads stay attributed when a click ID is missing.
Meta attribution
Connect Meta Ads with the Facebook account that manages your ads and pick the ad account. Orwel syncs Facebook and Instagram campaigns with daily impressions, clicks, spend and conversions, on the same 3 hour schedule.
Meta has no click level report, so fbclid proves a visit came from a Meta ad but cannot be joined with spend. The join uses the campaign ID instead. Set the ad's URL parameters to:
utm_source=meta&utm_medium=paid&utm_campaign={{campaign.name}}&utm_id={{campaign.id}}
Orwel matches utm_id with the Meta campaign ID. If it is missing, it falls back to a campaign whose name matches utm_campaign exactly. utm_id keeps working after you rename a campaign, utm_campaign does not. The UTM builder has presets for both platforms.
Orwel only reads from Google Ads and Meta Ads. It never creates, edits or pauses campaigns.
Cost per lead and cost per qualified lead
With attribution and spend in place, the Campaigns screen shows for each campaign:
| Metric | How it is computed |
|---|---|
| Cost per lead | Campaign spend divided by the leads it produced |
| Cost per qualified lead | Campaign spend divided by leads that score 60 or more |
| Wasted spend | Campaigns that spent money and produced no qualified leads |
Cost per lead alone rewards cheap campaigns that bring junk. Cost per qualified lead uses Orwel's 0 to 100 lead score, which is built from conversions, engagement, recency and visit consistency. A campaign with a higher cost per lead can still be the better buy if its leads qualify. For Google Ads, a keyword and search term breakdown below highlights terms that spend without converting, which are candidates for negative keywords.
To sanity check the numbers by hand, the CAC calculator works out cost per lead and customer acquisition cost from your own spend.
Check your setup
Open your site with ?utm_source=test&utm_campaign=check using the development key, submit a conversion, and open the request in Dev mode. The payload should contain the attribution object with no missing_attribution warning. A conversion without UTMs or click IDs gets that warning and the lead counts as direct.
What Orwel attribution does not do
- No multi-touch weighting models. Orwel keeps first touch and last touch, not a weighted path of every touch.
- No spend sync for TikTok, Microsoft or LinkedIn. Their click IDs and UTMs are captured, but cost comes from Google Ads and Meta Ads only.
- No changes to your campaigns. Access is read only.