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.

Fetch and render with the SDK#

The SDK fetches the current paywall configuration and its offering. You render your UI from that data and hand a package to purchase.

swift
let offering = try await CashSDK.offerings()

// Render your paywall from offering.paywall + offering.packages
let result = try await CashSDK.purchase(offering.monthly)

if result.entitlements["pro"]?.isActive == true {
  unlockPro()
}
kotlin
val offering = CashSDK.offerings()

val result = CashSDK.purchase(offering.monthly)

if (result.entitlements["pro"]?.isActive == true) {
  unlockPro()
}
ts
const offering = await CashSDK.offerings();

const result = await CashSDK.purchase(offering.monthly);

if (result.entitlements["pro"]?.isActive) {
  unlockPro();
}

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 — no App Store or Play review, 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#