Saas pricing architect
Skill frobinson47/solo-dev-suite/skills/saas-pricing-architect
Designs a defensible SaaS pricing structure -- strategy (freemium/trial/paid), billing unit, tier count and content, psychological pricing, annual discounting, and launch vs steady-state pricing. Produces a versioned pricing model with change history and a rendered PRICING.md doc. Triggers on "design my pricing", "pricing strategy", "what should I charge", "tier structure", "iterate my pricing", "compare pricing", "am I pricing wrong". Part of the solo-dev-suite. Not for one-off "what's a fair price for X" questions (just answer those) or for non-SaaS monetization (ads, one-time sales, marketplaces).From its SKILL.md
npx -y skills add frobinson47/solo-dev-suite --skill saas-pricing-architectAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 4 stars4 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
12.0 KB, as published. Nobody here has run it
SaaS Pricing Architect
Designs and iterates on SaaS pricing with version history. Reads the project profile to anchor proposals, produces profile.pricing_model as the canonical active pricing, and renders PRICING.md as a developer reference.
When to use this skill
- User wants to design pricing for the first time (pre-launch scoping OR mid-build before wiring Stripe tier logic).
- User wants to iterate on existing pricing based on customer feedback, churn data, or competitive moves.
- User is wiring payment logic and needs a single source of truth to code against.
- Another suite skill (launch-readiness, sprint-planner) needs to confirm pricing is locked.
When NOT to use this skill
- Non-SaaS monetization -- ads, marketplace take-rates, one-time license sales, donation models. Different methodology entirely.
- B2B enterprise contracts with custom quotes -- this skill is for self-serve / low-touch SaaS. Enterprise pricing is a sales conversation, not a published table.
- "How much should a coffee cost" or other non-product pricing -- just answer inline.
- Project has
business_modelset tofree-self-hostedorinternal-onlyin the profile -- pricing doesn't apply.
Prerequisites
- Profile must exist with
business_modelin{saas-subscription, one-time-purchase, freemium, undecided}. target_userson the profile should be specific (vague "everyone" breaks tier design).- User should have at least 2 competitor price points in hand. The skill will ask if missing -- don't proceed without them.
Methodology
This skill bakes in the pricing frameworks that apply to solo / small SaaS:
The Five Decisions
Every pricing model is the product of five decisions. The skill walks them in this order because each downstream decision depends on the ones above:
- Value metric -- what unit scales with customer success? This is the single most consequential choice. Default: per-account (flat). Consider per-seat, per-active-user, per-usage (API calls, clients managed, transactions), or per-outcome (revenue share, deals closed).
- Strategy -- paid-only / free-trial / freemium. Default: free-trial for most solo SaaS. Freemium only if you can sustain the free user cost (infrastructure-lean) AND have a clear upgrade moment.
- Tier count -- 3 tiers is the sweet spot (ladder: Starter / Pro / Business). 2 tiers works for very simple products. 4+ creates choice paralysis and rarely earns the extra revenue.
- Anchor & ladder -- the highest tier sets the frame for the rest. Price the top tier at what a power user would reasonably pay, not what would feel cheap. Everything below reads as "value" relative to the anchor.
- Launch discount -- beta / early-adopter pricing. Common pattern: launch 30-40% below steady-state, grandfather early users at their price forever, raise prices for new signups after 60-90 days.
Value metric selection (the #1 mistake)
Default to per-account unless customer value genuinely scales with a specific unit. Common misfires:
- Per-seat on tools solo practitioners use alone (like my-project -- trainers work solo; seat-based undermonetizes).
- Per-user on tools where "user" means "customer of the customer" (charge per managed client, not per trainer).
- Usage metering on tools where usage is chunky/predictable (annoying UX, unpredictable bills).
Decision tree:
Does revenue value scale linearly with a specific unit the customer controls?
├-- YES -> that unit IS your value metric (usage, clients managed, transactions)
└-- NO -> flat per-account pricing is correct
Tier design patterns
For a 3-tier ladder, these shapes work 90% of the time:
- Ladder by limit (most common): same feature set, tiers cap usage. Good for metered value. Example: Starter 10 clients / Pro 50 / Business unlimited.
- Ladder by feature: tiers unlock features. Good when features cluster by customer maturity. Example: Starter (core) / Pro (+ messaging, progress tracking) / Business (+ team, white-label).
- Hybrid: limits + feature gates. Most realistic but hardest to communicate simply.
Annual discount
Default: 17% (≈2 months free on a monthly price). This is the near-universal anchor -- customers recognize it. Lower discounts feel cheap; higher discounts signal desperation.
Psychological pricing
- $X9 pricing: $29 reads cheaper than $30 despite the 3% difference. Use it at tier prices.
- Anchor-high ordering: list top tier first on pricing page (the "decoy effect"). The script produces PRICING.md in anchor-high order by default.
- Round annual prices: $290/year feels cleaner than $348/year. When possible, round the annual to a tidy number (even if the monthly × 10 math is slightly different from the stated discount).
Operations
1. Design (first-time)
Goal: Produce version 1 of the pricing model.
Workflow:
- Load the profile:
python <SUITE_DIR>/scripts/profile_io.py show <slug> --json - Sanity-check preconditions:
business_modelis SaaS-compatible.target_usersis specific (push back if vague).
- Ask for competitor price points -- minimum 2, ideally 3. Store them in the sidecar.
- Walk the Five Decisions conversationally. Propose a default for each based on profile + project_type heuristics; let the user override.
- For tiers, propose names/prices/features based on the ladder pattern chosen. Iterate until the user signs off.
- Persist:
The script writes the sidecar, mirrors the active summary toecho '<pricing_json>' | python scripts/pricing_tool.py design <slug> --from-stdinprofile.pricing_model, rendersPRICING.md, and updateslast_skill_run.
2. Show
python scripts/pricing_tool.py show <slug> [--version N] [--json]
Default shows the active version. Pass --version N to inspect a historical version.
3. Iterate
Goal: Create a new version based on customer feedback, competitive moves, or conversion data. Archive the previous version with its rationale intact.
Workflow:
- User describes the change and why.
- Load the current active version, construct the new one.
- Persist:
echo '<iteration_json>' | python scripts/pricing_tool.py iterate <slug> --from-stdin
The iteration payload must include a reason field. Like rescope in scope-guardian, this forces documented justification.
Legitimate iteration triggers:
- Conversion rate data (trial -> paid too low, or too high)
- Churn data reveals a tier shape problem
- Customer willingness-to-pay signals (people asking about features that don't exist in higher tiers)
- A real competitor move (not a vibes move)
Not legitimate:
- "I'm second-guessing myself"
- "It's been a week, maybe I should test a new price"
- "I saw a hot take on Twitter"
4. Render
python scripts/pricing_tool.py render <slug> [--output-dir <path>]
Re-generates PRICING.md from the sidecar. Default output location matches scope-guardian: <repo>/docs/ if reachable, else staging under the suite's profiles dir.
5. Delete
python scripts/pricing_tool.py delete <slug> [--yes]
Removes the sidecar and staged docs. Does NOT touch the profile -- profile.pricing_model stays until the user or another skill clears it. (We don't want deleting a pricing session to wipe the agreed-on tier data that Stripe code already references.)
Output: PRICING.md
Generated doc lives at <output_dir>/PRICING.md. Sections:
- Active Pricing -- big clean tier table, anchor-high order, monthly + annual, features and limits
- Billing Model -- strategy, billing unit, trial period if any, annual discount
- Competitive Anchors -- the price points collected during design
- Launch Pricing -- if current pricing is pre-launch / early-adopter, a note about when it goes to steady-state
- Version History -- links / summaries of prior versions with rationale
- Stripe Wiring Hints -- suggested product/price IDs, metadata keys (the developer reference part)
Sidecar data shape
Authoritative: templates/pricing.schema.json. Top-level keys:
schema_version(integer, currently 1)project_slugcreated_at/updated_atactive_version-- integer pointer intoversions[]competitors[]--{name, monthly_price_usd, notes}versions[]-- each entry is a full pricing snapshot (see below)change_log[]--{at, change, reason, from_version, to_version}entries on every iteration
Each entry in versions[]:
version-- monotonically increasing integercreated_at,active_until-- when this version was currentstrategy--paid-only | free-trial | freemiumtrial_days-- integer or nullbilling_unit--per-account | per-seat | per-usage | per-outcomevalue_metric-- free-form description of what scales with valuefree_tier-- optional tier object if strategy isfreemiumtiers[]-- ordered list of paid tiersannual_discount_percent-- integerlaunch_strategy--steady-state | early-adopter | betawith optional grandfather rulesrationale-- why this version exists
Each tier:
name(e.g. "Starter", "Pro", "Business")tagline-- one-line positioningmonthly_price_usd,annual_price_usdfeatures[]-- bullet listlimits-- object like{clients: 10, workouts_per_month: null}where null = unlimitedtarget_segment-- who this tier is for
Profile mirror
On every successful write, the skill mirrors a summary of the active version to profile.pricing_model:
{
"active_version": 2,
"strategy": "free-trial",
"billing_unit": "per-account",
"trial_days": 14,
"tier_summary": [
{"name": "Starter", "monthly_price_usd": 29, "annual_price_usd": 290},
{"name": "Pro", "monthly_price_usd": 49, "annual_price_usd": 490},
{"name": "Business", "monthly_price_usd": 99, "annual_price_usd": 990}
],
"annual_discount_percent": 17
}
This summary is what other skills (launch-readiness, sprint-planner, integration-mapper) consume. Full history stays in the sidecar.
Files
saas-pricing-architect/
├-- SKILL.md # this file
├-- scripts/
│ └-- pricing_tool.py # design / show / iterate / render / delete
└-- templates/
├-- pricing.schema.json # sidecar JSON Schema
└-- PRICING.md.tmpl # rendered doc template
Testing
# Uses the same test profile pattern as scope-guardian
echo '<profile_json>' | python <SUITE>/scripts/profile_io.py init --from-stdin
echo '{
"competitors": [{"name":"Trainerize","monthly_price_usd":24,"notes":"market leader"}],
"version": {
"strategy": "free-trial",
"trial_days": 14,
"billing_unit": "per-account",
"value_metric": "trainer accounts",
"tiers": [
{"name":"Starter","tagline":"Up to 10 clients","monthly_price_usd":29,"annual_price_usd":290,"features":["core"],"limits":{"clients":10},"target_segment":"new"},
{"name":"Pro","tagline":"Up to 50 clients","monthly_price_usd":49,"annual_price_usd":490,"features":["core","+messaging"],"limits":{"clients":50},"target_segment":"established"}
],
"annual_discount_percent": 17,
"launch_strategy": "early-adopter",
"rationale": "Test"
}
}' | python scripts/pricing_tool.py design <slug> --from-stdin
python scripts/pricing_tool.py show <slug>
python scripts/pricing_tool.py render <slug>
python scripts/pricing_tool.py delete <slug> --yes