> ## Documentation Index
> Fetch the complete documentation index at: https://orwel-22af1265.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Attribution

> First and last touch UTMs and ad click ids, captured by the SDK and joined with your ad spend.

Every lead in Orwel says where it came from. The SDK captures the campaign parameters of the landing URL, keeps them across sessions, and sends them with each conversion. The server uses them for the lead source and to join leads with the spend of your [Google Ads](/integrations/google-ads) and [Meta Ads](/integrations/meta-ads) campaigns.

## What the SDK captures

| Group | Parameters |
| - | - |
| UTMs | `utm_source`, `utm_medium`, `utm_campaign`, `utm_term`, `utm_content`, `utm_id` |
| Ad click ids (SDK 1.7.0+) | `gclid`, `gbraid`, `wbraid` (Google), `fbclid` (Meta), `ttclid` (TikTok), `msclkid` (Microsoft), `li_fat_id` (LinkedIn) |

They are read from the URL query string, then from a query inside the hash (`/#/?utm_source=...`, for hash routers), then from the referrer. Within a session they are kept in `sessionStorage`, so they survive client side navigation and redirects.

## First and last touch

Across sessions the SDK keeps an `attribution` object in `localStorage`:

```json theme={null}
{
  "first_touch": { "utm_source": "google", "utm_medium": "cpc", "utm_campaign": "brand" },
  "last_touch": { "utm_source": "meta", "utm_medium": "paid", "utm_id": "120210000000" },
  "first_click_ids": { "gclid": "Cj0KCQ..." },
  "last_click_ids": { "fbclid": "IwAR..." }
}
```

* `first_touch` and `first_click_ids` are written once: the campaign that first brought the visitor.
* `last_touch` and `last_click_ids` are overwritten on every new tagged visit.

Every `conversion()` carries this object. You don't need to read the URL or pass UTMs yourself.

## How the server uses it

* **Lead source:** an explicit `source` property on the conversion wins. Otherwise the last touch `utm_source`, then the first touch, then the UTMs of the session.
* **Google Ads:** the last touch `gclid` (or `gbraid` / `wbraid`) is stored on the lead and matched with the clicks of your synced Google Ads campaigns, so each lead is tied to the campaign that paid for it.
* **Meta Ads:** Meta has no click level report, so `fbclid` proves that a visit came from a Meta ad but cannot be joined with spend. The join uses `utm_id` (the Meta campaign id), with the campaign name in `utm_campaign` as a fallback.
* **Older SDKs:** if a conversion has no `attribution` object (SDK before 1.6) the server recovers UTMs and click ids from the landing URL of the session.

With attribution and cost synced, the Campaigns screen shows cost per lead, cost per qualified lead and spend that produced no qualified leads.

## Tag your ads

Ad platforms add their click id automatically (`gclid` with auto tagging in Google Ads, `fbclid` on Meta). Add UTMs as well, and always `utm_id`: unlike `utm_campaign` it survives a campaign rename.

<CodeGroup>
  ```text Google Ads (tracking template or final URL suffix) theme={null}
  utm_source=google&utm_medium=cpc&utm_campaign={campaignid}&utm_id={campaignid}
  ```

  ```text Meta Ads (URL parameters) theme={null}
  utm_source=meta&utm_medium=paid&utm_campaign={{campaign.name}}&utm_id={{campaign.id}}
  ```

  ```text LinkedIn, newsletters, partners theme={null}
  utm_source=linkedin&utm_medium=paid&utm_campaign=q4_launch
  ```
</CodeGroup>

## Check it

Open your site with `?utm_source=test&utm_campaign=check` using the [development key](/guides/dev-mode), submit a conversion, and open the request in Dev mode: the payload has the `attribution` object, and there is no `missing_attribution` warning. A conversion without UTMs or click ids gets that warning and the lead counts as direct.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.