> For the complete documentation index, see [llms.txt](https://docs.amply.tools/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.amply.tools/recipes/paywall-versioning.md).

# Paywall versioning

Swap paywall variants, target them to specific cohorts, and roll back the same day — no App Store or Play Store submission.

**Use this when** you want to test seasonal pricing, headline copy, or a new paywall layout without blocking on a release train. **Don't use this when** the variant needs new native UI that is not already shipped in the build; remote config cannot introduce new screens, only pick between ones that exist.

## Goal

Paywall changes that live in app code are expensive to iterate on: two weeks of review, a rollback means another submission, and you cannot target a variant to a specific cohort. This recipe ships the paywall as a remote-selectable deeplink so the dashboard decides which variant a given user sees and when.

## Setup

### In the dashboard

* Create one campaign per variant: `paywall-control`, `paywall-winter-offer`, `paywall-long-copy`.
* Trigger: session start, or on a custom event like `PaywallRequested` fired from a feature gate.
* Target audience: the free cohort (`subscription_status != "pro"`).
* Split variants by audience filter rather than a percentage split — for example, send `paywall-winter-offer` to users with `country` in `["US","CA"]`, `paywall-long-copy` to users with `install_date` after a given date, and leave `paywall-control` as the broadest-audience fallback that catches every free user not matched by a narrower variant.
* Action: fire the deeplink for that variant (`yourapp://paywall/control`, `yourapp://paywall/winter`, `yourapp://paywall/long-copy`).
* To retire a seasonal variant, move its campaign state to `Cancel` on the planned end date. The change propagates on the next session. Use `Draft` state to stage a variant that is not yet live.

### In the app (engineering hand-off)

* Ship every variant screen in the build before you promote the campaign. Remote config selects between them; it cannot create them.
* Register a deeplink handler for `yourapp://paywall/<variant>` that resolves `<variant>` to the matching view controller.
* Track the outcome so variants are comparable:

  ```typescript
  await Amply.track({ name: 'PaywallViewed', properties: { variant: 'winter' }});
  await Amply.track({ name: 'PurchaseCompleted', properties: { variant: 'winter', product: sku }});
  ```

## How it runs

1. User opens the app. Session starts.
2. Amply evaluates the paywall campaigns. The user's `country` is `"US"`, so the narrower `paywall-winter-offer` audience matches; the broader `paywall-control` audience would also match but is only selected when no narrower variant does.
3. Amply fires `yourapp://paywall/winter`. The app presents the winter variant.
4. App tracks `PaywallViewed` with `variant: "winter"`. If the user converts, `PurchaseCompleted` carries the same variant tag.
5. The growth team compares conversion across `variant` values in their analytics tool.
6. When the winter window closes, the operator moves that campaign to `Cancel`. Amply stops firing it. Users fall back to the control variant.

## Metrics to watch

* View-to-purchase rate per variant. This is the headline number.
* Average revenue per paying user per variant — protects against a variant that converts more people into a worse plan.
* Trial-start rate per variant, if the product has a trial.
* Refund and cancel rate per variant over the following 30 days. A variant that converts well but refunds high is a net loss.

## Related

* [Campaigns](/user-guide/campaigns.md) — the campaign types used here
* [Testing and rollout](/user-guide/testing-and-rollout.md) — using Draft state and instant rollback
* [Campaign delivery](/concepts/campaign-delivery.md) — how session-start and event-triggered delivery differ
* [Tracking events](/developer-guide/tracking-events.md) — tagging purchase events with the variant
* [Post-trial recovery](/recipes/post-trial-recovery.md) — a related recipe that also swaps paywalls by context
* [AI-assisted integration](/getting-started/ai-assisted-integration.md) — describe this campaign in plain language and have your AI assistant build it


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.amply.tools/recipes/paywall-versioning.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
