Skip to content

Free Claude skill · Fundraising · v1.0

Pitch deck review skill for Claude

Share your pitch deck and Claude reads it the way an investor would: slide by slide, against the twelve sections most decks need. It rebuilds your TAM, SAM and SOM from customer counts and prices, checks growth claims, runway and use of funds with a bundled script, and returns a scorecard, the five fixes that matter most and the questions investors are likely to ask.

By the StartupReader editorial desk · Updated 2026-11-08 · MIT licence · Works on claude.ai, Claude Code and the Claude API

At a glance2026

Pitch deck review

sections it checks
12
calculations it runs
3
network calls
0
MIT licence
Free
Pitch deck review at a glance: sections it checks: 12; calculations it runs: 3; network calls: 0; MIT licence: Free.

What it does

  • Maps every slide to a standard structure, from problem and why now to the ask and use of funds, and lists the sections the deck leaves out.
  • Rebuilds TAM, SAM and SOM bottom-up from your customer counts and prices, and compares them with the figures on the market slide.
  • Builds a ledger of every number in the deck and flags figures that disagree between slides or lack a definition, period or date.
  • Recomputes growth claims, runway from the raise and the burn plan, the use of funds total and the stake sold, with a small bundled script.
  • Rates each slide Strong, Needs work, Weak or Missing against what investors look for at your stage.
  • Lists the five fixes that matter most, the superlatives to back up or cut, and the questions investors are likely to ask.

Ask Claude things like

  • “Review my seed deck before I send it to investors.”
  • “Is our TAM slide credible? We quote one big industry figure.”
  • “Here's our pre-seed deck. What's missing?”
  • “Does our ask slide add up? We say the round gives us 24 months.”

What you give it

  • The deck as a PDF, a PowerPoint file or slide images. The appendix and speaker notes help.
  • Your stage and round size, if the deck doesn't say.
  • For the market check: customer counts per segment and what each customer pays, with sources, if they aren't on the slides.
  • For the runway check: cash in the bank today and your planned monthly burn after the round, including planned hires.

What you get back

  • A scorecard with a rating, what works and what to fix for every slide.
  • The five fixes that matter most, most important first.
  • A table of numbers that don't agree, with the check that shows it.
  • Missing slides, words to back up or cut, and the questions investors are likely to ask.

Why it rebuilds your market size from the bottom up

A top-down market slide takes a large industry total and claims a slice of it. It says nothing about who will buy. A bottom-up build starts from customers: count the customers in each segment and multiply by what each pays a year, and you have the total addressable market (TAM). The part your product and sales channels can reach today is the serviceable addressable market (SAM), and the share you can realistically win in the near term is the serviceable obtainable market (SOM). Investors trust bottom-up estimates more than top-down ones, so the skill rebuilds the market from your own counts and prices and shows both figures side by side.

It then uses the market as a check on the rest of the deck. The revenue in the last year of your plan should fit inside the SOM, and the number of customers that revenue needs should match what the go-to-market slide can deliver. In the example below, a year-three target needs 1,654 customers when the SOM holds 645. The skill never supplies market data of its own: if the deck has no customer counts, getting them becomes the first fix.

How it checks that the numbers agree

Before rating anything, Claude lists every figure in the deck with its slide, what it measures, its period and its date. That ledger catches the problems a slide-by-slide read misses: a customer count on the summary slide that differs from the traction slide, "users" that might mean sign-ups or paying accounts, or ARR that turns out to be one month's total revenue times twelve, which isn't ARR at all.

The arithmetic goes to a small Python script rather than Claude's head. It recomputes the compound growth between your first and last data points and compares it with the rate the deck claims, works out runway from the raise, the cash in the bank and a burn plan that can step up as you hire, checks that the use of funds adds up to the raise, and shows the stake a priced round sells. Every figure in the review has to appear in the deck or the script's output.

What it expects at each stage

The same deck can be strong at one stage and weak at another, so the skill notes the stage first and rates against it. At pre-seed, investors are backing the founders and the problem, and a clear plan for what the money will prove matters more than a detailed five-year forecast. At seed, they look for users or revenue growing without heavy pushing. At Series A, they look for a working sales or growth engine and solid unit economics, such as an LTV:CAC ratio and payback period built from gross profit and full acquisition costs.

The ask is checked against the same standards: rounds are usually sized to last 18 to 24 months, and priced rounds commonly sell 10% to 25% of the company. A deck that falls outside those ranges isn't wrong, but it should say why.

  • Strong: shows everything the section needs, with evidence, and agrees with the rest of the deck.
  • Needs work: the right content, but a number lacks a definition, period or source.
  • Weak: the core element is absent, unsupported or contradicts another slide.
  • Missing: no slide covers the section.

Worked example

Molarly, a made-up clinic software startup, is raising a $1.5M seed round at a $6M pre-money valuation. Its deck quotes a top-down $4.2B TAM, says MRR grew from $8,000 to $30,000 over nine months with "40% month-on-month growth", plans $2.4M of revenue in year three, and promises 24 months of runway. It has $100,000 in the bank and plans to burn $60,000 a month for six months, then $85,000 once it hires. Its own research counts 40,000 independent clinics paying $1,200 a year, half of them reachable today, and 6,000 group practices paying $4,800, a quarter reachable, and it assumes it can win 3% of what it can reach. There is no why-now or competition slide. All figures are invented.

The founder asks

Here's the Molarly seed deck (attached). Be honest: is it ready to send to investors?

Claude reads the skill, then runs its script with the figures from the documents. These are the script's real outputs:

$ python scripts/market_size.py market --segment "Independent clinics" 40000 1200 50% --segment "Group practices" 6000 4800 25% --som-share 3% --claimed-tam 4200000000 --revenue-target 2400000
Bottom-up market size (annual revenue; price per customer per year)  Segment                Customers   Price/yr             TAM   Reach             SAM  Independent clinics       40,000      1,200      48,000,000     50%      24,000,000  Group practices            6,000      4,800      28,800,000     25%       7,200,000  TAM  every customer in every segment       76,800,000  (46,000 customers)  SAM  the part the product can reach        31,200,000  (21,500 customers)  SOM  3.0% of SAM                              936,000  (645 customers)  Deck's TAM 4,200,000,000 is 54.7x the bottom-up TAM.  Revenue target 2,400,000: 7.7% of SAM, 2.56x the SOM.  At the average serviceable price (1,451) that is 1,654 customers.
$ python scripts/market_size.py growth --start 8000 --end 30000 --periods 9 --per month --claimed-rate 40%
Growth from 8,000 to 30,000 over 9 months: 3.75x  Compound growth: 15.8% a month  (equivalent to 482.6% a year)  Deck claims 40.0% a month: 9 months at that rate would turn 8,000 into 165,288, not 30,000.
$ python scripts/market_size.py runway --raise 1500000 --cash 100000 --burn 60000:6,85000 --claimed-months 24 --pre-money 6000000 --use "Product and engineering" 45% --use "Sales and marketing" 35% --use "Operations" 20%
Runway: raise 1,500,000 + cash in the bank 100,000 = 1,600,000  Net burn 60,000 a month, months 0 to 6  Net burn 85,000 a month, from month 6  Runway: 20.6 months  Rounds are usually sized to last 18 to 24 months; this is within that range.  Start preparing the next round by month 8.6 (12 months of runway left).  Deck claims 24 months: the burn plan is 3.4 months short of that.  Pre-money 6,000,000 + raise = post-money 7,500,000; new investors own 20.0%.  Priced rounds commonly sell 10% to 25%; this is within that range.  Use of funds                   Amount   Share  Product and engineering       675,000   45.0%  Sales and marketing           525,000   35.0%  Operations                    300,000   20.0%  Total                       1,500,000  100.0%  adds up to the raise

The answer, in the skill's format (abridged):

Pitch deck review: Molarly, seed, raising $1.5M

The verdict

The traction is real for a seed deck: MRR grew 3.75x in nine months. But three numbers don't survive a check: the market, the growth rate and the runway. Fix those before the deck goes to anyone.

Scorecard (excerpt)

# Slide Rating What to fix
4 Market Weak Replace the top-down $4.2B with the bottom-up build: TAM $76.8M, SAM $31.2M, SOM $936,000
6 Traction Needs work "40% month-on-month" doesn't match $8,000 to $30,000 in nine months, which is 15.8% a month
11 Financials Weak Year-three revenue of $2.4M is 2.56x the SOM and needs 1,654 customers
12 The ask Needs work Use of funds adds up, but the burn plan gives 20.6 months, not 24

Five fixes that matter most (excerpt)

  1. Market: lead with the bottom-up build and the source of each clinic count. The $4.2B is 54.7x the bottom-up TAM.
  2. Financials: show how the plan reaches 1,654 customers, or cut the target to fit a SOM of 645 customers.
  3. Traction: say 15.8% compound monthly growth, or name the month that grew 40%.
  4. The ask: claim 20.6 months, or show the cuts that reach 24, and plan to start the next raise by month 8.6.

Missing slides

Why now and competition. Both matter at seed: investors will ask what changed and who you lose deals to.

Questions investors will ask

  1. Where do the 40,000 and 6,000 clinic counts come from? (slide 4)
  2. What stops you reaching the other half of independent clinics today? (slide 4)
  3. Which month grew 40%, and what is monthly churn? (slide 6)
  4. What will be true when this money runs out that makes the next round possible? (slide 12)

A made-up company and numbers. Your answer depends on your documents, and Claude's wording varies from run to run; the figures come from the script.

Install it

The skill is one folder. Download it once and add it wherever you use Claude; skills don't sync between claude.ai, Claude Code and the API, so each needs its own copy.

claude.ai and the Claude apps

  1. Download the ZIP and keep it zipped.
  2. In Claude, open Settings > Capabilities and turn on Code execution and file creation (called Create and edit files in the newer settings layout).
  3. Open Customize > Skills, click +, choose Create skill, then Upload a skill, and pick the ZIP.
  4. Leave the skill switched on. Claude uses it when your request matches its description; you don't have to name it.

On Team and Enterprise plans an owner first turns on code execution and skills under Organization settings > Plugins & skills. Anthropic's help centre has the details for each plan.

Claude Code

Unzip it into your personal skills folder to use it in every project, or into .claude/skills/ in a repository to share it with your team. Claude picks it up automatically; you can also run it by typing /pitch-deck-review.

Terminal
mkdir -p ~/.claude/skills
unzip pitch-deck-review.zip -d ~/.claude/skills/

Skills with a script need Python 3 on your computer.

Claude API

Upload the unzipped folder once; the response includes the skill's id. Uploaded skills are shared across your API workspace.

Terminal
curl -X POST "https://api.anthropic.com/v1/skills" \
  -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "anthropic-version: 2026-10-21" \
  -F "files[]=@pitch-deck-review/SKILL.md;filename=pitch-deck-review/SKILL.md" \
  -F "files[]=@pitch-deck-review/references/slide-checklist.md;filename=pitch-deck-review/references/slide-checklist.md" \
  -F "files[]=@pitch-deck-review/scripts/market_size.py;filename=pitch-deck-review/scripts/market_size.py"

Then list it in a request's container, with the code execution tool that skills run in (up to 20 skills per request):

Terminal
curl https://api.anthropic.com/v1/messages \
  -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "anthropic-version: 2026-10-21" \
  -H "content-type: application/json" \
  -d '{
    "model": "claude-opus-5-5",
    "max_tokens": 4096,
    "container": {
      "skills": [{ "type": "custom", "skill_id": "YOUR_SKILL_ID", "version": "latest" }]
    },
    "tools": [{ "type": "code_execution_20250825", "name": "code_execution" }],
    "messages": [{ "role": "user", "content": "..." }]
  }'

From Anthropic's skills API guide. Skills on the API run with no network access, which is why these skills' scripts use only Python's standard library.

What's in the skill

Every file, exactly as it is in the download. Claude reads SKILL.md when a request matches, opens the other files only when a step needs them, and runs scripts without loading their code. Read them before you install: a skill can direct Claude to run code, so only add skills you trust.

Folder
pitch-deck-review/
  SKILL.md
  references/slide-checklist.md
  scripts/market_size.py
SKILL.md119 lines
---
name: pitch-deck-review
description: Reviews a startup's investor pitch deck slide by slide against the standard structure (problem, solution, why now, market, product, traction, business model, competition, go-to-market, team, financials, the ask and use of funds). Rebuilds TAM, SAM and SOM bottom-up from customer counts and prices, checks that numbers agree across slides, that traction claims say what they measure and over what period, that the runway claim matches the burn plan and that the deck fits its stage, and flags unsupported superlatives. Returns a scorecard per slide, the five fixes that matter most, missing slides and the questions investors will ask. Use when a founder shares a pitch deck, investor deck, fundraising deck or slides (PDF, PPTX or images), or asks for deck feedback, a market size or TAM/SAM/SOM check, a traction slide review, use of funds, runway, or whether a deck is ready before a pre-seed, seed or Series A raise.
license: MIT
compatibility: Works on claude.ai, Claude Code and the Claude API. The script needs Python 3.8+ (standard library only) and no network access.
metadata:
  author: StartupReader
  version: "1.0"
  homepage: https://startupreader.com/claude-skills/pitch-deck-review
---

# Pitch deck review

Read the deck the way an investor would on a first pass, then show the founders exactly what to fix. Judge substance, not design: mention layout only where it hides a number or a point.

## Workflow

Copy this checklist and tick it off as you go:

```
- [ ] 1. Map every slide to the twelve sections; note stage, amount and instrument
- [ ] 2. Build the number ledger and find conflicts
- [ ] 3. Run the checks with scripts/market_size.py
- [ ] 4. Rate every slide using references/slide-checklist.md
- [ ] 5. Write the review in the output format below
- [ ] 6. Check every figure against the deck and the script output
```

### 1. Map the deck

Read every slide before judging any, including the appendix and speaker notes. Text inside charts, tables and screenshots counts. If a file cannot be read, ask for a PDF export rather than guessing.

Map each slide to one of the twelve sections: problem, solution, why now, market, product, traction, business model, competition, go-to-market, team, financials, the ask and use of funds. A slide can cover two sections and a section can span several slides. Sections with no slide are **Missing**.

Record: company, stage (pre-seed, seed, Series A; if not stated, infer it from the ask and the traction and say so), amount, instrument, and any valuation or cap the deck states.

### 2. Build the number ledger

List every figure: value, slide, what it measures, period or as-of date, and source. Then look for:

- **Conflicts**: the same metric with different values on different slides (summary versus traction, ask versus use of funds).
- **Undefined metrics**: users (signed up, active or paying?), revenue (recognised, GMV, bookings or recurring?), ARR (run-rate or contracted, or one month's total revenue x 12?), customers (paying, pilots or letters of intent?). Mark each as "not defined" rather than assuming.
- **Missing periods**: a total or a growth rate with no time window or date.
- **Cross-slide links**: price x customers against stated revenue, projected revenue against the SOM, the number of customers the plan needs against the go-to-market plan, the claimed runway against the burn plan.

### 3. Run the checks

Run the script instead of doing the arithmetic in your head:

```bash
# Bottom-up market: one --segment per customer group: NAME CUSTOMERS PRICE_PER_YEAR [SERVICEABLE_SHARE]
python scripts/market_size.py market --segment "Independent clinics" 40000 1200 50% --segment "Group practices" 6000 4800 25% --som-share 3% --claimed-tam 4200000000 --revenue-target 2400000

# Runway and use of funds: net burn by phase as AMOUNT:MONTHS, last phase open-ended
python scripts/market_size.py runway --raise 1500000 --cash 100000 --burn 60000:6,85000 --claimed-months 24 --pre-money 6000000 --use "Product and engineering" 45% --use "Sales and marketing" 35% --use "Operations" 20%

# A growth claim, from the deck's own first and last data points
python scripts/market_size.py growth --start 8000 --end 30000 --periods 9 --per month --claimed-rate 40%
```

- **Market**: counts, prices and shares come from the deck or the founders, never from you. If the deck quotes only a top-down figure, ask for customer counts and prices; if there are none, make the bottom-up rebuild a top fix instead of inventing counts. Use `--monthly` when prices are monthly. `SERVICEABLE_SHARE` is the part of a segment the product and channels reach today (language, geography, product fit, channel). Pass the deck's own TAM, SAM or SOM with `--claimed-tam`, `--claimed-sam`, `--claimed-som`, and the revenue in the last year of its plan with `--revenue-target`.
- **Runway**: `--burn` is planned net burn (spending minus revenue) after the round. Use phases when the plan hires: `60000:6,85000` means 60,000 a month for six months, then 85,000. `--cash` is cash in the bank only, not money promised. Pass `--pre-money` only for a priced round with a stated pre-money.
- **Growth**: `--periods` counts intervals between the two data points (January to October is 9 months). Use it for every stated growth rate.
- For any other sum, such as price x customers, run a one-line `python -c "print(...)"` rather than estimating.
- If a script exits with an error, fix the input it names and run it again.

### 4. Rate each slide

Read [references/slide-checklist.md](references/slide-checklist.md) for what each section must show, what makes it weak, the stage expectations and the words to flag. Use exactly four ratings: **Strong**, **Needs work**, **Weak**, **Missing**.

Two things change a rating:
- **Stage.** A pre-seed deck with thin financials can still be Strong; one with no evidence of demand or no clear ask cannot. A Series A deck without unit economics is Weak on business model.
- **Consistency.** A slide that is fine alone becomes Weak if it contradicts another, for example a revenue plan larger than the SOM or a runway claim the burn plan does not support.

### 5. Output format

```markdown
# Pitch deck review: [Company], [stage], raising [amount]

## The verdict
Two or three sentences: what the deck does well, the biggest problem, and whether it fits the stage.

## Scorecard
| # | Slide | Section | Rating | What works | What to fix |
|---|---|---|---|---|---|

## Five fixes that matter most
Numbered, most important first. Each: the slide, the fix, and why an investor cares.

## Numbers that don't agree
| Figure | Slide | Conflicts with | What the check shows |
|---|---|---|---|

## Missing slides
Each missing section, and whether this stage needs it.

## Words to back up or cut
Quoted phrase, slide, and the evidence that would replace it.

## Questions investors will ask
Numbered, specific to this deck, each with the slide that prompts it.
```

Keep the five fixes to five even when there are more problems; put the rest in the scorecard.

### 6. Check before sending

- Every figure in the review appears in the deck or in the script output.
- Every Weak or Missing rating says what is absent.
- No market sizes, competitor names, benchmarks or statistics that are not in the deck or in references/slide-checklist.md.
- Fixes say what to show, not just "add more detail".

## Rules

- Review the deck, not the founders' chances: never predict whether the round will close or name investors to approach.
- Do not add facts about the market or competitors from memory. Ask for the source instead.
- Quote the deck when flagging a claim, with its slide number.
- Do not rewrite the whole deck unless asked. A sample headline for a weak slide is fine.
references/slide-checklist.md118 lines
# Slide checklist: what each slide must show

## Contents
- How to rate
- Stage expectations
- The twelve sections: problem, solution, why now, market, product, traction, business model, competition, go-to-market, team, financials, the ask and use of funds
- Words to flag

## How to rate

Rate each slide against the section it covers, with one of:

- **Strong**: shows everything in "Must show" for its section, with evidence, and agrees with the rest of the deck.
- **Needs work**: the right content, but a number lacks a definition, period, date or source, or the point is buried.
- **Weak**: the core element is absent, a claim has no support, or a number contradicts another slide.
- **Missing**: no slide covers the section. Say whether the stage makes it essential.

Rate what is on the slide, not how good the business is. A slow-growing company with an honest, well-defined traction slide rates Strong on that slide.

## Stage expectations

From StartupReader's funding stage explainers. Labels vary between investors and countries, so if the deck does not state its stage, infer it from the ask and the traction and say so.

| Stage | What the round pays for | What investors look for | What the deck needs most |
|---|---|---|---|
| Pre-seed | Turning an idea into a first product | The founders, the problem, early signs of demand | Why this team, how painful the problem is, any evidence of demand (waitlist, design partners, pilot customers, engagement with a prototype), and what the money will prove and by when |
| Seed | Finding product-market fit | Users or revenue growing without heavy pushing | Defined traction with periods, retention or repeat use, early unit economics |
| Series A | Building a repeatable way to grow | A working sales or growth engine and solid unit economics | Channel-level acquisition cost, LTV:CAC and payback, cohorts, a plan that shows what more money does to growth |

At pre-seed, a clear plan for what the money will prove matters more than a detailed five-year forecast. Do not mark a pre-seed deck down for thin financials; do mark it down for an unclear ask or no evidence of demand.

## The twelve sections

### 1. Problem
- Must show: a specific customer (not "everyone" or "businesses"), what the problem costs them in money, time or risk, how often it happens, and how they deal with it today.
- Weak if: the problem is stated as the absence of the product ("there is no app for X"); no evidence beyond the founders' view, such as interviews, data or a customer quote.
- Investors ask: How do they solve it today, and what does that cost them? How many people have you spoken to who have this problem?

### 2. Solution
- Must show: what the product does for that customer, in one sentence, and the outcome compared with today's alternative.
- Weak if: a list of features with no outcome; jargon that a generalist investor would not follow.
- Investors ask: Why will customers switch from what they do today?

### 3. Why now
- Must show: what changed (technology, regulation, cost, behaviour, distribution) that makes this possible or necessary now and not five years ago.
- Weak if: only "the market is growing" or a market growth rate with no change behind it.
- Investors ask: What stops an incumbent doing this now that it is possible?

### 4. Market
- Must show: a bottom-up build. Customer segments, a count of customers in each with its source, the price each would pay a year, and which part the product and channels can reach today. TAM, SAM and SOM labelled correctly:
  - TAM: the whole demand for the product category (every customer in every segment, times price).
  - SAM: the part the company's product and channels can serve.
  - SOM: the share it can realistically win in the near term.
- Weak if: only a top-down figure (an industry report total, or "1% of a huge market"); no source or year; TAM labelled as SAM; a SOM the revenue plan does not fit inside. Investors trust bottom-up estimates more than top-down ones.
- Run `market` in scripts/market_size.py with the deck's own counts and prices. If the deck gives no counts, do not supply your own: list the rebuild as a fix and ask the founders for the counts.
- Investors ask: Where does the customer count come from? Who pays, and how much a year? Why that share of SAM?

### 5. Product
- Must show: what it looks like and how it works (screenshots or a demo link), what is live today and what is still planned.
- Weak if: mock-ups presented as a live product without saying so; a roadmap with no timing or no link to the raise.
- Investors ask: What is built, what is next, and what does this round pay to build?

### 6. Traction
- Must show: each metric defined, with the period and an as-of date. Growth shown with start and end values. Retention or repeat use where the stage allows.
- Definitions to check:
  - Users: signed up, active (in what window) or paying.
  - Revenue: recognised revenue, GMV, bookings, or recurring revenue. MRR and ARR count only recurring fees from active customers; one-off setup and services fees and unpaid pilots are excluded.
  - ARR: run-rate ARR (current MRR x 12) or contracted ARR (signed recurring contracts, including some not yet live). "Revenue run-rate" built from one month's total revenue x 12, including one-off fees or a seasonal peak, is not ARR.
  - Customers and logos: paying customers, paid pilots, unpaid pilots or letters of intent. Logos on a slide should say which.
- Weak if: a cumulative chart with no label (a cumulative total can only rise); sign-ups or downloads with no activity measure; a growth rate with no period; "40% growth" without saying month on month, year on year or best month.
- Run `growth` with the deck's own first and last data points to check any stated growth rate.
- Investors ask: What does an active user mean here? How many of these customers pay, and how many renewed?

### 7. Business model
- Must show: who pays, how much and how often; gross margin if known. From seed onward, unit economics with their definitions:
  - CAC: all sales and marketing spend (including salaries, tools and agencies) divided by new customers won in the same period.
  - LTV: average monthly revenue per customer x gross margin / monthly churn rate. It uses gross profit, not revenue.
  - CAC payback: CAC / (monthly revenue per customer x gross margin).
  - A common rule of thumb for subscription businesses is LTV:CAC of at least 3:1 and payback within about 12 to 18 months. Treat these as guides, not pass marks: early cohorts are small and churn estimates are noisy.
  - For marketplaces, consumer brands and delivery businesses, contribution margin per order (after product cost, payment fees, delivery, discounts and returns) often matters more.
- Weak if: price not stated; LTV built on revenue; churn extrapolated from a few months as if customers stay for years; one blended CAC hiding channels.
- Investors ask: What does it cost to win a customer, by channel, and how long until they pay it back?

### 8. Competition
- Must show: the alternatives customers use today, including spreadsheets, manual work, an in-house build or doing nothing; how the company compares on what customers care about; why it wins and how it keeps winning.
- Weak if: "no competitors" or "no direct competition"; a two-by-two chart with axes chosen so only the company sits in the best corner; an obvious alternative left out.
- Investors ask: Who do you lose deals to, and why?

### 9. Go-to-market
- Must show: how the company reaches its first and next customers (channels, sales motion, sales cycle), what that costs, and evidence that at least one channel works.
- Weak if: channels listed with no evidence or cost ("viral", "partnerships", "social media"); the plan cannot produce the number of customers the financials need. The `market` run with `--revenue-target` gives that number.
- Investors ask: Which channel brought your last ten customers? What will the next 100 cost?

### 10. Team
- Must show: who does what, who is full-time, and why this team is suited to this problem (relevant experience, customer access, technical depth). Key hires the round pays for.
- Weak if: advisers outnumber the team; roles unclear; a gap the plan depends on (for example, nobody who has sold to this customer) is not addressed.
- Investors ask: Why are you the people to build this? Who do you hire first with this money?

### 11. Financials
- Must show: historical figures kept apart from projections; the assumptions behind the projections (customers, price, churn, hiring); burn and runway.
- Weak if: a revenue curve with no assumptions; projected revenue larger than the SOM; customer numbers the go-to-market plan cannot reach; a growth rate that does not match the traction slide; a break-even date that contradicts the burn plan.
- At pre-seed, a short plan for what the money proves is enough.
- Investors ask: Which assumption, if wrong, changes the plan most?

### 12. The ask and use of funds
- Must show: the amount, the instrument (priced equity, SAFE, convertible note; in India usually CCPS for priced rounds, or CCDs or convertible notes), the valuation or cap if the founders choose to state it, how long the money lasts, the milestone it reaches, and a use of funds that adds up to the raise.
- Checks, using `runway` in scripts/market_size.py:
  - Runway from the raise plus cash in the bank and the planned net burn. Rounds are usually sized to last 18 to 24 months, because a raise itself can take three to six months; the next round should be in preparation with about a year of runway left.
  - Any runway the deck claims, against the burn plan.
  - Use of funds adds up to the raise (percentages to 100%).
  - For a priced round with a stated pre-money, the stake sold. Priced rounds commonly sell 10% to 25% of the company; pre-seed rounds often sell 10% to 20% in total.
- Weak if: no amount; no milestone; use of funds does not add up; claimed runway does not match the burn plan.
- Investors ask: What will be true when this money runs out that makes the next round possible?

## Words to flag

Flag these when the deck gives no number or source to back them: first, only, leading, largest, best, unique, revolutionary, disruptive, world-class, unmatched, guaranteed, massive, huge, explosive, no competition, no competitors. Quote the phrase, give the slide, and suggest the evidence that would replace it (a metric, a customer quote, a source). Do not flag the same word when it is backed: "the only supplier certified for X (certificate on slide 14)" is fine.
scripts/market_size.py344 lines
#!/usr/bin/env python3
"""Pitch deck arithmetic: bottom-up market size, runway and use of funds, growth.

Standard library only, so it runs in the Claude API sandbox (no network, no
package installs), on claude.ai and in Claude Code.

Usage:
  python scripts/market_size.py market \
      --segment "Independent clinics" 40000 1200 50% \
      --segment "Group practices" 6000 4800 25% \
      --som-share 3% [--monthly] [--claimed-tam 4200000000] \
      [--claimed-sam N] [--claimed-som N] [--revenue-target 2400000]
  python scripts/market_size.py runway --raise 1500000 --burn 60000:6,85000 \
      [--cash 100000] [--claimed-months 24] [--pre-money 6000000] \
      [--use "Product and engineering" 45% --use "Sales and marketing" 35% ...]
  python scripts/market_size.py growth --start 8000 --end 30000 --periods 9 \
      [--per month|quarter|year] [--claimed-rate 40%]

market: each --segment is NAME CUSTOMERS PRICE [SERVICEABLE]. PRICE is revenue
per customer per year (per month with --monthly). SERVICEABLE is the share of
those customers the product and sales channels can reach today (default 100%).
TAM = customers x price over all segments; SAM = the serviceable part;
SOM = --som-share of SAM, the part the company can win in the plan period.

runway: --burn is planned monthly net burn (spending minus revenue) after the
round, as AMOUNT or phases AMOUNT:MONTHS,...,AMOUNT. The last phase has no
month count: it runs until the cash is gone. --use values are all amounts or
all percentages of the raise.

Shares and rates take a fraction (0.03) or a percentage (3%); write a negative
rate as --claimed-rate=-5%. Amounts are in one currency unit and may use commas. The results check a deck's arithmetic;
they are not a forecast.
"""
import argparse
import math
import sys

MONTHS_PER_YEAR = 12
PERIODS_PER_YEAR = {"month": 12, "quarter": 4, "year": 1}
# StartupReader's startup-funding-stages explainer: rounds are usually sized to
# last 18 to 24 months, and the next round should be prepared with about a
# year of runway left, because a raise itself takes three to six months.
USUAL_RUNWAY_MONTHS = (18, 24)
NEXT_RAISE_LEAD_MONTHS = 12
# Same explainer: each priced round commonly sells 10% to 25% of the company.
USUAL_ROUND_STAKE = (0.10, 0.25)
# Use-of-funds lines within half a percentage point of the raise count as adding up
# (decks round each line to a whole percentage).
ROUNDING_TOLERANCE = 0.005


def fail(message):
    print(f"Error: {message}", file=sys.stderr)
    sys.exit(2)


def money(x):
    return f"{x:,.0f}"


def pct(x):
    return f"{x * 100:.1f}%"


def number(text, what):
    try:
        value = float(str(text).replace(",", "").replace("_", "").strip())
    except ValueError:
        fail(f"{what} must be a number, got {text!r}")
    if not math.isfinite(value):
        fail(f"{what} must be a finite number, got {text!r}")
    return value


def share(text, what):
    """A fraction (0.03) or a percentage (3%). Without a % sign, values above 1
    are ambiguous (is 5 meant as 5% or 500%?), so they are refused."""
    raw = str(text).strip()
    if raw.endswith("%"):
        return number(raw[:-1], what) / 100
    value = number(raw, what)
    if value > 1:
        fail(f"{what} must be a fraction like 0.05 or a percentage like 5%, got {text!r}")
    return value


def periods_text(n, unit):
    return f"{n:g} {unit}" + ("" if n == 1 else "s")


def optional_positive(value, flag):
    if value is None:
        return None
    result = number(value, flag)
    if result <= 0:
        fail(f"{flag} must be positive")
    return result


def market(args):
    if not args.segment:
        fail("give at least one --segment NAME CUSTOMERS PRICE [SERVICEABLE]")
    rows = []
    for seg in args.segment:
        if len(seg) not in (3, 4):
            fail(f"--segment needs NAME CUSTOMERS PRICE [SERVICEABLE], got {len(seg)} values: {' '.join(seg)}")
        name = seg[0].strip()
        if not name:
            fail("--segment NAME is empty")
        count = number(seg[1], f"customers for {name!r}")
        price = number(seg[2], f"price for {name!r}")
        reach = share(seg[3], f"serviceable share for {name!r}") if len(seg) == 4 else 1.0
        if count <= 0 or price <= 0:
            fail(f"customers and price for {name!r} must be positive")
        if not 0 < reach <= 1:
            fail(f"serviceable share for {name!r} must be above 0 and at most 100%")
        if args.monthly:
            price *= MONTHS_PER_YEAR
        rows.append((name, count, price, reach))
    som_share = None
    if args.som_share is not None:
        som_share = share(args.som_share, "--som-share")
        if not 0 < som_share <= 1:
            fail("--som-share must be above 0 and at most 100%")
    claimed_tam = optional_positive(args.claimed_tam, "--claimed-tam")
    claimed_sam = optional_positive(args.claimed_sam, "--claimed-sam")
    claimed_som = optional_positive(args.claimed_som, "--claimed-som")
    target = optional_positive(args.revenue_target, "--revenue-target")

    tam = sum(c * p for _, c, p, _ in rows)
    sam = sum(c * p * r for _, c, p, r in rows)
    customers = sum(c for _, c, _, _ in rows)
    reachable = sum(c * r for _, c, _, r in rows)
    width = max(len("Segment"), *(len(n) for n, _, _, _ in rows))

    print("Bottom-up market size (annual revenue; price per customer per year)")
    print(f"  {'Segment':<{width}}  {'Customers':>11}  {'Price/yr':>9}  {'TAM':>14}  {'Reach':>6}  {'SAM':>14}")
    for name, count, price, reach in rows:
        print(f"  {name:<{width}}  {money(count):>11}  {money(price):>9}  {money(count * price):>14}"
              f"  {reach * 100:>5.0f}%  {money(count * price * reach):>14}")
    summary = [("TAM", "every customer in every segment", tam, customers),
               ("SAM", "the part the product can reach", sam, reachable)]
    if som_share is not None:
        summary.append(("SOM", f"{pct(som_share)} of SAM", sam * som_share, reachable * som_share))
    for label, what, value, count in summary:
        print(f"  {label}  {what:<32}  {money(value):>14}  ({money(count)} customers)")
    if claimed_tam:
        print(f"  Deck's TAM {money(claimed_tam)} is {claimed_tam / tam:,.1f}x the bottom-up TAM.")
    if claimed_sam:
        print(f"  Deck's SAM {money(claimed_sam)} is {claimed_sam / sam:,.1f}x the bottom-up SAM.")
    if claimed_som:
        print(f"  Deck's SOM {money(claimed_som)} is {pct(claimed_som / sam)} of the bottom-up SAM.")
    if target:
        line = f"  Revenue target {money(target)}: {pct(target / sam)} of SAM"
        if som_share is not None:
            line += f", {target / (sam * som_share):,.2f}x the SOM"
        print(line + ".")
        avg_price = sam / reachable
        print(f"  At the average serviceable price ({money(avg_price)}) that is {money(target / avg_price)} customers.")


def parse_burn(text):
    phases = []
    parts = [p.strip() for p in str(text).split(",") if p.strip()]
    if not parts:
        fail("--burn is empty: give a monthly amount, e.g. 60000, or phases, e.g. 60000:6,85000")
    for i, part in enumerate(parts):
        amount_text, _, months_text = part.partition(":")
        amount = number(amount_text, "--burn amount")
        if i == len(parts) - 1:
            if months_text:
                fail("--burn: leave the month count off the last phase (it runs until the cash is gone), e.g. 60000:6,85000")
            phases.append((amount, None))
            continue
        if not months_text:
            fail(f"--burn: phase {part!r} needs a month count, e.g. 60000:6 (commas separate phases, so write 60000 not 60,000)")
        months = number(months_text, "--burn months")
        if months <= 0:
            fail(f"--burn: months in {part!r} must be positive")
        phases.append((amount, months))
    return phases


def where(value, low, high):
    return "below" if value < low else ("above" if value > high else "within")


def runway(args):
    raise_ = number(args.raise_, "--raise")
    cash = number(args.cash, "--cash")
    if raise_ <= 0:
        fail("--raise must be positive")
    if cash < 0:
        fail("--cash must be zero or more")
    phases = parse_burn(args.burn)
    claimed = optional_positive(args.claimed_months, "--claimed-months")
    pre_money = optional_positive(args.pre_money, "--pre-money")
    uses = []
    if args.use:
        percent_mode = [value.strip().endswith("%") for _, value in args.use]
        if any(percent_mode) and not all(percent_mode):
            fail("--use values must be all amounts or all percentages, not a mix")
        for name, value in args.use:
            if all(percent_mode):
                amount = share(value, f"--use {name!r}") * raise_
            else:
                amount = number(value, f"--use {name!r}")
            if amount < 0:
                fail(f"--use {name!r} must not be negative")
            uses.append((name, amount))

    total_cash = raise_ + cash
    print(f"Runway: raise {money(raise_)} + cash in the bank {money(cash)} = {money(total_cash)}")
    elapsed = 0.0
    remaining = total_cash
    months = None
    for amount, length in phases:
        span = f"months {elapsed:g} to {elapsed + length:g}" if length else f"from month {elapsed:g}"
        print(f"  Net burn {money(amount)} a month, {span}")
        if amount > 0 and (length is None or amount * length >= remaining):
            months = elapsed + remaining / amount
            break
        if length is None:
            break
        remaining -= amount * length
        elapsed += length
    if months is None:
        print(f"  Cash does not run out on this plan: net burn is zero or below from month {elapsed:g}.")
    else:
        low, high = USUAL_RUNWAY_MONTHS
        print(f"  Runway: {months:.1f} months")
        print(f"  Rounds are usually sized to last {low} to {high} months; this is {where(months, low, high)} that range.")
        if months > NEXT_RAISE_LEAD_MONTHS:
            print(f"  Start preparing the next round by month {months - NEXT_RAISE_LEAD_MONTHS:.1f}"
                  f" ({NEXT_RAISE_LEAD_MONTHS} months of runway left).")
        else:
            print(f"  Runway is {NEXT_RAISE_LEAD_MONTHS} months or less from the start: the next raise starts now.")
    if claimed:
        if months is None:
            print(f"  Deck claims {claimed:g} months; on this plan the cash does not run out.")
        else:
            gap = months - claimed
            if abs(gap) < 0.05:
                verdict = "matches that"
            elif gap < 0:
                verdict = f"is {-gap:.1f} months short of that"
            else:
                verdict = f"gives {gap:.1f} months more than that"
            print(f"  Deck claims {claimed:g} months: the burn plan {verdict}.")

    if pre_money:
        post = pre_money + raise_
        stake = raise_ / post
        low, high = USUAL_ROUND_STAKE
        print(f"  Pre-money {money(pre_money)} + raise = post-money {money(post)}; new investors own {pct(stake)}.")
        print(f"  Priced rounds commonly sell {low * 100:.0f}% to {high * 100:.0f}%; this is {where(stake, low, high)} that range.")

    if uses:
        width = max(len("Use of funds"), *(len(n) for n, _ in uses))
        print(f"  {'Use of funds':<{width}}  {'Amount':>12}  {'Share':>6}")
        for name, amount in uses:
            print(f"  {name:<{width}}  {money(amount):>12}  {pct(amount / raise_):>6}")
        total = sum(amount for _, amount in uses)
        line = f"  {'Total':<{width}}  {money(total):>12}  {pct(total / raise_):>6}"
        if abs(total / raise_ - 1) <= ROUNDING_TOLERANCE:
            print(line + "  adds up to the raise")
        else:
            side = "more than" if total > raise_ else "short of"
            print(line + f"  {money(abs(total - raise_))} {side} the raise")


def growth(args):
    start = number(args.start, "--start")
    end = number(args.end, "--end")
    periods = number(args.periods, "--periods")
    if start <= 0 or end < 0:
        fail("--start must be positive and --end zero or more")
    if periods <= 0:
        fail("--periods must be positive")
    claimed = None
    if args.claimed_rate is not None:
        claimed = share(args.claimed_rate, "--claimed-rate")
        if claimed <= -1:
            fail("--claimed-rate must be above -100%")
    unit = args.per
    multiple = end / start
    rate = multiple ** (1 / periods) - 1
    print(f"Growth from {money(start)} to {money(end)} over {periods_text(periods, unit)}: {multiple:,.2f}x")
    line = f"  Compound growth: {pct(rate)} a {unit}"
    if unit != "year":
        line += f"  (equivalent to {pct((1 + rate) ** PERIODS_PER_YEAR[unit] - 1)} a year)"
    print(line)
    if claimed is not None:
        if abs(claimed - rate) < 0.0005:
            print(f"  Deck claims {pct(claimed)} a {unit}: matches the start and end figures.")
        else:
            implied_end = start * (1 + claimed) ** periods
            print(f"  Deck claims {pct(claimed)} a {unit}: {periods_text(periods, unit)} at that rate would turn"
                  f" {money(start)} into {money(implied_end)}, not {money(end)}.")


def main():
    if hasattr(sys.stdout, "reconfigure"):
        # Segment names can hold characters the console cannot show: print "?" rather than crash.
        sys.stdout.reconfigure(errors="replace")
    parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
    sub = parser.add_subparsers(dest="command", required=True)

    m = sub.add_parser("market", help="bottom-up TAM, SAM and SOM from customer counts and prices")
    m.add_argument("--segment", nargs="+", action="append", metavar="VALUE",
                   help="NAME CUSTOMERS PRICE [SERVICEABLE]; repeat for each customer group")
    m.add_argument("--monthly", action="store_true", help="prices are per month, not per year")
    m.add_argument("--som-share", help="share of SAM the company can win in the plan period, e.g. 3%%")
    m.add_argument("--claimed-tam", help="TAM the deck quotes, to compare")
    m.add_argument("--claimed-sam", help="SAM the deck quotes, to compare")
    m.add_argument("--claimed-som", help="SOM the deck quotes, to compare")
    m.add_argument("--revenue-target", help="annual revenue in the last year of the deck's plan")
    m.set_defaults(run=market)

    r = sub.add_parser("runway", help="months of runway from the raise and the burn plan, and use of funds")
    r.add_argument("--raise", dest="raise_", required=True, help="amount being raised")
    r.add_argument("--burn", required=True, help="monthly net burn: 60000, or phases 60000:6,85000")
    r.add_argument("--cash", default="0", help="cash in the bank before the raise")
    r.add_argument("--claimed-months", help="runway the deck claims, in months")
    r.add_argument("--pre-money", help="pre-money valuation, for a priced round")
    r.add_argument("--use", nargs=2, action="append", metavar=("NAME", "VALUE"),
                   help="a use of funds line: amount, or percentage of the raise like 45%%")
    r.set_defaults(run=runway)

    g = sub.add_parser("growth", help="compound growth rate between two data points")
    g.add_argument("--start", required=True, help="first value, e.g. MRR at the start")
    g.add_argument("--end", required=True, help="last value")
    g.add_argument("--periods", required=True, help="number of periods between them")
    g.add_argument("--per", choices=sorted(PERIODS_PER_YEAR), default="month", help="period length")
    g.add_argument("--claimed-rate", help="growth rate the deck claims per period, e.g. 40%%")
    g.set_defaults(run=growth)

    args = parser.parse_args()
    args.run(args)


if __name__ == "__main__":
    main()

Limits

  • It reviews the deck, not the business. It won't predict whether you'll raise, and it won't suggest investors to approach.
  • It brings no market data of its own. Customer counts, prices and sources must come from you; without them it can't rebuild the market and says so.
  • It comments on design only where the layout hides a number or a point. It isn't a design review.
  • Its stage expectations are general. Investors, sectors and countries differ, and labels such as pre-seed and seed are used loosely.
  • The runway check uses your planned net burn by phase. It doesn't forecast revenue month by month; use the burn rate and runway calculator for that.

Questions

Will it tell me whether my deck is good enough to raise?

No. It tells you how the deck reads against what investors look for at your stage, which slides are weak or missing, and which numbers don't agree. Whether a round closes depends on much more than the deck, so it never predicts that.

Where does it get market size data?

From you. The skill rebuilds TAM, SAM and SOM from the customer counts and prices in your deck or in your answers, and asks for a source for each count. It won't fill gaps with figures from memory, because a number you can't source is the first thing an investor will question.

Does it work for a pre-seed deck with no revenue?

Yes. At pre-seed it looks for why your team suits the problem, how painful the problem is, any evidence of demand such as a waitlist, design partners or pilots, and what the money will prove and by when. It doesn't mark a pre-seed deck down for thin financials.

Does it judge the design of my slides?

Only where the design gets in the way, such as a chart with no labelled axis or a key number in tiny type. Its job is the substance: the story, the evidence and whether the numbers hold together.

Can it check the valuation we're asking for?

It checks the arithmetic: for a priced round with a stated pre-money, it shows the post-money and the stake investors would own, against the 10% to 25% priced rounds commonly sell. It doesn't say what your company is worth; our guide to valuing a pre-revenue startup covers how early rounds are priced.

Does the skill send my deck anywhere?

The skill itself is instructions and a Python script with no network calls, so it sends nothing anywhere. The deck you upload is handled under your Claude plan's normal data terms, so check those before sharing anything confidential.

Learn what the skill checks

The skill is built from the same rules and formulas as these StartupReader pages, so you can follow its reasoning step by step.

Pairs well with

The weekly brief

More on pitch deck review, once a week

Who raised, who launched and the founder terms worth knowing, in one short email a week.

The StartupReader app

Startup news in 60-second swipes

Funding, launches and founder programs, each on one card with the key numbers. Free, with read-aloud and auto-scroll.

Get it on Google PlayComing soon

Building something? List your startup free.

Written and tested by the StartupReader editorial desk with AI assistance; the example outputs are the skill's scripts run on the made-up figures shown. StartupReader is not affiliated with Anthropic. The skill gives general information, not legal, tax or financial advice. Spotted something wrong? Tell us.