Install any skill in seconds. Free to start, no credit card required.
Get Started Free →In-app paywall and upgrade screen optimization covering feature gate design, usage limit UX, trial expiration flows, upgrade trigger timing, save offer strategy, and ethical monetization patterns.
.claude/skills/borghei-paywall-upgrade-cro/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-02 | ✗→✓ | ▲ Improved | 153% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 202% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 212% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 228% | 0% |
| case-12 | ✗→✓ | ▲ Improved | 214% | 0% |
Production-grade framework for in-product upgrade flows. Covers feature gate design, usage limit UX, trial expiration sequences, upgrade trigger timing, dark pattern avoidance, and ethical monetization. Distinct from public pricing pages (use page-cro for those) -- this focuses on in-product moments where users have already experienced value.
Before designing the paywall, confirm these inputs. If any is unknown or vague, ASK — do not assume:
Stop rule: ask only the 2-3 that most change the output. If the user says "just draft it," proceed and list your assumptions at the top of the deliverable.
| Question | Why It Matters | |----------|---------------| | What is the upgrade model? (freemium to paid, trial to paid, tier upgrade) | Determines the paywall type | | What is free vs paid? | Defines the value gap to communicate | | What triggers upgrade prompts today? | Identifies current trigger points | | What is the current free-to-paid conversion rate? | Baseline for improvement | | What is the aha moment for users? | Determines when the paywall should appear | | What pricing model? (per seat, usage, flat) | Affects paywall messaging | | Mobile app, web app, or both? | Platform-specific requirements |
The single most important rule in paywall design: The user must have experienced real value before seeing an upgrade prompt.
| Show | Do Not Show | |------|------------| | After aha moment is reached | During onboarding | | When user hits a genuine limit | On first login | | When user clicks a paid feature | When user is in the middle of a task | | After milestone completion | Immediately after a frustrating experience | | On session start (gentle reminder) | After every action |
| Trigger | When It Fires | Best For | |---------|--------------|----------| | Feature gate | User clicks a locked feature | Feature-differentiated tiers | | Usage limit | User reaches a quota | Usage-based pricing | | Trial expiration | Trial period ending | Time-limited trial models | | Time-based | After N days of active use | Freemium nurture | | Milestone-based | After user achieves X | Upsell at success moments | | Team-based | When team grows past free seat limit | Per-seat models |
| User State | Primary Trigger | Timing | |-----------|----------------|--------| | Activated, under limits | Feature gate (when they try paid feature) | On click | | Approaching limit | Soft warning (80% of limit) | Proactive | | Hit limit | Usage limit paywall | On action that exceeds limit | | Trial day 7 of 14 | Trial ending reminder | Session start | | Trial day 13 of 14 | Urgent trial expiration | Session start + email | | Trial day 14 | Trial expired | On login | | Active for 30+ days, free | Value-based upgrade prompt | Session start, once per week |
┌─────────────────────────────────────┐
│ [X Close / "Not now"] │ Escape hatch (always visible)
│ │
│ HEADLINE: Value-focused │ "Unlock [feature] to [benefit]"
│ │
│ [Feature preview / screenshot] │ Show what they are missing
│ │
│ KEY BENEFITS: │
│ - Benefit 1 │
│ - Benefit 2 │
│ - Benefit 3 │
│ │
│ PRICE: $X/month │ Clear, simple pricing
│ (or plan comparison) │
│ │
│ [UPGRADE CTA - Primary] │ "Start Pro Plan"
│ [Maybe Later - Secondary] │ Clear secondary action
│ │
│ "Join 5,000+ teams on Pro" │ Social proof
└─────────────────────────────────────┘| Trigger | Headline Pattern | CTA Pattern | |---------|-----------------|-------------| | Feature gate | "Unlock Feature] to Benefit]" | "Upgrade to Plan]" | | Usage limit | "You've used all N] resources]" | "Get Unlimited Resources]" | | Trial expiring | "Your trial ends in N] days" | "Continue with Plan]" | | Milestone | "You just hit milestone]! Keep growing with Pro" | "Upgrade & Keep Growing" | | Time-based | "Product] Pro helps teams like yours benefit]" | "See Pro Features" |
User can see what the feature does but cannot use it fully.
┌──────────────────────────────┐
│ [Feature Preview] │ Blurred screenshot or partial result
│ │
│ [Lock Icon] Pro Feature │
│ │
│ [Feature name] lets you: │
│ - Capability 1 │
│ - Capability 2 │
│ │
│ [Upgrade to Pro - $X/mo] │
│ [Maybe Later] │
└──────────────────────────────┘User cannot access the feature at all. Show the value clearly.
┌──────────────────────────────┐
│ [Lock Icon] │
│ │
│ This feature is available │
│ on the Pro plan │
│ │
│ What you get: │
│ - Benefit 1 │
│ - Benefit 2 │
│ - Benefit 3 │
│ │
│ [Upgrade to Pro] │
│ [Compare Plans] │
└──────────────────────────────┘┌──────────────────────────────────┐
│ [Progress Bar: 80%] │
│ You've used 80 of 100 credits │
│ │
│ [Get More Credits] [Dismiss] │
└──────────────────────────────────┘┌──────────────────────────────────────┐
│ [Progress Bar: 100%] │
│ You've reached your monthly limit │
│ │
│ Free: 100 credits | Pro: Unlimited │
│ │
│ [Upgrade to Pro] │
│ [Delete items to free space] │ Alternative action
└──────────────────────────────────────┘| Day | Channel | Message | Tone | |-----|---------|---------|------| | Day 7 (of 14) | In-app banner | "7 days left in your trial" | Informational | | Day 10 | Email | "4 days left -- here's what you've accomplished" | Value summary | | Day 12 | In-app modal | "2 days left -- don't lose access to feature]" | Mild urgency | | Day 13 | Email | "Tomorrow is your last day" | Urgency + offer | | Day 14 | In-app full screen | "Your trial has ended" | Clear options | | Day 15 | Email | "We kept your data safe -- reactivate anytime" | Reassurance |
┌─────────────────────────────────────────┐
│ Your trial has ended │
│ │
│ What you accomplished during trial: │
│ - Created [N] projects │ Personalized data
│ - Invited [N] team members │
│ - Saved an estimated [X] hours │
│ │
│ What happens now: │
│ - Your data is saved for 30 days │
│ - Read-only access to existing work │
│ - Full access resumes when you upgrade │
│ │
│ [Continue with Pro - $X/mo] │
│ [Remind Me Later] [Downgrade to Free] │
└─────────────────────────────────────────┘| Rule | Implementation | |------|---------------| | Max 1 paywall per session | Do not interrupt twice in one visit | | 3-7 day cooldown after dismissal | If they click "Not now", wait at least 3 days | | Never during active task | If user is creating, editing, or mid-workflow, do not interrupt | | Cap at 3 per month | After 3 dismissals in a month, stop showing until next month | | Track annoyance signals | If user closes paywall within 1 second repeatedly, increase cooldown |
| Attempt | Approach | Invasiveness | |---------|----------|-------------| | 1 | Subtle banner or sidebar widget | Low | | 2 | Modal with value proposition | Medium | | 3 | Modal with special offer (discount/extended trial) | Medium-High | | 4+ | Reduce frequency, switch to email nurture | Low (change channel) |
| Step | Optimization | |------|-------------| | 1. Click upgrade CTA | Opens upgrade flow (do not redirect to external page if avoidable) | | 2. Plan selection | Pre-select the recommended plan, show comparison | | 3. Payment | Pre-fill known info (email, name), support all payment methods | | 4. Confirmation | Immediate access to paid features, confirmation email | | 5. Post-upgrade | Guide to newly unlocked features, celebration moment |
| Dark Pattern | Why It Fails | Ethical Alternative | |-------------|-------------|---------------------| | Hidden close button | Breaks trust, generates support tickets | Clear X in top-right corner | | Shame copy ("No, I don't want to grow my business") | Manipulative, reduces brand respect | "Maybe later" or "Not now" | | Countdown timer (fake urgency) | Users discover it resets, destroys credibility | Only use for genuinely expiring offers | | Confusing plan selection | Users feel tricked, higher refund rate | Clear plan names with honest comparison | | Blocking critical actions | Users feel trapped, generates churn | Allow continued use of existing features | | Making downgrade difficult | Regulatory risk (especially in EU/CA) | One-click downgrade option |
| Metric | Formula | Benchmark | |--------|---------|-----------| | Paywall impression rate | Users who see paywall / Active users | Track, no universal benchmark | | Paywall CTR | Upgrade clicks / Paywall impressions | 5-15% | | Upgrade completion rate | Completed upgrades / Upgrade clicks | 30-60% | | Free-to-paid conversion | Paid users / Total free users | 2-5% for freemium, 15-30% for trial | | Revenue per user (ARPU) | Total revenue / Active users | Segment-dependent | | Post-upgrade churn (30-day) | Churned within 30 days / New paid users | < 10% |
| Signal | Diagnosis | Action | |--------|-----------|--------| | CTR < 3% | Paywall copy or timing is wrong | Test different triggers and messaging | | Completion < 20% | Upgrade flow has too much friction | Simplify payment flow | | Post-upgrade churn > 15% | Value not matching expectations | Review feature access and onboarding | | Free-to-paid < 1% | Paywall appears before value is delivered | Delay triggers until after activation |
| Test | Hypothesis | Metric | |------|-----------|--------| | Trigger timing (earlier vs later) | Later trigger = higher conversion rate | Free-to-paid conversion | | Soft gate vs hard gate | Soft gate (preview) converts better | Feature gate CTR | | Copy variation | Value-focused vs urgency-focused | Paywall CTR | | Price presentation | Monthly vs annual default | ARPU |
| Artifact | Format | Description | |----------|--------|-------------| | Paywall Trigger Map | Trigger x timing x frequency table | All trigger points with rules and cooldowns | | Screen Copy Set | Complete screen designs | Headline, benefits, CTA, escape hatch for each paywall type | | Upgrade Flow Diagram | Step-by-step flow | Paywall click to post-upgrade confirmation | | Dark Pattern Audit | Checklist | Review of existing paywall for manipulative patterns | | Trial Expiration Sequence | Day-by-day plan | In-app + email sequence for trial countdown | | A/B Test Backlog | Prioritized table | Test ideas ranked by expected impact |
Audits paywall trigger configuration for timing, frequency, and coverage issues. Reads a JSON file of trigger rules and user event data, then flags misconfigured triggers, missing cooldowns, and dark-pattern risks.
bashpython scripts/paywall_trigger_auditor.py triggers.json --format text python scripts/paywall_trigger_auditor.py triggers.json --format json
| Flag | Type | Description | |------|------|-------------| | triggers.json | positional | Path to JSON file with trigger rules and event data | | --format | optional | Output format: text (default) or json |
Analyzes upgrade funnel step-by-step conversion from paywall impression through payment completion. Identifies the highest-drop steps, calculates stage-over-stage conversion, and benchmarks against industry targets.
bashpython scripts/upgrade_funnel_analyzer.py funnel.json --format text python scripts/upgrade_funnel_analyzer.py funnel.json --format json
| Flag | Type | Description | |------|------|-------------| | funnel.json | positional | Path to JSON file with funnel step data | | --format | optional | Output format: text (default) or json |
Scores paywall screen copy against proven conversion patterns. Evaluates headline structure, benefit clarity, CTA strength, social proof presence, and dark-pattern risk. Outputs a 0-100 score with itemized feedback.
bashpython scripts/paywall_copy_scorer.py copy.json --format text python scripts/paywall_copy_scorer.py copy.json --format json
| Flag | Type | Description | |------|------|-------------| | copy.json | positional | Path to JSON file with paywall copy elements | | --format | optional | Output format: text (default) or json |
| Problem | Likely Cause | Resolution | |---------|-------------|------------| | Paywall CTR below 3% | Trigger fires before user reaches aha moment or copy is feature-focused instead of benefit-focused | Delay trigger until after activation event; rewrite headline to outcome-based messaging (lifts CTR up to 23% per Strava case study) | | Upgrade completion below 20% | Too much friction in payment flow (redirects, missing payment methods, surprise charges) | Keep flow in-context (modal/slide-out), pre-fill known info, show price before payment step | | Post-upgrade churn above 15% | Value expectation mismatch -- paid experience does not match what the paywall promised | Audit feature access post-upgrade, add guided tour of newly unlocked features, align copy with actual capabilities | | Free-to-paid conversion below 1% | Paywall appears before value is delivered or free tier is too generous | Map activation events and ensure paywall only fires after aha moment; review free vs paid feature boundary | | Users close paywall within 1 second repeatedly | Paywall is interrupting workflow or appearing too frequently | Increase cooldown to 7+ days after dismissal, cap at 3 per month, switch to less intrusive format (banner vs modal) | | Mobile paywall underperforms desktop by >30% | iOS/Android IAP friction, small dismiss targets, or full-screen overlay on mobile | Ensure 44x44px touch targets, use bottom-sheet format on mobile, comply with App Store guidelines | | Trial expiration emails have low open rate | Generic subject lines, wrong send timing, or email deliverability issues | Personalize with usage data ("You created 12 projects"), send at user's active hours, check spam score |
In scope: In-product upgrade flows including feature gates, usage limit screens, trial expiration sequences, upgrade trigger timing, save offer strategy, paywall screen design, and A/B test frameworks for freemium-to-paid and trial-to-paid conversion.
Out of scope: Public-facing pricing pages (use page-cro), the pricing model itself (use pricing-strategy), post-signup onboarding before the aha moment (use onboarding-cro), initial registration flows (use signup-flow-cro), and post-upgrade churn intervention (use churn-prevention). This skill does not cover App Store Optimization (ASO) or paid acquisition strategies. Scripts operate on local data only -- no integrations with payment processors, analytics platforms, or A/B testing tools.
Limitations: Conversion benchmarks are based on aggregate SaaS/app industry data and may vary significantly by vertical, price point, and audience. Mobile paywall performance is highly dependent on platform-specific IAP requirements (Apple 30% commission, Google Play billing). Scripts analyze static snapshots; real-time paywall optimization requires integration with analytics and experimentation platforms not provided here.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 24,457 | 23,453 | -4% | 1 | 1 | 0% | 3,798 | 8,984 | +137% | 0 | 0 | — |
case-02 | fail→pass | 28,402 | 36,689 | +29% | 1 | 1 | 0% | 4,284 | 10,828 | +153% | 0 | 0 | — |
case-03 | fail→fail | 15,615 | 15,104 | -3% | 1 | 1 | 0% | 2,181 | 7,587 | +248% | 0 | 0 | — |
case-04 | fail→fail | 18,420 | 12,556 | -32% | 1 | 1 | 0% | 2,670 | 7,078 | +165% | 0 | 0 | — |
case-05 | fail→fail | 19,520 | 27,905 | +43% | 1 | 1 | 0% | 2,935 | 9,651 | +229% | 0 | 0 | — |
case-06 | fail→pass | 17,592 | 15,616 | -11% | 1 | 1 | 0% | 2,482 | 7,508 | +202% | 0 | 0 | — |
case-07 | fail→pass | 17,979 | 21,055 | +17% | 1 | 1 | 0% | 2,736 | 8,547 | +212% | 0 | 0 | — |
case-08 | pass→pass | 16,005 | 25,159 | +57% | 1 | 1 | 0% | 2,216 | 8,388 | +279% | 0 | 0 | — |
case-09 | fail→pass | 16,759 | 13,569 | -19% | 1 | 1 | 0% | 2,177 | 7,145 | +228% | 0 | 0 | — |
case-10 | pass→pass | 16,888 | 20,864 | +24% | 1 | 1 | 0% | 2,375 | 8,119 | +242% | 0 | 0 | — |
case-11 | pass→pass | 16,855 | 13,965 | -17% | 1 | 1 | 0% | 2,478 | 7,166 | +189% | 0 | 0 | — |
case-12 | fail→pass | 20,255 | 27,865 | +38% | 1 | 1 | 0% | 2,995 | 9,402 | +214% | 0 | 0 | — |
case-13 | fail→pass | 11,320 | 4,410 | -61% | 1 | 1 | 0% | 1,745 | 6,043 | +246% | 0 | 0 | — |
case-14 | fail→pass | 6,235 | 2,608 | -58% | 1 | 1 | 0% | 921 | 5,745 | +524% | 0 | 0 | — |
case-15 | fail→pass | 8,367 | 3,519 | -58% | 1 | 1 | 0% | 1,151 | 5,887 | +411% | 0 | 0 | — |
case-16 | fail→pass | 14,531 | 10,066 | -31% | 1 | 1 | 0% | 2,251 | 6,869 | +205% | 0 | 0 | — |
case-17 | pass→pass | 14,427 | 17,144 | +19% | 1 | 1 | 0% | 2,037 | 7,840 | +285% | 0 | 0 | — |
case-18 | pass→pass | 16,347 | 17,582 | +8% | 1 | 1 | 0% | 2,253 | 7,898 | +251% | 0 | 0 | — |
case-19 | fail→fail | 15,378 | 17,373 | +13% | 1 | 1 | 0% | 2,252 | 8,019 | +256% | 0 | 0 | — |
case-20 | fail→pass | 15,104 | 12,100 | -20% | 1 | 1 | 0% | 2,058 | 7,049 | +243% | 0 | 0 | — |
case-21 | fail→pass | 14,444 | 13,443 | -7% | 1 | 1 | 0% | 2,076 | 7,279 | +251% | 0 | 0 | — |
case-22 | fail→pass | 13,101 | 20,488 | +56% | 1 | 1 | 0% | 1,940 | 8,473 | +337% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +55 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.