logicspike/docs

Billing

Vlozi Pricing & Plan Redesign — Proposal

Status: Draft for review Date: 2026-04-23 Author: Dipanshu + Claude Decision owner: Dipanshu


TL;DR

The current pricing page displays "0 blog posts / 0 scheduled posts / 0 emails" across every paid tier. This is not a data bug — it's a presentation bug. Vlozi is designed as a hybrid model: capacity features are tier-gated, consumption features are credit-metered. The UI is trying to show consumption features as if they were capacity features, so they render as zero.

This doc proposes:

  1. Keep the hybrid model (capacity + credits) — it's the right architecture.
  2. Rewrite the pricing page to make the two axes obvious instead of hiding them.
  3. Refine the plan ladder — current numbers are defensible, but 2 dimensions need tightening.
  4. Anchor every tier to a persona + a "what your credits actually buy" translation table so prospects can self-select.

No schema or pricing-engine changes required — this is largely a UI/copy project plus some plan-limit tuning.


1. Current State (what's actually in place)

1.1 The two-axis design (already implemented)

The billing system has two independent gating mechanisms:

Axis What it gates Enforcement Examples
Capacity (tier-gated) Things that are persistent state Hard cap per plan via plan_service_limitstenant_services Team seats, API keys, storage GB, custom roles, custom domain
Consumption (credit-metered) Things that happen per-action Credits debited on use; user can top up or upgrade AI chat, content generation, blog publish, email send

Seed file packages/core-database/src/seed.ts line 119 literally comments:

// Static holding limits only (transactional usage drains credits instead)

The design intent is clear. The UI doesn't reflect it.

1.2 Current plan values (as seeded)

Free Starter Pro Business
Price / month ₹0 ₹999 ₹2,499 ₹6,799
Price / year ₹9,990 (17% off) ₹24,990 (17% off) ₹67,990 (17% off)
Trial 14 days 14 days 14 days
Monthly credits 100 5,000 15,000 50,000
Team seats 2 5 15 50
Extra seat cost ₹199/mo ₹149/mo ₹99/mo
API keys 1 5 20 Unlimited
Custom roles 0 3 10 Unlimited
Blog storage 512 MB 5 GB 20 GB 100 GB
Media storage 512 MB 5 GB 20 GB 100 GB
Custom domain

1.3 Credit costs (what 1 action consumes)

Source: packages/core-types/src/credit-costs.ts

Action Cost
AI chat — base hold 1 credit
AI chat — per 1k tokens +1 credit
AI insight generation 5 credits
Blog post publish 10 credits
Content generation (bulk) 20 credits
Email send 1 credit

1.4 Existing credit packs

Pack Price Credits Bonus Effective ₹/credit
Small ₹415 500 0% ₹0.83
Medium ₹1,660 2,200 10% ₹0.69
Large ₹4,150 6,000 20% ₹0.57

1.5 Existing add-ons (recurring, credit-funded)

Add-on Cost Unit
Extra storage 50 credits per GB/month
Extra team seat 100 credits per seat/month
Custom domain 200 credits per domain/month

2. The Problem

2.1 UI shows consumption as capacity

The pricing page renders a plan's features by iterating plan_service_limits. Consumption features (blog posts, scheduled posts, email sends) aren't in that table because they're not capacity gates. The UI defaults those to zero and displays "0 blog posts", which reads to a prospect as "this plan doesn't let me blog."

This is misleading and sabotages conversion on the paid tiers.

2.2 Credits are underexposed

The credit allowance (100 / 5,000 / 15,000 / 50,000) is the single most differentiated dimension across tiers, but the UI shows it as one badge at the top of the card with no translation. A prospect has no way to know if 5,000 credits is "enough for my weekly blog" or "gone in an hour."

2.3 Persona ambiguity

Nothing on the page tells a prospect which tier they are. There's no "Best for solo creators" / "Best for teams" framing. Tier self-selection is left to the visitor to reverse-engineer from feature lists.


3. Design Principles (for the redesign)

  1. Two-axis gating is correct — don't flatten it. Capacity gates are real and persistent. Credits are metered and fungible. Both belong on the pricing page but labeled differently.
  2. Show credits in customer-meaningful units, not abstract numbers. "5,000 credits ≈ 500 blog posts OR 5,000 emails OR 250 AI content generations" means something. "5,000 credits" means nothing.
  3. Anchor each tier to a persona. The purpose of tiering is self-selection.
  4. Price ladders should have justifiable jumps. Not arbitrary.
  5. Subscription credits must be ≥3x cheaper than credit packs (currently 3-5x — maintain this).
  6. Don't gate things we don't enforce. Remove dead limit keys. Stop claiming "0 emails" when we don't actually cap emails.

4. Proposed Plan Structure

4.1 Tier count: 5 tiers (adding Basic)

  • 3 tiers (Good/Better/Best): simpler, better-converting in theory — but loses the distinction between "solo creator" and "team," which are genuinely different buyers.
  • 5 tiers (proposed): Right for now. Adding a "Basic" ₹399 tier captures the hobbyist/student market who find ₹999 too steep for a side project. Revisit Enterprise in Q3/Q4 once SSO + audit log + SLA are real.

4.2 Personas (the prose that goes on each card)

Tier Persona headline Pitch
Free "Explore" Try everything. Ship your first post. No credit card.
Basic "Hobbyists & students" Just getting started. One blog, no team, essential AI tools.
Starter "Solo creators & side projects" One blog, one voice, AI-powered drafts.
Pro "Teams publishing weekly" Multi-author workflows, email campaigns, custom domains at scale.
Business "Agencies & established brands" Manage multiple brands, high-volume content, priority support.

4.3 Proposed plan matrix

Deltas from current shown as → arrows. Bold = changed.

Free Basic Starter Pro Business
Price / mo ₹0 ₹399 ₹999 ₹2,499 ₹6,799
Price / yr (17% off) ₹3,990 ₹9,990 ₹24,990 ₹67,990
Trial 14 days 14 days 14 days 14 days
Monthly credits 100 1,500 5,000 15,000 50,000
Team seats 2 → 1 1 5 15 → 10 50
Extra seat ₹199/mo ₹149/mo ₹99/mo
API keys 1 2 5 20 → 10 Unlimited
Custom roles 0 0 3 10 Unlimited
Storage (blog + media, combined) 512MB each → 1GB total 2GB total 5GB each → 10GB total 20GB each → 50GB total 100GB each → 200GB total
Custom domain 1 1 1 → 3 1 → 10
Priority support ✅ email ✅ phone + Slack

Rationale for each change:

  • Free: 2 → 1 seat. A single-user Free plan forces teams to upgrade; 2 seats lets a founding duo stay free forever. Match the messaging ("try everything, ship your first post").
  • Pro: 15 → 10 seats. The gap between Starter (5) and Pro (15) is 3x. Business jumps to 50. Flattening Pro to 10 makes the ladder 5 → 10 → 50 — the "team" tier shouldn't include mid-agency capacity.
  • Pro: 20 → 10 API keys. API key sprawl past 10 is almost always a sign you've outgrown Pro and should be on Business.
  • Storage combined, not split. The current split (blog.storage_mb and media.storage_mb as separate gates) is an implementation detail leaking into pricing. Customers don't care. Combine into one "Storage" number and track internally.
  • Custom domain count. Pro and Business should support multiple custom domains (multi-brand agencies need this). Starter keeps 1.
  • Priority support. Currently no support tiering. Agencies expect it; it's a $0-cost pricing differentiator.

4.4 What the UI should show (per card)

Starter                          [14-day free trial]
Solo creators & side projects
₹999 /month   or   ₹9,990/year (save 17%)
 
✨ 5,000 monthly credits
   ≈ 500 blog posts published
   ≈ 5,000 emails sent
   ≈ 250 AI content generations
   Credits reset monthly. Top up anytime from ₹415.
 
Included:
  • 5 team members
  • 10 GB storage
  • 1 custom domain
  • 5 API keys, 3 custom roles
 
[ Start 14-day free trial ]

Note what's not on the card: "0 blog posts / 0 emails / 0 scheduled." Those were never real gates.


5. Credit Economics

5.1 What 1 month of credits actually buys

Using standard cost table from §1.3:

Credits = Blog posts (10c) = Emails (1c) = Content gens (20c) = AI chats (~2c avg)
100 (Free) 10 100 5 ~50
1,500 (Basic) 150 1,500 75 ~750
5,000 (Starter) 500 5,000 250 ~2,500
15,000 (Pro) 1,500 15,000 750 ~7,500
50,000 (Business) 5,000 50,000 2,500 ~25,000

Realistically, customers mix actions. A typical Starter user publishing 20 posts/mo + sending 500 emails + doing 50 AI chats consumes: 20×10 + 500×1 + 50×2 = 800 credits. They use ~16% of their allowance. This is correct: monthly credits should feel abundant for the tier's typical persona. Bottlenecks drive upgrades only at clear persona-crossing points.

5.2 Subscription vs pack pricing (is the ratio right?)

Source Effective ₹/credit
Starter subscription ₹0.20
Pro subscription ₹0.17
Business subscription ₹0.14
Small pack ₹0.83
Medium pack ₹0.69
Large pack ₹0.57

Packs are 3–5× more expensive than subscription credits. This is healthy. Packs are for burst usage; subscriptions are for baseline. A Starter customer hitting credit limits should always find upgrading to Pro more attractive than buying packs repeatedly.

Math check: Starter (5k for ₹999) + Medium pack (2.2k for ₹1,660) = 7.2k credits for ₹2,659. Upgrading to Pro instead: 15k credits for ₹2,499. Pro gives 2× credits for less money. The upgrade path dominates. Good.

5.3 Pricing ladder (are the price jumps right?)

Jump Price multiplier Credits multiplier Seats multiplier
Free → Basic 15×
Basic → Starter 2.5× 3.3×
Starter → Pro 2.5× 2× (proposed 2×)
Pro → Business 2.7× 3.3×

Starter → Pro and Pro → Business have similar price/credit ratios (credits scale slightly faster than price — correct for a consumption-heavy product). The ladder works.

What's slightly off: Pro → Business price jump is 2.7× but seat jump is 5× (proposed 10→50). Agencies paying ₹6,799 get disproportionate seat capacity. This is fine (we want agencies on Business), but it means Starter-sized agencies (~15 seats) get squeezed: they need Business for seats but don't need 50k credits. That's the "extra seat" add-on's purpose — priced at ₹149/seat on Pro, which means a 12-seat Pro team pays ₹2,499 + 2×₹149 = ₹2,797 vs. upgrading to Business at ₹6,799. Correct gap.


6. Yearly Pricing

Current: 17% discount. Industry standard is 15–20% for annual. 17% is fine but unmemorable. Consider "Save 2 months when billed yearly" (16.67% = ~17%) as marketing copy — mechanically identical, emotionally clearer.

No change to the math. Just the copy.


7. Upgrade / Downgrade Behavior (already implemented — for reference)

This doc doesn't change any of the following. Listed here so the user knows what's already handled:

  • Upgrade: Razorpay subscription creation → payment confirmation → immediate plan swap + credit dispense (prorated difference for mid-cycle).
  • Downgrade: Scheduled at current period end. User keeps current capacity + credits until then.
  • Cancel: Subscription ends at current period end. No refund for used portion.
  • Past-due: 4-stage escalation (day 1 / day 3 / final warning / imminent downgrade).
  • Trial: 14 days on paid tiers. No card up front (or with card — decision pending).

See docs/billing/SYSTEM-REFERENCE.md for the full state machine.


8. Open Questions (for Dipanshu to decide)

The following are genuine forks the doc can't resolve without a product call. Please answer each:

  1. Trial: card required?

    • Option A (current): Card required to start trial. Higher conversion from trial → paid, lower top-of-funnel.
    • Option B: No card on trial. Bigger top-of-funnel, more ghost accounts.
    • Recommendation: A (card required). Vlozi is a tool-of-record product, not a discovery product. Users who won't enter a card won't convert.
  2. Free plan seats: 1 or 2?

    • 1 forces teams to upgrade faster. 2 is friendlier.
    • Recommendation: 1 seat on Free. Teams means paid tier. Single-user Free is the honest persona.
  3. Storage: combined or split (blog/media)?

    • Recommendation: Combined in the UI, split internally (so the enforcement doesn't change, but customers see one number). Low-risk UI-only change.
  4. Multi-domain on Pro/Business?

    • Implementation exists (blog.custom_domain as a count, currently 1). Bumping Pro to 3 and Business to 10 — is this product-feasible? (Multi-tenant domain routing must support it.)
    • Action: Verify with DNS / routing layer before promising.
  5. Priority support — do we actually have the capacity?

    • A "priority email" claim requires someone to actually respond fast. Today that's you.
    • Recommendation: Keep for Pro/Business but define the SLA modestly ("response within 1 business day"). Don't claim what we can't deliver.
  6. Do Pro/Business get any credit rollover?

    • Current behavior: monthly subscription credits expire at period end (unused → forfeit). Permanent-bucket credits from packs don't expire.
    • Option A: Keep as-is. Simpler.
    • Option B: Roll over up to 1 month of unused subscription credits on Pro/Business. Marketing win but complicates expiry logic.
    • Recommendation: A (as-is) for v1. Ship rollover as a future Pro/Business perk if churn data demands it.
  7. Enterprise tier — placeholder now, or wait?

    • Showing "Enterprise — Contact Us" converts 0.1% of visitors into high-ACV leads. Low cost, nonzero upside.
    • Recommendation: Add a 5th "Enterprise — Contact us" card with no pricing, listing SSO / SLA / dedicated support as "coming soon / bespoke."

9. Implementation Checklist

If this proposal is accepted, the work breaks down as:

Backend (seed data + schema)

  • Update packages/core-database/src/seed.ts:
    • Free: seats 2 → 1
    • Pro: seats 15 → 10, api_keys 20 → 10
    • Pro: custom_domain 1 → 3 (verify DNS layer first)
    • Business: custom_domain 1 → 10 (same)
  • Run migration against staging, verify upgrade path doesn't break existing paying customers (grandfathering check).
  • Grandfathering decision: Existing Pro customers on 15 seats should keep 15. New Pro signups get 10. Implement via tenant_services overrides — do NOT rewrite their effective limits.

Frontend (billing page)

  • Remove "0 blog posts / 0 scheduled posts / 0 emails" rendering. Kill the feature entries entirely — they were never real capacity gates.
  • Add persona headline per card ("Solo creators & side projects" etc.).
  • Replace the single "X monthly credits" badge with a credits translation block (see §4.4 mockup).
  • Consolidate blog+media storage into one "Storage" line.
  • Add "Save 2 months" tooltip on yearly toggle.
  • (Optional) Add "Enterprise — Contact us" 5th card.

Copy / marketing

  • Write persona headlines + sub-copy per card.
  • Write 5 FAQ items that commonly come up: "what's a credit," "what happens when I run out," "can I buy more," "do credits roll over," "what if I need more seats."

Docs

  • Update docs/billing/SYSTEM-REFERENCE.md §Plans table with new seats/domains.
  • Ship a public /pricing FAQ page (landing site, not dashboard).

10. Not Doing (explicit scope cuts)

To keep this a focused project, the following are out of scope for this proposal:

  • Rewriting the credit-costs table. Costs (1 credit per email, 10 per post, etc.) are defensible and well-tested. No change.
  • Changing the core SMB price points. ₹999 / ₹2,499 / ₹6,799 are market-appropriate for the Indian SMB segment. Added ₹399 Basic for hobbyists.
  • Per-seat pricing instead of tiered. Vlozi isn't a seat-centric product (unlike Slack/Notion). Tiered is correct.
  • Currency expansion (USD/EUR). Deferred until international customers appear.
  • Usage-based billing ("pay as you go"). Credit packs already serve this need. No product call to add metered overage billing.
  • Enterprise features (SSO, audit logs, SLA). Roadmap for Q3/Q4. Listed in "Coming soon" Enterprise card only.

11. Success Metrics (how we'll know the redesign worked)

Track for 30 days post-launch vs. 30 days pre-launch:

  • Free → paid conversion rate. Expect ↑ 10-20% (persona clarity + credit translation reduces decision friction).
  • Starter → Pro upgrade rate. Expect ↑ 5-10% (clearer ladder).
  • Pricing page bounce rate. Expect ↓ 10% (no more confusing "0 blog posts").
  • Credit pack purchases. May ↓ slightly as users better self-select upgrade-worthy plans. Acceptable.
  • Support tickets asking "what does X credits mean?" Expect near-zero (translation table answers it).

Next Action

Dipanshu to:

  1. Answer the 7 open questions in §8.
  2. Approve / reject / modify the proposed plan matrix (§4.3).
  3. Confirm scope: is this UI-only, or do we bump plan limits in the same ship?

Once those are answered, I'll draft an implementation PR breaking this into 3–4 commits: (a) seed changes, (b) UI/copy rewrite, (c) docs update, (d) optional Enterprise card.

Billing