We Were Pricing PPV Blind — Then We Segmented Fans by Spend History
Every fan on our roster was getting the same $20 PPV price. When we pulled spend history data, we discovered our top fans would have paid $75 — and our casual fans needed $10 to convert at all.
For two years, our agency had a PPV strategy that we were quietly proud of. We price-tested our way to $20. It felt scientific. It was the number that sat comfortably in the middle — not so cheap it devalued the content, not so expensive it killed conversion. We presented it in client calls as a data-informed decision.
It wasn’t. It was a guess dressed up as a number.
When we finally pulled spend history data across our top five creators and ran actual onlyfans fan segmentation analysis, the $20 price point turned out to be the worst of all worlds: too expensive for casual fans to convert, and so far below market rate for our top spenders that we were leaving the bulk of available revenue on the table. The same PPV blast was simultaneously under-performing with fans who would have paid $75 and failing to convert fans who needed $10.
That one insight changed how we think about onlyfans ppv pricing entirely. Here is how we found it and what we built from it.
The Flat-Price Assumption We Never Questioned
The logic behind flat PPV pricing is seductive. You pick one price, blast it to everyone, track open rates and purchase rates, and optimize from there. It feels like a system. The problem is that it treats a creator’s fan base as a homogeneous group, when the spending behavior across that group varies by a factor of ten or more.
Most creators we work with have a fan base that looks something like this when you segment by 90-day spend: a small top tier that represents maybe 8% of subscribers but 55% of revenue, a mid-tier that represents 30% of subscribers and 35% of revenue, and a large base of casual or dormant fans who have barely spent anything since the initial subscription charge.
If you price to the top tier, the casual fans never convert. If you price to the casual fans, you’re charging your whales a fraction of what they’d happily pay. A flat price optimizes for the average and under-serves everyone.
We didn’t know our own distribution until we started querying it.
Pulling the Spend History
The /stats/fans/top endpoint gave us our first real look at spending concentration. Combined with /fans/info for individual fan records, we could reconstruct 90-day spend histories across our entire roster and build proper segmentation tiers.
The key insight is that you want to know not just who the top spenders are, but where the natural break points exist in your spending distribution. Those break points tell you how many tiers make sense and what price to set for each.
import requests
import statistics
from collections import defaultdict
API_KEY = "your_api_key"
BASE_URL = "http://157.180.79.226:4024/api/v1"
headers = {"X-API-Key": API_KEY}
def get_top_fans(creator_id, limit=500):
response = requests.get(
f"{BASE_URL}/stats/fans/top",
headers=headers,
params={"creatorId": creator_id, "limit": limit}
)
response.raise_for_status()
return response.json().get("fans", [])
def get_fan_info(fan_id):
response = requests.get(
f"{BASE_URL}/fans/info",
headers=headers,
params={"fanId": fan_id}
)
response.raise_for_status()
return response.json()
def segment_fans_by_spend(creator_id):
fans = get_top_fans(creator_id)
spend_data = []
for fan in fans:
info = get_fan_info(fan["fanId"])
total_spend = info.get("totalSpend90d", 0)
spend_data.append({
"fan_id": fan["fanId"],
"username": fan.get("username"),
"spend_90d": total_spend,
"ppv_purchases": info.get("ppvCount90d", 0),
"subscription_months": info.get("subscriptionMonths", 0)
})
spend_data.sort(key=lambda x: x["spend_90d"], reverse=True)
total_fans = len(spend_data)
top_8_pct = max(1, int(total_fans * 0.08))
next_30_pct = max(1, int(total_fans * 0.30))
tiers = {
"whale": spend_data[:top_8_pct],
"mid": spend_data[top_8_pct:top_8_pct + next_30_pct],
"casual": spend_data[top_8_pct + next_30_pct:]
}
for tier_name, tier_fans in tiers.items():
if not tier_fans:
continue
spends = [f["spend_90d"] for f in tier_fans]
avg = statistics.mean(spends)
median = statistics.median(spends)
print(f"\n{tier_name.upper()} TIER ({len(tier_fans)} fans)")
print(f" Avg 90d spend: ${avg:.2f}")
print(f" Median 90d spend: ${median:.2f}")
print(f" Total spend: ${sum(spends):.2f}")
return tiers
tiers = segment_fans_by_spend("creator_123")
When we ran this across five creators, the concentration was more extreme than we’d expected. The top 8% of fans were averaging $340 in 90-day spend. The mid tier was averaging $67. The casual base was averaging $9.
A $20 PPV is a rounding error to a fan spending $340 in 90 days. And it’s a complete non-starter for a fan who has spent $9 total.
Calculating Optimal Price Points Per Tier
Once we had the spend distribution, we needed to convert it into price recommendations. We used a simple heuristic: for each tier, the PPV price that maximizes conversion without cannibilizing revenue is roughly 15-20% of the average fan’s 90-day spend. This gives you a number that feels proportional to their existing commitment without being a stretch.
But we also cross-referenced against historical PPV purchase data. Fans who had bought PPVs before told us their revealed price tolerance — the price at which they actually converted. That historical behavior is a stronger signal than calculated ratios alone.
def calculate_tier_pricing(tiers):
price_recommendations = {}
for tier_name, tier_fans in tiers.items():
if not tier_fans:
continue
spends = [f["spend_90d"] for f in tier_fans]
avg_spend = statistics.mean(spends)
ppv_buyers = [f for f in tier_fans if f["ppv_purchases"] > 0]
historical_conversion_rate = len(ppv_buyers) / len(tier_fans) if tier_fans else 0
# Base price at 18% of average 90d spend
base_price = avg_spend * 0.18
# Floor and ceiling by tier
floors = {"whale": 35, "mid": 14, "casual": 7}
ceilings = {"whale": 120, "mid": 35, "casual": 18}
recommended_price = max(floors[tier_name], min(ceilings[tier_name], round(base_price / 5) * 5))
price_recommendations[tier_name] = {
"recommended_price": recommended_price,
"avg_spend_90d": avg_spend,
"fan_count": len(tier_fans),
"historical_ppv_conversion": f"{historical_conversion_rate * 100:.1f}%"
}
print(f"{tier_name.upper()}: Recommended PPV price = ${recommended_price} "
f"(avg spend: ${avg_spend:.0f}, conversion rate: {historical_conversion_rate*100:.1f}%)")
return price_recommendations
pricing = calculate_tier_pricing(tiers)
The output for our first creator was illuminating:
- Whale tier (top 8%): Recommended price $75. Average 90d spend $340, historical PPV conversion 71%.
- Mid tier (next 30%): Recommended price $20. Average 90d spend $112, historical PPV conversion 34%.
- Casual tier (remaining 62%): Recommended price $10. Average 90d spend $19, historical PPV conversion 8%.
We had been charging whales $20 and charging casual fans $20. Same price, wildly different customer.
What Tiered Pricing Looks Like in Practice
The mechanics of tiered PPV distribution are straightforward: when you release a piece of content, instead of one mass-send at a single price point, you run three sends to three groups. The content is identical. The price is different.
We built this into our standard PPV release workflow. Every release now goes through three sends scheduled within minutes of each other — whale tier at the top price, mid tier at the middle price, casual tier at the floor price. We track conversions by tier after 24 hours and use that data to refine the price recommendations for the next release.
The first concern every creator has when you explain this: “Won’t fans find out they paid more than someone else?” In practice, no. OnlyFans fans aren’t comparing PPV receipts with each other. And even if they did, the prices we’re talking about — $10 vs $20 vs $75 — don’t create outrage the way airline pricing does. The content is still priced proportionally to what the fan has demonstrated they’re willing to spend.
The second concern is operational: is this three times the work? Not with the API. You pull the segment lists once, you build the send logic once, and then every release runs through the same automated flow. The marginal effort per PPV drop is nearly zero.
The Revenue Impact
We ran tiered pricing across our roster for 90 days before pulling comparison numbers. The results were not ambiguous.
Before tiered pricing (flat $20):
- Average PPV conversion rate across all fans: 14%
- Average revenue per PPV release (one creator, 3,200 subscribers): $896
- Top fan tier conversion rate: 71% (but at $20, not $75)
After tiered pricing (three tiers):
- Average PPV conversion rate across all fans: 19%
- Average revenue per PPV release (same creator, same content): $2,104
- Top fan tier conversion rate: 68% at $75
The casual fan conversion rate went from near-zero to 11% when we dropped their price to $10. We were making $0 from casual fans with flat pricing because they never converted. At $10, they converted in volume — and 11% of 1,984 casual-tier fans adds up fast.
The whale tier revenue calculation is even more striking. Charging 256 whale-tier fans $75 instead of $20 — with essentially the same conversion rate — is the difference between $3,584 in whale revenue and $9,600. Per PPV release. On the same piece of content.
Across our five creators over 90 days, total PPV revenue increased 40% with no increase in content volume. The content was already there. We were just pricing it to the audience.
What This Requires You to Know
Tiered onlyfans ppv pricing is not complex, but it requires two things that most agencies don’t have: a clean spend history segmentation and a workflow for executing segmented sends.
The spend history piece is now automated — we run the segmentation script at the start of each week and maintain a live tier list for every creator. Fans move tiers as their spend behavior changes. A casual fan who goes on a spending run gets upgraded to mid-tier. A whale who hasn’t engaged in 60 days gets flagged for re-engagement before they get reclassified.
The workflow piece is a matter of discipline. Every PPV release gets a brief — who the tiers are, what the price points are, what the scheduled send times are. It takes 10 minutes before a release versus zero minutes when you’re just blasting everyone the same thing. The 10 minutes pays for itself many times over.
The underlying principle applies beyond PPV as well. Any time you’re making a one-size-fits-all offer to a fan base that clearly isn’t one size, you’re leaving revenue on the table. Subscription pricing, bundle offers, personalized content requests — all of them benefit from the same segmentation logic.
For more on building fan behavior profiles, see our post on predicting churn from engagement signals and the full fan segmentation API reference.
If you are managing PPV for one or more creators and you have never segmented your fan base by spend history, you almost certainly have a significant gap between what you are earning and what is available. Close that gap: pull your spend distribution this week, find the natural break points in your fan tiers, and run your next PPV release at three price points instead of one. The revenue difference will be visible within 24 hours.
Explore the full feature set on the pricing page, or start querying your fan data directly from the API documentation.