> ## Documentation Index
> Fetch the complete documentation index at: https://docs.formo.so/llms.txt
> Use this file to discover all available pages before exploring further.

# How to Set Up Onchain Attribution

> Connect referrers, referral codes, ads, UTM campaigns, and builder codes to wallet connects, transactions, volume, and revenue.

This guide covers every attribution source Formo supports, how the SDK captures each one, and how to connect acquisition touchpoints to onchain conversions. Use it to compare referrers, referral codes, ad networks, UTM campaigns, and builder codes across wallet connects, transactions, volume, and revenue.

## What you'll learn

* Understand what Formo and its SDK capture automatically
* Track referrers, referral codes, ads, UTM campaigns, and builder codes
* Understand first-touch vs. last-touch attribution
* Measure performance by source through wallet connects and transactions
* Optimize budget allocation based on conversion data

## Part 1: The Attribution Challenge in Crypto

### Why traditional attribution fails

Traditional analytics measure clicks and visits. For crypto apps, this misses what matters:

| What traditional tools measure | What actually matters |
| - | - |
| Page views | Wallet connects |
| Time on site | Transactions completed |
| Form submissions | Volume/revenue generated |
| Bounce rate | User quality (net worth, labels) |

### The crypto user journey

A typical onchain user touches multiple channels:

1. **Discovery**: Sees your tweet, ad, or mention
2. **Research**: Reads about you on Discord, docs, or DeFiLlama
3. **First visit**: Lands on your site (often without converting)
4. **Return visit**: Comes back from a different source
5. **Conversion**: Connects wallet and transacts

Each touchpoint matters. The question is: which one gets credit?

## Part 2: How Formo Captures Attribution Sources

The Formo SDK captures attribution context from landing URLs, browser referrers, and onchain transaction data. You do not need UTMs for every attribution method:

| Source | What Formo captures | Setup |
| - | - | - |
| **Referrers** | Previous site and referring URL when the browser provides them | Automatic; configure `Referrer-Policy` for full URLs |
| **Referral codes** | `ref` and supported referral parameters | Add the referral code to links you control |
| **Ads** | Click IDs such as `gclid`, `fbclid`, and `twclid` | Keep ad-platform auto-tagging enabled |
| **UTM** | Source, medium, campaign, content, and term | Add UTMs to links you control |
| **Builder codes** | ERC-8021 attribution embedded in EVM transaction calldata | Add a builder code when constructing transactions |
| **Mobile links and installs** | UTM and referral data from deep links; Android Play Install Referrer data | Enabled by default; Android install attribution requires its native module |

Each source remains independently useful. For example, one visit can carry a browser referrer, a referral code, UTM campaign details, and an ad click ID at the same time.

### Mobile deep links and install referrers

The React Native SDK parses UTM parameters and referral codes from deep and universal links. On Android, the optional Google Play Install Referrer integration connects the website or campaign that led to an install with the first app launch. Apple does not expose an equivalent install-referrer API, so iOS supports deep-link attribution but not SDK-only install attribution. See [Deep link attribution](/sdks/mobile#deep-link-attribution) and [Web-to-mobile attribution](/sdks/mobile#web-to-mobile-attribution).

## Part 3: How to Set Up UTM Tracking

### UTM parameter basics

UTM parameters let you track where users come from:

```
https://yourapp.xyz/?utm_source=twitter&utm_medium=social&utm_campaign=launch_2024
```

| Parameter | Purpose | Examples |
| - | - | - |
| `utm_source` | The platform | twitter, discord, newsletter, defillama |
| `utm_medium` | The channel type | social, email, paid, referral |
| `utm_campaign` | The campaign name | launch\_2024, airdrop\_promo, partnership\_xyz |
| `utm_content` | The creative variant | banner\_a, thread\_1, video\_ad |
| `utm_term` | Keywords (for paid) | defi, swap, yield |

### Where to add UTMs

Add UTM parameters to every link you control:

**Social media:**

```
https://yourapp.xyz/?utm_source=twitter&utm_medium=social&utm_campaign=daily_content
```

**Email campaigns:**

```
https://yourapp.xyz/?utm_source=newsletter&utm_medium=email&utm_campaign=weekly_update
```

**Partner/referral links:**

```
https://yourapp.xyz/?utm_source=partner_name&utm_medium=referral&utm_campaign=collab_jan
```

**Paid ads:**

```
https://yourapp.xyz/?utm_source=twitter_ads&utm_medium=paid&utm_campaign=retargeting&utm_content=banner_v2
```

> You can use this free [UTM link generator](https://formo.so/utm-generator) to generate UTM links.

### UTM naming conventions

Use consistent naming to make analysis easier:

| Bad | Good |
| - | - |
| `twitter`, `Twitter`, `tw` | Always `twitter` |
| `paid ad`, `paid_ad`, `paidAd` | Always `paid` |
| `Launch`, `launch2027`, `jan-launch` | `launch_2024_jan` |

**Recommended format:**

* Lowercase only
* Underscores for spaces
* Include date/month for campaigns: `campaign_name_mmyy`

## Part 4: How to Set Up Referral Tracking

Formo automatically captures referral codes alongside UTM parameters.

### Referral code basics

Add a `ref` parameter to your referral links:

```
https://yourapp.xyz/?ref=alice
```

When a user lands with a `ref` parameter, Formo captures it and associates it with the user's session. You can then trace connect sessions, events, and users back to specific referral codes.

The Web SDK also recognizes `referral`, `refcode`, `af`, and `referrer` by default. If your program uses another convention, configure custom query parameter names or a URL path pattern; see [Web SDK referrals](/sdks/web#referrals).

### Where to add referral codes

**User-generated referral links:**

```
https://yourapp.xyz/?ref=0x1234...abcd
```

**Partner referral links:**

```
https://yourapp.xyz/?ref=partner_name
```

**Influencer referral links (combine with UTMs for full attribution):**

```
https://yourapp.xyz/?ref=influencer_handle&utm_source=twitter&utm_medium=social&utm_campaign=influencer_jan
```

### Referral naming conventions

| Bad | Good |
| - | - |
| Mixed case (`Alice`, `alice`, `ALICE`) | Always lowercase (`alice`) |
| Spaces or special characters (`my ref`) | Underscores only (`my_ref`) |
| Generic names (`partner1`) | Descriptive names (`uniswap_collab`) |

### Analyze referral performance

The Overview page has a dedicated referral chart, and the Users page and Wallet Profiles show you which referral code acquired each user.

Use **Ask AI** or the **Explorer** to query referral data:

> "Show me wallet connects and transactions grouped by ref parameter for the last 30 days"

```sql theme={null}
SELECT
  JSONExtractString(properties, 'ref') AS referrer,
  countDistinct(address) AS wallets,
  count(*) AS transactions
FROM events
WHERE JSONExtractString(properties, 'ref') != ''
  AND timestamp >= now() - INTERVAL 30 DAY
GROUP BY referrer
ORDER BY wallets DESC
```

## Part 5: Referrer Attribution

Formo automatically records the referring site when the browser sends it. Referrers are useful for links you do not control—such as editorial coverage, search results, community posts, or directory listings—where no UTM or referral code was added.

By default, browsers may send only the referring origin. To capture the specific referring page URL, configure your site's `Referrer-Policy` header. See [Referrer URL tracking](/sdks/web#referrer-url-tracking) for the recommended setup and privacy tradeoffs.

Same-domain referrers are removed before channel classification so internal navigation does not appear as a new acquisition source. See [Referrers](/data/metrics#referrers) for counting details.

## Part 6: Ad Attribution

Ad platforms append click IDs to landing URLs. The Formo SDK captures supported IDs automatically and attributes the session and user to the acquiring network—even when an in-app browser does not provide a referrer.

Keep auto-tagging enabled in your ad platforms. Add UTMs when you also want campaign, creative, or keyword detail; the click ID identifies the network while UTMs provide your naming taxonomy.

Formo supports Google, Meta, Microsoft, TikTok, X, LinkedIn, and Reddit click IDs, plus paid `utm_medium` values without a known click ID. See [Ad attribution](/features/attribution/ads) for the complete parameter list, attribution behavior, and dashboard surfaces.

## Part 7: Builder Code Attribution

[Builder codes](/data/events/transaction#builder-codes) attribute EVM transactions directly to the app that built them by appending an ERC-8021 code to transaction calldata. Unlike referrers, referral codes, ads, and UTMs, builder codes describe transaction-level onchain provenance rather than the user's landing source.

Use builder codes when your app constructs transactions and you want durable attribution that survives wallets, RPC providers, and aggregators. Formo detects supported codes from transaction data and makes them available as breakdowns for wallets, transactions, volume, and revenue.

## Part 8: Understand Attribution Models

Formo supports multiple attribution models. Each gives credit differently.

### First-touch attribution

**How it works:** 100% credit to the first channel that introduced the user.

**Best for:** Understanding discovery channels.

**Example:**

1. User finds you via Twitter (first touch)
2. Returns via Discord link
3. Converts via direct visit

→ Twitter gets 100% credit

### Last-touch attribution

**How it works:** 100% credit to the last channel before conversion.

**Best for:** Understanding what drives final conversions.

**Example:**

1. User finds you via Twitter
2. Returns via Discord link
3. Converts via direct visit (last touch)

→ Direct gets 100% credit

### Which model to use?

| Goal | Model | Why |
| - | - | - |
| Grow awareness | First-touch | Shows which channels introduce new users |
| Optimize conversions | Last-touch | Shows what pushes users to convert |

## Part 9: How to Analyze Attribution in Formo

### View attribution in Overview

<Steps>
  <Step title="Go to Overview in the Formo Dashboard" />

  <Step title="Find the Channels, Referrers, Referrals, Ads, and UTM tabs">
    These sit alongside your other traffic breakdowns (Pages, Countries, Devices).
  </Step>

  <Step title="Select different units (users, volume, revenue)" />
</Steps>

<Tip>You can apply filters on the overview page to see attribution by different segments.</Tip>

Each tab answers a different attribution question:

| View | Shows |
| - | - |
| **Channels** | Traffic auto-classified into one of 13 acquisition channels (Paid Search, Organic Social, Direct, etc.) |
| **Referrers** | The specific referring domain (twitter.com, google.com, defillama.com) |
| **Referrals** | Traffic from `ref` codes, plus `affiliate`/`referral` UTM traffic |
| **Ads** | Paid sessions and visitors grouped by the acquiring ad network |
| **UTM** | Breakdown by `utm_source`, `utm_medium`, `utm_campaign`, `utm_content`, and `utm_term` |
| **Builder codes** | Wallets, transactions, volume, and revenue attributed through ERC-8021 transaction calldata |

Formo automatically classifies every session into a channel at ingestion time, using a priority-ordered ladder over the referrer domain, `utm_medium`, and ad-platform click IDs. See the full [channel classification table](/features/attribution/key-metrics#channels) for how each of the 13 channels is detected.

### Key metrics by source

For each acquisition source, the Channels, Referrers, Referrals, Ads, and UTM tabs show raw counts. Builder codes are available as a breakdown for onchain metrics:

| Metric | What it tells you |
| - | - |
| **Visitors** | Reach/awareness |
| **Wallet connects** | Engagement quality |
| **Transactions** | Conversion performance |
| **Volume** | Revenue contribution |

These tabs show one metric at a time, not a percentage. To see an actual connect rate (visitor → wallet) or transaction rate (wallet → transaction) by source, build a [funnel](/features/product-analytics/funnels) with a breakdown dimension, covered below.

### Create custom attribution charts

Beyond the built-in tabs, build custom charts to track attribution over time. Use **Ask AI** for quick answers, or the SQL editor for full control. See [Charts](/features/product-analytics/charts) for the full guide to creating, organizing, and sharing charts.

**Ask AI examples:**

> "Compare wallet connects by utm\_source for the last 30 days"

> "Show me transactions and volume by utm\_campaign this month"

> "What are the top 5 first-touch sources for users who transacted?"

> "Compare transactions by ad network and referral code"

> "Which referrer or builder code generated the most transaction volume?"

**Attribution chart ideas:**

| Chart | Query |
| - | - |
| **Visitors by Source** | Daily visitors grouped by referrer or UTM source |
| **Conversion by Source** | Transaction rate by first-touch channel, referral, or ad network |
| **Revenue by Campaign** | Revenue grouped by UTM campaign |
| **Onchain Attribution** | Transaction volume grouped by builder code |

**Attribution funnel:**

<Steps>
  <Step title="Go to Dashboards, click Add Chart, and select the Funnel chart type" />

  <Step title="Add steps: Visit → Connect → Transaction" />

  <Step title="Add a breakdown dimension: Referrer, Referral, Ads, UTM Source/Medium/Campaign/Content/Term, Builder Codes, Device, Country, Browser, or OS" />

  <Step title="Compare conversion rates across each value" />
</Steps>

### Calculate true ROI

For paid campaigns, calculate cost per conversion:

```
Cost per Transaction = Campaign Spend / Transactions from Campaign
```

**Example:**

| Channel | Spend | Transactions | Cost/Transaction |
| - | - | - | - |
| Influencer | \$5,000 | 100 | \$50 |
| Discord Ads | \$2,000 | 80 | \$25 |
| Twitter Ads | \$3,000 | 150 | \$20 |

In this example, Twitter Ads has the best ROI.

## Part 10: How to Optimize Your Marketing

### Identify your best channels

From your attribution data, categorize channels:

**High-volume, high-conversion:**

* Scale these immediately
* Allocate more budget
* Test similar channels

**High-volume, low-conversion:**

* Improve landing pages
* Refine targeting
* Test different messaging

**Low-volume, high-conversion:**

* Increase investment
* Find ways to scale
* Understand what makes them work

**Low-volume, low-conversion:**

* Reduce or cut spend
* Test improvements before continuing
* Consider audience mismatch

### Optimize by user quality

Don't just measure conversions. Measure user quality:

* Filter users by referrer, referral code, ad network, or UTM source
* Compare average net worth by source
* Compare retention by source
* Compare volume per user by source

**Example insight:**

> Twitter drives more users, but Discord users have 3x higher average net worth and 2x better retention.

### Assisted journey analysis

* Identify common multi-touch paths
* Ensure each touchpoint is optimized
* Don't cut discovery channels just because another source received last-touch credit

**Example path:**
Twitter (awareness) → DeFiLlama (research) → Direct (conversion)

All three channels contributed. Cutting Twitter would reduce DeFiLlama traffic.

## Part 11: Advanced Attribution Tactics

### Cross-channel attribution

Track users across marketing channels:

* Use consistent UTM naming
* Track first-touch and last-touch separately
* Compare referral, referrer, ad, and UTM properties together
* Analyze common paths with Flows

### Cohort-based attribution

Compare user quality by acquisition cohort:

* Create segments by first-touch source
* Measure retention for each segment
* Calculate LTV by acquisition source

**Example:**

| Source | 30-day Retention | Avg LTV |
| - | - | - |
| Twitter | 15% | \$50 |
| Discord | 25% | \$120 |
| DeFiLlama | 35% | \$200 |

## Attribution checklist

* [ ] UTM parameters on all social links
* [ ] UTM parameters on all email links
* [ ] UTM parameters on all partner links
* [ ] UTM parameters on all paid ads
* [ ] Referral codes on all partner and influencer links
* [ ] Ad-platform auto-tagging enabled
* [ ] `Referrer-Policy` configured if full referring URLs are needed
* [ ] Builder codes added to app-built EVM transactions
* [ ] Deep-link capture reviewed for mobile apps
* [ ] Google Play Install Referrer module installed if Android install attribution is needed
* [ ] Consistent naming conventions
* [ ] Attribution dashboard created
* [ ] Weekly review of channel performance

## Summary

You've learned how to:

1. **Use automatic attribution capture** from the web and mobile SDKs and Formo's onchain data
2. **Set up controlled links** with referral codes and UTM parameters
3. **Measure referrers and ad networks** without relying on UTMs alone
4. **Attribute onchain activity** with builder codes
5. **Compare first-touch and last-touch models** across users and sessions
6. **Analyze and optimize sources** through conversions, volume, revenue, and user quality

## FAQ

<AccordionGroup>
  <Accordion title="Does Formo capture attribution parameters automatically?">
    Yes. When a user lands on your app, Formo automatically captures UTM parameters, browser referrers, supported referral parameters, and ad click IDs, then associates them with the session and user. Formo also detects supported builder codes from EVM transaction calldata.
  </Accordion>

  <Accordion title="What happens if a user visits from multiple sources before converting?">
    Formo records both first-touch and last-touch attribution. You can view either model on the Users page to understand the full user journey.
  </Accordion>

  <Accordion title="Can I use both UTM parameters and ref codes on the same link?">
    Yes. Combine them for full attribution: `?ref=alice&utm_source=twitter&utm_medium=social`. Both are captured independently.
  </Accordion>
</AccordionGroup>


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