Most SaaS paywalls are still implemented as scattered conditional logic.
You start with something simple:
if (user.isPaid) {
enableExport()
}
Then the product grows.
Now you have:
- Free users
- Pro users
- Business users
- usage limits
- feature-specific restrictions
- trials
- team permissions
- billing state
- upgrade prompts
- API enforcement
- backend authorization
Before long, monetization logic is spread across frontend components, API routes, middleware, database checks, and billing code.
That is the problem I wanted to solve with PaywallOS.
PaywallOS is an AI-powered semantic monetization and paywall platform built on top of OpenVerb, an open execution layer for AI actions.
The core idea is simple:
Instead of monetizing pages, monetize actions.
⸻
The Problem With Traditional Paywalls
Traditional SaaS products often think in terms of routes or features.
For example:
/dashboard → Free
/reports → Pro
/admin → Business
That model works for some products, but it becomes limiting when the same interface contains actions that belong to different pricing tiers.
Imagine a data platform where every user can open the dashboard.
A Free user might be able to:
view_data
search_records
create_project
A Pro user might additionally have access to:
export_data
generate_report
ai_suggestions
And a Business user might unlock:
bulk_export
team_management
advanced_analytics
The page itself is not really what you are selling.
The capabilities are.
That is where semantic monetization becomes useful.
⸻
Treating Product Features as Verbs
OpenVerb is built around the idea that software actions can be represented as semantic verbs.
Instead of thinking about a button as merely a UI component:
Export
I can describe what the button actually does:
export_data
The same approach works for many different capabilities:
generate_report
create_workspace
invite_member
ai_suggestions
download_pdf
run_analysis
publish_project
These become part of the product’s semantic action layer.
PaywallOS can then map those verbs to commercial rules.
For example:
tiers:
free:
actions:
- view_data
- search_records
pro:
actions:
- view_data
- search_records
- export_data
- generate_report
- ai_suggestions
business:
actions:
- "*"
Now the pricing model is expressed in terms of what users are allowed to do.
⸻
Frontend Integration
The frontend can remain relatively simple.
Initialize PaywallOS with the current application and user context:
initPaywallOS(
apiKey,
appId,
userId,
userTier
)
Then actionable components can be tagged with semantic verbs:
Export
Generate Report
AI Suggestions
The important part is that the UI does not need to contain the full pricing policy.
The component simply declares intent.
verb="export_data"
PaywallOS determines whether that action is allowed.
⸻
What Happens When the User Clicks?
Suppose a Free user clicks:
Export
The application can send an authorization request conceptually like:
{
"userId": "user_123",
"tier": "free",
"verb": "export_data"
}
PaywallOS evaluates the request.
The result might be:
{
"allowed": false,
"reason": "tier_required",
"requiredTier": "pro"
}
The frontend can then show the appropriate upgrade experience.
For an authorized user:
{
"allowed": true
}
The application continues with the action.
This creates a clean separation between:
User intent
↓
Monetization policy
↓
Authorization
↓
Execution
⸻
Centralizing Monetization Logic
One of my main goals with PaywallOS was eliminating pricing logic scattered throughout an application.
Without a centralized system, you eventually get code like:
if (
user.plan === "pro" ||
user.plan === "business" ||
user.isAdmin ||
user.hasLegacyAccess
) {
// ...
}
Then another component has slightly different logic.
And another API endpoint checks something else.
Eventually nobody is completely sure which rules are authoritative.
With an action-centric model, the product can have a centralized policy configuration:
actions:
export_data:
minimumTier: pro
generate_report:
minimumTier: pro
monthlyLimit: 50
ai_suggestions:
minimumTier: pro
monthlyLimit: 100
bulk_export:
minimumTier: business
team_management:
minimumTier: business
Now monetization becomes configuration rather than duplicated application logic.
That is a major architectural difference.
⸻
Usage-Based Monetization
Tier access is only one part of the problem.
AI products especially are increasingly usage-based.
A Pro subscription might include:
100 AI generations / month
50 reports / month
10 exports / day
That means authorization needs to understand more than:
Does this user have Pro?
It may also need to ask:
Has this user reached the action limit?
The action model makes this natural.
For example:
ai_suggestions:
minimumTier: pro
limits:
monthly: 100
An authorization result could then return:
{
"allowed": false,
"reason": "usage_limit",
"limit": 100,
"used": 100,
"resetAt": "2026-09-01T00:00:00Z"
}
The product can respond accordingly.
⸻
Stripe Handles Billing. PaywallOS Handles Meaning.
Stripe is excellent at managing the financial side of subscriptions.
It understands things like:
customer
subscription
price
invoice
payment
But your application still needs to understand what those billing states mean inside the product.
For example:
Stripe price_123
does not inherently mean:
allow export_data
allow generate_report
deny bulk_export
limit ai_suggestions to 100/month
That semantic mapping belongs to the application layer.
PaywallOS sits between billing state and product capability.
Conceptually:
Stripe
↓
Subscription state
↓
PaywallOS
↓
Semantic action policy
↓
Application
Stripe remains the billing infrastructure.
PaywallOS interprets that billing state as executable product permissions.
⸻
Why OpenVerb Fits This Model
OpenVerb treats actions as structured verbs.
A verb can define things such as:
name
description
input schema
output schema
policy
execution behavior
receipt
That architecture maps naturally to monetization.
If the system already understands:
export_data
as an action, then commercial policy can become another policy applied to that action.
Conceptually:
Intent
↓
Verb
↓
Authentication
↓
Monetization policy
↓
Usage policy
↓
Execution
↓
Receipt
This is especially interesting for AI systems.
An AI agent may decide that it wants to perform:
generate_report
The runtime should still be able to determine whether that user is commercially authorized to execute the verb.
The AI does not need to understand the entire pricing implementation.
It simply expresses the intended action.
⸻
AI-Native Paywall Configuration
Another area I am exploring with PaywallOS is using AI to generate the initial action library.
A developer could describe an application:
My SaaS product lets users create projects, run AI analysis,
export reports, invite teammates, and perform bulk exports.
An AI-assisted setup process could propose:
create_project
run_ai_analysis
export_report
invite_member
bulk_export
It could then suggest an initial tier structure:
Free:
create_project
Pro:
run_ai_analysis
export_report
Business:
invite_member
bulk_export
The developer still controls the final policy.
But AI can dramatically reduce the amount of configuration required to get started.
⸻
The Backend Still Has to Enforce It
Frontend paywalls should never be treated as security boundaries.
Hiding or disabling a button is useful UX, but users can still call APIs directly.
That means the same semantic authorization needs to happen on the backend.
For example:
app.post("/api/export", async (req, res) => {
const decision = await paywall.authorize({
userId: req.user.id,
verb: "export_data"
})
if (!decision.allowed) {
return res.status(403).json(decision)
}
return exportData(req, res)
})
The frontend improves the experience.
The backend provides the enforcement.
Both systems use the same semantic action.
That prevents the frontend and backend from developing separate interpretations of the pricing model.
⸻
A Better Developer Mental Model
The biggest change is not really technical.
It is conceptual.
Instead of asking:
Which page does this plan unlock?
I want developers to ask:
Which actions can this user perform?
That creates a more flexible monetization model.
The same action can appear:
- on multiple pages
- in a mobile app
- in a desktop application
- through an API
- inside an AI agent
- through an automation workflow
The commercial rule remains attached to the action.
Not the interface.
⸻
Where This Could Go
Action-based monetization opens up some interesting possibilities.
A product could eventually define:
generate_image → $0.10
run_analysis → $1.00
export_dataset → Pro
bulk_processing → Business
premium_model → 5 credits
The same semantic execution layer could support:
- subscriptions
- credits
- usage-based pricing
- per-action pricing
- API metering
- AI agent permissions
- enterprise feature controls
- marketplace actions
At that point, monetization becomes part of application architecture rather than a layer added after the product is built.
⸻
Final Thoughts
The main idea behind PaywallOS is straightforward:
Product capabilities should be first-class objects in the monetization system.
Instead of spreading pricing logic across dozens of components:
if paid
if pro
if business
if credits > 0
describe the action:
export_data
Then let a centralized policy determine:
Who can execute it?
Which tier includes it?
How often can it run?
Does it consume usage?
Should an upgrade be shown?
OpenVerb provides the semantic action model.
Stripe can provide the billing infrastructure.
PaywallOS connects those pieces into an action-centric monetization layer.
That is the architecture I am experimenting with at:
paywallos.openverb.org
If you are building SaaS, AI tools, agents, or usage-based products, I think action-level monetization is going to become increasingly useful as applications become more dynamic and less page-centric.
Top comments (0)