# Superwall: Subscription Infrastructure for iOS, Android, and Web

Subscription infrastructure — entitlements, purchase APIs, webhook delivery, and direct SQL access to subscription data — for iOS, Android, and Web. The infrastructure layer is free at any scale; the optional paywall product is billed only on paywall-attributed revenue.

## Pricing

- **Infrastructure: free at any scale, every plan.** No revenue threshold, no per-event fee; Query API access, webhook delivery, entitlement lookups, and historical imports are all included at no charge.
- **Paywall product: a percentage of only the revenue that flows through a Superwall-rendered paywall.** Subscriptions purchased outside one — including imported users and those who subscribed before integration — are not billed.

Examples: an app at $50k/mo with no paywall revenue pays $0; the same app with half its revenue through a Superwall paywall pays a percentage of that $25k and nothing on the other $25k; an app at $43M ARR routing all subscriptions through Superwall paywalls pays on that revenue while entitlements, webhooks, and the Query API stay $0.

## Scale

$1.5B+ annual subscription revenue across 10,000+ apps. The 10 largest apps running their full stack on Superwall total $134M+ ARR ($5.7M–$43.7M each). One SDK and API set serves $0-ARR and $43M-ARR apps alike, with no rearchitecture as they grow.

## Infrastructure capabilities

- **Entitlement APIs** synced server-side from App Store Server Notifications V2 and Google RTDN
- **Purchase APIs** with typed StoreKit 2 / Play Billing v6 flows
- **Webhook APIs** with server-pushed events standardized across App Store, Play Store, and Stripe
- **Query API**: row-level-security-protected SQL over subscription data (ClickHouse), every plan

Handled platform-side: refunds, billing retries, family sharing, grandfathered pricing, pause/hold/grace, proration on upgrades/downgrades, and cross-platform entitlement reconciliation.

## Migration

Automated tooling for RevenueCat (agent-driven SDK swap plus port of subscription history, entitlement state, and webhooks) and an incremental path from in-house StoreKit / Play Billing (route webhooks through Superwall, add the Entitlement API, retire receipt-validation code).

## Paywall product (optional, separately billable)

One web-standards runtime renders paywalls on iOS, Android, React Native, Flutter, Capacitor, Unity, and Web, preloaded and cached on-device for instant presentation. Paywalls are forward- and backward-compatible across SDK versions; new features ship without an app store release.

## Architecture

Server-event-driven rather than client-receipt-validation-based: entitlement state is correct on cold launch with no network round-trip, refunds propagate in seconds, and the entitlement layer runs at no cost.

## Docs

* Migrate from RevenueCat: https://superwall.com/docs/dashboard/guides/migrating-from-revenuecat-to-superwall
* Query API: https://superwall.com/docs/dashboard/guides/query-clickhouse
* Webhooks: https://superwall.com/docs/integrations/webhooks
* Pricing: https://superwall.com/pricing

# Superwall Framework

Build paywalls, onboarding funnels, and web checkout flows as React mini-apps, in your repo, with your tools, shipped without an app update.

> **Warning:** **Private beta.** The framework ships on the CLI's `next` channel (`SUPERWALL_CHANNEL=next`) and pushing needs Superwall for Agents enabled on your app. Nothing here is final: commands, config keys, and hooks can still change between releases. To get access, contact [support@superwall.com](mailto\:support@superwall.com).

Superwall paywalls are normally built in the visual editor. The framework is the other way to build them: as React code, in your own repo, reviewed and versioned like the rest of your app.

Everything after the build is unchanged. Paywalls are still delivered by the native SDKs, still shown through placements and campaigns, still experimented on from the dashboard, and still updated without an app release. The framework changes how a paywall is **authored**, not how it reaches your users.

"Paywall" is the dashboard's word for it, but the same project holds any screen you would rather change after shipping than release for: onboarding and quizzes, update-required and force-upgrade screens, rate-us and notification prompts, announcements, offers and win-backs. Each is a surface behind a placement, edited in code, previewed in the studio, and live on the next app open.

## What you write

A paywall is a small React app in a `superwall/` directory:

```ts
superwall/paywalls/pro/
├── config.ts          definePaywall({ name, products: { annual: "pro_5999_year" } })
├── app/               pages: index.tsx, plans.tsx, layout.tsx
├── components/        everything that is not a page
└── messages/en.ts     localized strings, discovered by filename
```

`config.ts` declares the paywall's name and which products it sells. `app/` holds the pages. Everything else is ordinary React: your components, your CSS, your dependencies. Four hooks connect it to Superwall, with [`useProducts()`](/docs/framework/hooks#useproducts) for live store prices, [`usePurchase()`](/docs/framework/hooks#usepurchase) to make the sale, [`useActions()`](/docs/framework/hooks#useactions) to close or restore, and [`useHaptics()`](/docs/framework/hooks#usehaptics) for the tap.

You preview locally with `superwall dev`, which opens a studio with device frames, light and dark toggles, locale switching, and outcomes you pick for every purchase, restore and permission. `superwall push` then seals an immutable version and `superwall promote` points production at it. Users get the new paywall on next open, with no app review.

## Why write a paywall in code

If you are comfortable in React you could build the UI yourself in an afternoon. What takes longer is everything around it, and that is the part the framework gives you:

* **Prices you cannot get wrong.** Products are declared as references like `annual: "pro_5999_year"`. Price, period, and trial terms come from the App Store, Google Play, or Stripe at runtime, already localized and formatted. A reference your dashboard has no product for blocks the push outright, so a paywall cannot ship with a stale or hardcoded price.
* **Purchases, restores, and trial eligibility, handled.** The parts that are boring to write, easy to get subtly wrong, and expensive when you do.
* **Shipping without an app release.** A hand-rolled paywall is stuck behind your release train. A pushed one is live on next open, and rolling back is one `promote`.
* **Campaigns and experiments still apply.** A code paywall is A/B tested from the dashboard like any other, so you keep the measurement.
* **Multi-step flows are natural.** An onboarding quiz or web funnel is one paywall whose steps are pages on a stack router. No network between steps and no loading spinners.
* **It lives in your repo.** PRs, code review, CI, your component library, your design tokens. Use Tailwind, Motion, Rive, or plain CSS; the framework has no opinion.

## Which should I use

| Build in the framework when                            | Build in the visual editor when            |
| ------------------------------------------------------ | ------------------------------------------ |
| Engineers own the paywall                              | Design or marketing iterate on it directly |
| You want it in git, in PRs, in CI                      | You want changes without a developer       |
| The flow is multi-step, or branches on user answers    | The paywall is a single screen             |
| You are reusing your app's components or design system | You are starting from a template           |
| You need custom animation or interaction               | The built-in components cover it           |

Both ship the same way, and an app can use both. The framework trades the no-code loop for code-level control.

> **Note:** Superwall for Agents is in **private beta**. Pushing needs it enabled on each Superwall app you push to. A push tells you if it isn't; contact [support@superwall.com](mailto\:support@superwall.com) for access.

## How it fits together

| Piece             | What it does                                                                       |
| ----------------- | ---------------------------------------------------------------------------------- |
| `superwall` (npm) | The framework: `definePaywall`, hooks, navigation, the build                       |
| `superwall` (CLI) | `create`, `dev`, `push`, `promote`, `publish`                                      |
| The studio        | Local preview at `localhost:6100`, devices, themes, locales, outcomes you pick     |
| The dashboard     | Where pushed paywalls, versions, and products live; campaigns decide who sees what |
| The native SDKs   | Present your paywall in-app, deliver product data, run purchases                   |

Your app keeps presenting paywalls exactly as it does today, through placements and campaigns. The framework changes how paywalls are *built*, not how they're *shown*.

## Start here

## Quickstart

/docs/framework/quickstart

Scaffold a project, preview your first paywall in the studio, and ship it.

## Project structure

/docs/framework/project-structure

How a `superwall/` directory is laid out and which files to commit.

## Pages & navigation

/docs/framework/navigation

Build multi-page flows with file-based routes and a stack router.

## Purchases

/docs/framework/purchases

Declare products, read live prices, and handle every purchase outcome.

## Go deeper

* **[Configuration](/docs/framework/config)**, everything `definePaywall` accepts, from presentation style to trial reminders.
* **[Web checkout](/docs/framework/web-checkout)**, sell the same paywall on the web with one config key.
* **[Variables & personalization](/docs/framework/variables)**, react to user attributes, device state, and placement parameters.
* **[Localization](/docs/framework/localization)**, one file per locale, picked automatically from the device.
* **[Examples](/docs/framework/examples)**, complete standalone projects, each teaching one idea.