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:

ScopeWhy Snow needs it
projects:readTo confirm which project the key belongs to.
webhooks:readTo see whether the key may create an endpoint before trying.
webhooks:writeTo register Snow's own webhook - the only way revenue reaches Snow.
products:readTo read each product's billing period, which is what turns a price into MRR.
customers:readTo 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.

Next step

On this page