Paywalls

Design server-driven paywalls, publish them over the air, and optimize revenue with A/B experiments.

A paywall is the screen that sells an offering: the set of products a customer can buy. In CashSDK, paywalls are configured on the server and fetched by the SDK at runtime, so you can restyle pricing, copy, and layout without shipping an app update.

Create a paywall#

1
Pick a starting point

Start from the visual editor in the dashboard, or from a prebuilt template. List available templates:

bash
curl https://api.cashsdk.com/v1/templates \
  -H "Authorization: Bearer csk_sk_..."
2
Define the paywall

Create it against your app via the API. The offering, its products, and display metadata are all part of the payload.

bash
curl https://api.cashsdk.com/v1/apps/{app}/paywalls \
  -H "Authorization: Bearer csk_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Main Paywall",
    "identifier": "main",
    "offering": "default",
    "products": ["pro_monthly", "pro_annual"],
    "template": "hard-sell",
    "targeting": { "platform": ["ios", "android"] }
  }'
3
Or let an agent build it

Point your coding agent at the CashSDK MCP server and call the generate_paywall tool. Describe the offer in plain language and it scaffolds the paywall, wires the products, and publishes a draft for review.

Present with the SDK#

Register a placement and CashSDK resolves the campaign, audience and experiment for you, then presents the paywall your team configured in the dashboard. It is fire-and-forget: with no campaign, no network, or a bad config it silently advances, so your app is never blocked by a paywall it could not load.

swift
CashSDK.shared.register(placement: "onboarding_finished")
kotlin
CashSDK.shared.register(placement = "onboarding_finished")

Building the UI yourself instead? Read prices from the native store (Product.products(for:) on iOS) and pass the selected product identifier to purchase(_:).

Update over the air#

Paywalls are versioned server-side. When you publish a change in the dashboard or via POST /v1/apps/{app}/paywalls, every device picks it up on its next fetch, with no App Store or Play review and no client release. Roll back just as fast by re-publishing a previous version.

A/B experiments#

CashSDK can serve multiple paywall variants and split traffic between them. Each variant is measured on revenue per impression, so the winner accounts for both conversion rate and price, not clicks alone.

1
Create variants

Duplicate a paywall and change one thing at a time (price emphasis, headline, trial length, layout).

2
Split traffic

Assign each variant a percentage of impressions. Customers are bucketed deterministically by app_user_id so they always see the same variant.

3
Ship the winner

Watch revenue per impression converge, then promote the winning variant to 100%. Everything happens over the air.

Targeting#

Serve different paywalls to different audiences without branching in your app. Target by:

  • Country: localize pricing, currency framing, and offers per region.
  • Platform: different layouts for iOS, Android, and Web.
  • Cohort: segment by acquisition source, app version, or lifecycle stage (new install, lapsed, returning).

The SDK sends the customer's live attributes with each fetch, and CashSDK resolves the highest-priority matching paywall on the server.

Next steps#