Connect Superwall
Connecting Superwall brings your app's in-app subscription revenue into the same place as your web traffic: the revenue metrics, the conversions list, and the link between a purchase and the visit that drove it. You connect Superwall per site, so each site reports its own revenue.
Superwall has no bulk purchase history Snow imports - revenue arrives by webhook. Snow therefore reports revenue from the moment you connect, not before it.
Create an organisation API key
In the Superwall dashboard, open Settings → API Keys and create an
organisation API key. It starts with sk_, and Superwall shows it once.
Give it these five scopes and leave the rest off:
| Scope | Why Snow needs it |
|---|---|
projects:read | To confirm which project the key belongs to. |
webhooks:read | To see whether the key may create an endpoint before trying. |
webhooks:write | To register Snow's own webhook - the only way revenue reaches Snow. |
products:read | To read each product's billing period, which is what turns a price into MRR. |
customers:read | To read a subscription's real start date, which a renewal webhook does not carry. |
Restrict the key to one project
A Superwall API key defaults to All projects. Set Project access to Restricted and pick the single project whose revenue you want in Snow.
This step is what makes connecting a single-field form. A key that can see more than one project leaves Snow with no way to tell which one to sync, so it is rejected rather than guessed at.
Paste it into your site's integration settings
Back in Snow, go to Settings → Integrations → Mobile Apps → Superwall and paste the key. Snow encrypts the key at rest before storing it, so the raw key is never kept in plain text.
Snow then creates one webhook endpoint in that project, named after your site. Purchases, renewals, cancellations and refunds arrive from that point on. See how revenue stays up to date.
Snow reads one payment provider at a time
A site can hold connections to several payment providers, but two providers' revenue is not one number, so the most recently connected one wins and the rest stay hidden. Connecting Superwall therefore hides an existing Stripe, Polar, Dodo or RevenueCat connection's revenue.
Nothing is lost: the other connection stays where it is, keeps syncing, and the integration row offers a Make primary button that switches the dashboard back to it.
Revenue is gross, not what the stores remit
Superwall sends two prices on every event: price, what the customer paid, and
proceeds, what is left after the store's commission. Snow records the price,
in the currency the customer actually paid in.
That is the same thing Snow records for Stripe, Polar and Dodo, which is what makes the Revenue tab comparable across providers - but it means your Superwall revenue reads higher than your bank. Apple takes 30% (15% on the Small Business Program), Google 11.8–15%, Stripe rather less.
Tie an app purchase back to a visit
A mobile purchase has no checkout page to carry metadata, so Superwall's
equivalent is a user attribute. Set the two ids the Snow tracking snippet
writes on your website - they live in the _sa_vid and _sa_sid cookies - on the
user before they buy:
Superwall.shared.setUserAttributes([
"sa_visitor_id": visitorId,
"sa_session_id": sessionId,
])Superwall.instance.setUserAttributes(
mapOf(
"sa_visitor_id" to visitorId,
"sa_session_id" to sessionId,
)
)Superwall includes those attributes on every webhook, which is where Snow reads
them. This is the same sa_visitor_id / sa_session_id convention Snow uses for
Stripe, Polar, Dodo and RevenueCat.
How you get the ids into the app is up to you - the usual routes are a deep link from the web page the user signed up on, or a value your own backend already stores against the account.
A purchase with no sa_visitor_id still counts. It appears in MRR, in revenue
totals and in the payments table exactly like any other - it just cannot be
placed under a traffic source in
revenue by dimension.
What Snow ignores
Sandbox purchases are dropped. Superwall sends them for real, but a
developer's test flow is not revenue, so anything not marked PRODUCTION is
discarded before it is written.
Free trials are not revenue either. A trial starting is recorded as a
trialing subscription with zero MRR, so it shows in your trial counts without
inflating your MRR. The renewal that ends it is what books the
trial_conversion.
Cancelling is not refunding. A cancellation in Superwall means auto-renew was switched off - the customer keeps access, and keeps counting, until the period actually ends. A refund is a different thing entirely: Superwall has no refund event type, and instead sends a negative price, which is what Snow tests for.
A family-share member pays nothing. Superwall sends their renewals with a price of zero, so they read as an active subscription at zero MRR rather than inheriting the organiser's.