Subscriptions and ads
How MRR and churn are counted, and how ad spend joins to visits on utm_campaign.
Subscriptions
When Stripe, Lemon Squeezy or Polar is connected, subscription events build a subscriptions store next to your payments. For Stripe, add customer.subscription.created, customer.subscription.updated and customer.subscription.deleted to the webhook you already have. Lemon Squeezy sends subscription_created, subscription_updated and subscription_cancelled; Polar sends subscription.created, subscription.updated and subscription.canceled. Only events from the day you connect onward are counted.
| MRR | Each active subscription's price as a monthly amount: yearly plans count a twelfth, weekly plans 52 / 12. Trials and cancelled subscriptions count zero. |
| New | MRR from a customer's first paid subscription. |
| Expansion / contraction | A paying subscription changing price or quantity, up or down. |
| Churned | MRR lost when a paid subscription ends. A cancel at period end counts when the period ends, not when the button is pressed. |
| Reactivation | A customer who had churned starting to pay again. |
| Logo churn | Subscribers lost in a month over subscribers at the start of it. |
| Revenue churn | MRR lost to churn and contraction in a month over MRR at the start of it. |
| Trial to paid | Of trials that ended, the share that became paid. |
The channel table and retention grid group subscribers by the visit that first brought them, the same first touch as revenue attribution.
How ad spend joins to visits
Ad platforms report spend per campaign. Pathrail joins that spend to your visits on utm_campaign: a campaign whose ads send people to ?utm_campaign=spring_launch is credited with every visitor whose visit carried spring_launch. The match ignores case, so Spring_Launch and spring_launch are the same campaign. Everything else must match exactly.
For Meta, the tag comes from each ad's URL parameters (the url_tags field, set under Tracking in Ads Manager). The first ad in a campaign that sets utm_campaign decides the campaign's tag. These macros are filled in before matching:
| {{campaign.name}} | The campaign's name, exactly as Meta has it. |
| {{campaign.id}} | The campaign's numeric id. |
A tag built from other macros, like ad set or ad names, can't be filled in per campaign, so that campaign is treated as untagged.
Unmatched spend
Spend is unmatched when its campaign has no tag, or when no visit in the last year carried its tag. The Ads page shows how much and which campaigns, marked "no matching visits". The usual causes are a missing utm_campaign on the ad's link, a typo between the ad and the link, or a redirect that drops the query string before the page loads. Fix the tag on the ad and new visits match from then on.
When two campaigns share one tag, its visitors and revenue are split between them by clicks, and both rows are marked.
First touch and last touch
| First touch | The default. A payment counts for the campaign of the visit that first brought the customer, so a campaign gets credit for customers it found even if they came back another way. |
| Last touch | A payment counts for the last campaign-tagged visit by the paying visitor before they paid. Use it to see what closes, not what finds. |
Visitors and signups are the same under both: everyone whose visit in the period carried the tag. ROAS is attributed revenue over spend. Spend stays in the ad account's currency and revenue in the site's, and when they differ the page says so rather than converting.
Connecting Meta Ads
In Settings, under Meta Ads, either sign in with Facebook (when the server has a Meta app configured) or paste a system user token with the ads_read permission and the ad account id. The last four weeks are pulled right away, then the last week again once a day, so late changes from Meta are picked up. Disconnecting keeps the spend already pulled.