# 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

# Apple Retention Messaging

Configure Apple's Retention Messaging API in Superwall, including the callback URL, messages, default message mappings, and real-time configurations.

In the **Retention Messaging** section within **Integrations**, you can configure Apple's
Retention Messaging API for subscribers who intend to cancel.

> **Warning:** Apple must **first** approve your app for the Retention Messaging API before you can use this integration
> in production — Superwall cannot grant this access.After Apple has approved your app, contact
> [Superwall Support](https://support.superwall.com) to enable full message configuration in the
> dashboard. Until then, only the callback URL is available.

## What the API does

Apple's [Retention Messaging API](https://developer.apple.com/documentation/retentionmessaging)
lets you choose which message appears on the App Store's cancellation confirmation screen after a
customer taps **Cancel Subscription**. You can use it to remind subscribers what they keep with
their plan, reinforce product value, or present an alternate product or offer that may reduce
churn.

Apple supports text-only messages, messages with images, switch-plan messages, and promotional
offers. In Superwall, you use this integration to configure the callback URL Apple calls, create
retention messages, set default message mappings, and define real-time configurations.

Examples of retention messaging in the cancellation flow:

![Retention messaging examples on Apple](https://claude-centralize-agent-preamble-superwall-docs.staffbar.workers.dev/docs/images/retention-messaging-example.png)

## Apple Callback URL

The dashboard generates a callback URL using your app's public API key:

`https://retention-messaging-api.superwall.com/v1/message/<public-api-key>`

Use this as the **Retention Messaging URL** in App Store Connect for your app.

1. Copy the callback URL from **Retention Messaging** in Superwall.
2. [Request access from Apple](https://developer.apple.com/contact/request/retention-messaging-api/)
   for the Retention Messaging API.
3. In App Store Connect, open your app's subscription settings and paste the URL into the
   **Retention Messaging URL** field.
4. After Apple approves access, contact Superwall support to enable message configuration in the
   dashboard.

The callback URL does **not** change when you switch between Production and Sandbox in the
dashboard. The environment selector applies to messages, default mappings, and real-time
configurations.

## Messages

Use **Messages** to create and manage the retention message payloads that Superwall sends to Apple.

These messages are the records referenced by [Default Messages](#default-messages) and
[Real-time Configurations](#real-time-configurations).

### Create a message

When you create a message, the dashboard asks for:

* `Name`: internal label shown in Superwall.
* `Environment`: `Production` or `Sandbox`.
* `Locale`: for example, `en-US`.
* `Header`
* `Body`
* `Alt Text` (optional)
* `Image Identifier` (optional)

The messages table shows the Apple review state for each message: `PENDING`, `APPROVED`,
`REJECTED`, or `UNKNOWN`.

Create the message for the correct environment and locale before adding a default mapping or
real-time configuration that references it — the message picker only shows matches for the selected
environment and locale.

### Preview a message

After a message exists, open the three-dot menu in the messages table and choose the preview action
to see a live preview. The preview shows the message payload beside an example cancellation screen,
so you can check the header, body, locale, image, and alt text before using the message in a default
mapping or real-time configuration.

![Retention message live preview in Superwall](https://claude-centralize-agent-preamble-superwall-docs.staffbar.workers.dev/docs/images/retention_preview_view.jpg)

## Default Messages

Use **Default Messages** to define fallback message mappings by product and locale.

Use a default mapping when you want Apple to show a specific message whenever there is no matching
real-time configuration for that product.

### Create a default mapping

To create a default mapping:

1. Choose the environment.
2. Select one or more products.
3. Enter the locale.
4. Choose a message. The picker only shows messages for the same environment and locale.
5. Save the mapping.

The dashboard lets you create mappings for multiple products in one action.

> **Note:** The UI disables products that already have a default mapping in the selected environment.
> If a product is unavailable, delete its existing mapping before creating another one.

## Real-time Configurations

Use **Real-time Configurations** to map product and locale combinations to the retention message
behavior Apple should use at runtime.

### Supported configuration types

Two real-time configuration types are supported:

* `Message`: Apple uses the linked retention message.
* `Alternate Product`: Apple uses the linked message together with an alternate product.

### Create a real-time configuration

To create a configuration:

1. Enter a name.
2. Choose the environment.
3. Select one or more products.
4. Enter the locale.
5. Choose the type.
6. If the type is `Alternate Product`, choose the alternate product.
7. Choose a message. The picker only shows messages for the same environment and locale.
8. Create the configuration.

The dashboard lets you create configurations for multiple products in one action.

> **Note:** The UI disables products that already have a real-time configuration in the selected
> environment. If a product is unavailable, delete its existing configuration before creating
> another one.

If a real-time configuration exists for a product, Apple uses that behavior instead of the default
message mapping. When no real-time configuration applies, Apple falls back to the default message.