The SaaS funnel
SaaS teams often mix pipeline events and conversion events into one noisy stream. Pipeline events describe commercial momentum: a visitor requested a demo, a lead became sales qualified, a deal moved to proposal, or procurement started. Those signals are useful because they arrive earlier and in higher volume, but they do not yet mean cash is committed. Conversion events, by contrast, should describe monetization truth such as a trial becoming paid, a subscription starting, or a contract renewing.
The distinction matters because ad platforms optimize on what you feed them. If Meta or Google receives every internal stage change as if it were revenue, bidding shifts toward leads that look busy in the CRM rather than customers who actually pay and retain. A good event model keeps pipeline progression available for scoring and reporting, while reserving monetized subscription events for value-based optimization.
TrackLayer's approach is to bridge the two layers instead of collapsing them. Pipeline changes can enrich the customer profile with plan fit, segment, rep ownership, and opportunity context. Billing or product systems then emit the canonical lifecycle events that confirm economic reality. The result is cleaner attribution, more stable bidding, and a subscription funnel that still makes sense six months later during churn and renewal analysis.
Canonical subscription events
| Event name | Required fields | Platforms it maps to | Revenue impact |
|---|---|---|---|
| trial_started | customer_id, subscription_id, plan_id, trial_start_at, trial_end_at | Meta Lead or StartTrial, Google begin_checkout or qualified_lead, LinkedIn Lead, TikTok SubmitForm | Top-of-funnel signal with predictive value only |
| trial_converted | customer_id, subscription_id, converted_at, plan_id, mrr, currency | Meta Subscribe, Google purchase, LinkedIn Purchase, TikTok CompletePayment | Turns free evaluation into monetized demand |
| subscription_started | customer_id, subscription_id, started_at, billing_interval, mrr, contract_value | Meta Subscribe, Google purchase, LinkedIn Purchase, TikTok Subscribe | Creates first recurring revenue |
| subscription_renewed | customer_id, subscription_id, renewed_at, invoice_id, mrr, renewal_term | Meta Purchase, Google purchase, LinkedIn Other, TikTok CompletePayment | Extends recognized recurring revenue |
| subscription_upgraded | customer_id, subscription_id, upgraded_at, old_plan, new_plan, mrr_delta | Meta Purchase, Google purchase, LinkedIn Upsell custom conversion, TikTok CompletePayment | Positive expansion revenue |
| subscription_downgraded | customer_id, subscription_id, downgraded_at, old_plan, new_plan, mrr_delta | Meta custom event, Google custom conversion, LinkedIn Other, TikTok custom event | Negative expansion or contraction revenue |
| subscription_paused | customer_id, subscription_id, paused_at, resume_at, reason | Meta custom event, Google custom conversion, LinkedIn Other, TikTok custom event | Revenue deferred, churn risk elevated |
| subscription_reactivated | customer_id, subscription_id, reactivated_at, prior_status, mrr, reactivation_source | Meta Purchase or Subscribe, Google purchase, LinkedIn Purchase, TikTok Subscribe | Recovered recurring revenue |
| subscription_cancelled | customer_id, subscription_id, cancelled_at, effective_end_at, cancel_reason, lost_mrr | Meta custom cancellation event, Google offline adjustment, LinkedIn CRM signal, TikTok custom event | Stops future recurring revenue and informs churn models |
| payment_failed | customer_id, subscription_id, invoice_id, failed_at, amount_due, attempt_count | Meta custom dunning event, Google qualified_lead or custom, LinkedIn Other, TikTok custom event | Revenue at risk during dunning window |
Ad platform mapping
Exact event names differ by network, so the practical job is not strict one-to-one parity. The job is to map each lifecycle event into the closest optimization primitive while preserving the original canonical name in metadata. That lets reporting stay TrackLayer-native even when the ad network only supports a smaller set of standard conversion labels.
| Event | Meta CAPI | Google Ads | TikTok | |
|---|---|---|---|---|
| trial_started | StartTrial or Lead | begin_checkout or qualified_lead | Lead | SubmitForm |
| trial_converted | Subscribe | purchase | Purchase | CompletePayment |
| subscription_started | Subscribe | purchase | Purchase | Subscribe |
| subscription_renewed | Purchase | purchase | Other | CompletePayment |
| subscription_upgraded | Purchase | purchase | Purchase | CompletePayment |
| subscription_downgraded | Custom event | Custom conversion | Other | Custom event |
| subscription_paused | Custom event | Custom conversion | Other | Custom event |
| subscription_reactivated | Subscribe or Purchase | purchase | Purchase | Subscribe |
| subscription_cancelled | Custom cancellation adjustment | Conversion adjustment | CRM stage update | Custom event |
| payment_failed | Custom dunning signal | qualified_lead or custom | Other | Custom event |
Revenue-weighted conversion values
Count-based optimization is usually wrong for subscription businesses. A free trial from a micro account and an annual enterprise expansion should not train the model with equal force. The fix is to pass value with each lifecycle event and choose the field that matches the business objective. Self-serve SaaS often uses MRR. Sales-assisted SaaS may use contract_value on subscription_started and expected annual recurring revenue on trial_converted.
In practice, TrackLayer sends the canonical event plus financial context in `custom_data`, for example `value`, `currency`, `mrr`, `arr`, `contract_value`, `ltv_model`, and `mrr_delta`. Meta and TikTok mainly need the optimization value and currency. Google can use the primary conversion value for Smart Bidding while the extra fields remain available for offline analysis and warehouse joins. Keep the primary value stable per event type so models are not trained on inconsistent economics.
{
"event_name": "subscription_started",
"custom_data": {
"value": 249,
"currency": "USD",
"mrr": 249,
"contract_value": 2988,
"ltv_model": 6220
}
}Billing integrations
Billing systems are the safest place to derive subscription lifecycle truth because they see invoice success, payment failure, pause, resumption, upgrade, downgrade, and cancellation after the platform has committed the state change. That makes webhook ingestion more reliable than page-based tracking for any recurring revenue workflow.
Stripe webhook
TrackLayer watches Stripe subscription, invoice, and checkout lifecycle webhooks, then maps them into trial_started, subscription_started, subscription_renewed, payment_failed, subscription_upgraded, and subscription_cancelled without relying on a thank-you page. Stripe object IDs become stable dedup keys across retries.
Recharge webhook
Recharge is common in subscription commerce and hybrid SaaS plus membership offers. Recharge webhooks usually contribute renewal, pause, skip, cancellation, and reactivation states. TrackLayer normalizes those payloads so downstream platforms see the same event names they receive from Stripe.
Paddle webhook
Paddle combines merchant of record billing with subscription state changes. Events such as trialing, active, past_due, paused, and canceled can be translated into the canonical lifecycle schema while preserving tax-inclusive contract values for revenue reporting and ad bidding.
Cancellation + reactivation
Cancellation should not behave like a silent data point. If a customer churns shortly after a paid conversion, many teams send a balancing server-side cancellation signal so the media platform is not left believing the original purchase was fully valuable. A common pattern with Meta is to emit a cancellation event tied to the original subscription or order reference and attach a negative value in `custom_data.value` equal to the lost MRR or refunded amount. That makes internal attribution and modeled bidding less optimistic.
Reactivation needs more care. If the same account returns after a brief pause or dunning recovery, treat it as `subscription_reactivated` and preserve the original customer identity. If the return happens after a long churn gap and the commercial motion is effectively a new deal, you may map it to a new `subscription_started` event while still keeping the previous subscription record for retention analysis. The rule should be explicit in your data contract, not improvised inside the ad ops team.
Long-window attribution
Enterprise and sales-assisted SaaS rarely closes inside a seven-day click window. Trials may convert 30 days later, annual contracts may start 90 days later, and upsells can happen 180 days after the original campaign touch. That is why TrackLayer keeps identity and event timestamps durable enough for longer attribution windows and offline imports.
Meta generally optimizes best on the events it receives quickly, but it still benefits when later subscription starts, renewals, and qualified values are fed back for attribution learning. Google Ads is especially useful when offline conversion imports or enhanced conversions can connect long-lag revenue back to the original click. For enterprise SaaS, the important design choice is to keep the click identifiers, hashed user data, and CRM or billing keys alive long enough to join the eventual revenue event back to acquisition.
Pipeline → CRM bridge
The CRM should explain why revenue happened, not invent revenue that billing never confirmed. Stage changes from Salesforce or HubSpot can enrich subscription lifecycle events with owner, segment, forecast category, source campaign, and deal metadata. Once the deal is commercially real, those fields should travel alongside the canonical billing event into ad destinations and the warehouse.
| System | Stage change | Canonical event |
|---|---|---|
| Salesforce | Opportunity stage → Closed Won | subscription_started or trial_converted |
| Salesforce | Opportunity amount increase or amendment | subscription_upgraded |
| Salesforce | Renewal opportunity closed | subscription_renewed |
| HubSpot | Deal stage → Customer | subscription_started |
| HubSpot | Deal stage → Churned or Lost | subscription_cancelled |
| HubSpot | Lifecycle stage reopens from churn | subscription_reactivated |
Common questions
Should trial_started count as a conversion in ad platforms?
Usually yes, but with a lower value than paid starts. It is useful as an optimization signal for self-serve SaaS, especially when paid conversion volume is low. Keep it separate from subscription_started so reporting does not overstate revenue.
What value should I send for annual contracts?
Send the value that matches the optimization goal. If media is judged on booked revenue, use contract_value. If growth teams care about recurring efficiency, send normalized MRR as the primary value and store annual contract value in a secondary property.
Do renewals need to be sent to ad platforms?
Not always, but they matter for enterprise and longer sales cycles. Renewals help train systems toward customers who retain, not just customers who activate once and churn immediately.
How do I prevent double counting between CRM and billing data?
Use one source of commercial truth per event type. In most cases billing owns starts, renewals, failures, pauses, and cancellations, while the CRM owns pipeline stage changes and sales-assisted context. Carry the same customer and subscription identifiers across both systems.
What is the minimum identity payload for subscription events?
A durable external_id or customer_id, subscription_id, event timestamp, currency, and hashed user identifiers for ad destinations. Add email, company domain, and plan metadata when policy allows because match quality improves materially.
When should a reactivation be treated as a new acquisition?
Treat it as reactivation when the customer returns inside your defined churn recovery window and the original account relationship still exists. Treat it as a new acquisition only when the contract is genuinely new and the prior identity should not inherit the original attribution.
Related implementation guides
Identity resolution
Connect billing IDs, CRM contacts, and ad platform user data into one durable customer record.
Read guide →Meta CAPI setup
Implement server-side conversion delivery with strong match quality and clean deduplication.
Read guide →Stripe webhook bridge
Translate Stripe events into canonical tracking events without browser dependency.
Read guide →