Pricing Academy Blog

Analyze funnel data with Claude Code

Analyze funnel data with Claude Code in eight prompts: from sales by funnel to a ranked list of fixes, with the ef CLI reading your ElasticFunnels numbers.

Summarize with:
What you'll build

A read-only analysis of one sales funnel, done by Claude Code with the ef CLI (command-line tool): sales by funnel, the funnel's step table, the upsell take rate per buyer from orders, a traced session that confirms the finding, a split test call made knowingly, and a developer brief ranked by money. The clips replay that analysis on the fictional Northwind Supplements brand. Every number in them is invented; the commands and the output format are the CLI's own.

Why this works: the full worked analysis, including the two claims the agent had to take back, is in Claude Code funnel analysis. To let Claude Code edit pages instead, see add an MCP server to Claude Code.

You need Claude Code, installed and signed in, Node.js 18 or newer, and the CLI: npm i -g @elasticfunnels/cli. In a new, empty folder, ef init signs you in through the browser, binds the folder to one brand and installs the skills. A folder you bound before only needs ef update, then step 1.

mkdir northwind && cd northwind
ef init

1Install the skills and set the timezone

In the bound folder, run ef claude. It updates the folder's CLAUDE.md and installs five skills into .claude/skills/: ef-stats, ef-funnel-analysis, ef-upsell-diagnosis, ef-funnel-performance and ef-page-events. Claude Code loads one when a question matches it, so you never name them.

ef claude updates CLAUDE.md and installs five ef skills; ef config set analyticsTz America/New_York; ef stats --range 7d prints revenue, sessions, conversion rate, sales and AOV for the last 7 days in that timezone
The VS column is the 7 days before, not last year. Every number in these clips is invented for the demo brand.

Then tell the CLI which timezone your brand counts days in: ef config set analyticsTz America/New_York. Run ef stats --range 7d to check: the first line names the range and the zone.

Pitfall: without analyticsTz the CLI counts days in your computer's timezone, which is not always your market's. Every day boundary shifts, so a "drop" on one day can be the edge of the range moving.

2Ask for sales by funnel

Start claude in the folder and type: show me sales by funnel for the last 30 days. Claude Code runs ef stats by funnel_id with sales, revenue, sessions, conversion rate and AOV (average order value).

The prompt asks for sales by funnel; Claude Code runs ef stats by funnel_id for 30 days; four funnels come back with sales, revenue, sessions, conversion rate and AOV, and the answer flags the 38.51% rate and the unlabeled row
The waits while Claude Code works are shortened in every clip. Tool output is shown expanded.

Look for three things in the answer: the range and timezone stated, a funnel whose conversion rate is too good to be real (38.51% here, most likely buyers who reach checkout without a tracked page view: compare that funnel on sales and revenue, and confirm with a trace as in step 5), and the (unlabeled) row, orders with no funnel attached. The funnel with the traffic is the Main VSL (video sales letter) funnel: 4,210 sessions at 2.76%.

Pitfall: --limit cuts the table and says so (4 of 8 rows). Before anyone concludes "most of our sales are X", check the row count.

3Build the funnel's step table

Pick the funnel with the traffic and name the problem: walk me through the Main VSL funnel, the upsell take is low. The ef-funnel-analysis skill joins three sources into one table: ef funnels product-flow 12 (which page follows which purchase), ef stats by page --funnel 12 (sessions and sales per page) and ef products list (prices).

Claude Code runs ef funnels product-flow, ef stats by page, ef products list and ef stats --metrics upsell_take_pct, then answers with a step table: front end, upsell 1, downsell, upsell 2 and upsell 3 with offer, sessions, sales and rate
upsell_take_pct is the server's own number (18.99%): about 1 upsell sale for every 5 front-end sales.

Read it in buyer order: front end, upsell 1, downsell, upsell 2, upsell 3. Here the half-price downsell converts about 2.6 times the upsell (12.1% vs 4.6%): buyers want more, and the price is the objection. Upsell 3 took 1 sale from 49 sessions.

Pitfall: session counts on pages after checkout are unreliable (reloads and repeat visits add some, missed page views drop others), so sales per session can misstate the take per buyer. The ranking between steps holds; the rates do not. Step 4 measures buyers.

4Check upsell take per buyer from orders

Before you change an upsell, ask who takes it: before we change upsell 1: who actually takes it? check orders, not sessions. Claude Code runs ef orders buyers --funnel 12 --range 30d: every buyer's first package, what they paid, and whether they bought anything after it. Order bumps are left out, and no customer data is printed.

Claude Code runs ef orders buyers for the Main VSL funnel; the table lists each front-end package with list price, median paid, buyers, how many took an upsell and the take rate, and the answer keeps the same-product upsell for 6-bottle buyers
Buyers are grouped by a hash of the email; the table itself holds no customer data.

The table settles what the step table can't. Buyers of the biggest package at full price took "more of the same" best (9 of 39, 23.1%), 1-bottle buyers took nothing, and the sale buyers, who paid $94 for 6 bottles, took nothing at all.

Pitfall: don't let the agent guess what a segment wants. In the real analysis behind this tutorial, Claude Code first suggested a different product for 6-bottle buyers; the orders showed they were the best takers of the same one, and it retracted. Samples are small, so ask for the n next to every rate.

5Trace a session to confirm the finding

A table says what happened, a session trace says why. Ask: why did none of the sale buyers take an upsell? trace a few. Claude Code takes session ids from ef orders list --funnel 12 --page 4471 --json and runs ef sessions show <id> on each: landing page, referrer, affiliate, and the path the buyer took.

Claude Code lists three session ids from the sale page's orders and runs ef sessions show: the landing is /summer-sale, the referrer is webmail, and every path goes from checkout straight to the members area
Session ids, page ids and the domain are invented. Traces are one request each, so trace a sample, not every buyer.

All three traces read /summer-sale → checkout → /members-area. Those buyers never see an upsell, so it's routing, not a weak offer. If the house-list sale is meant to skip upsells, fine; if not, they need a price-matched upsell, not the $228 one.

Pitfall: the compiled funnel flow can show a path the runtime never takes (a page that sits in two page groups, for example). Confirm a routing claim with orders and two or three traces before anyone rewires the funnel. When a trace shows a buy click with no page view before it, ef sessions show flags a TRACKING GAP: that page's conversion rate is understated.

6Read the split test result before you act

If a step has a test running, ask whether it can finish: is the upsell 1 split test ever going to finish? Claude Code runs ef stats split 318 from the day the test started and reports the p-value and the sample size the app computed. It never runs its own test.

Claude Code runs ef stats split 318; Control has 99 sessions at 4.04% and Short copy 93 sessions at 7.53%, p-value 0.2980, no winner yet with about 700 sessions needed per arm, and the answer calls it trending, not conclusive
4 vs 7 sales cannot confirm a lift that size: at these rates each arm needs about 700 sessions (α 0.05, 80% power).

Here the challenger is ahead (7.53% vs 4.04% for the control), but there is no winner: the p-value is 0.2980 and each arm needs about 700 sessions. With about 50 sessions a month per arm, that is roughly another year. The honest label is "trending, not conclusive".

Pitfall: a low p-value on a small sample is what peeking too early looks like. Decide the sample size before launch, judge at that size, and when traffic can never get there, say so and make the call as a business decision.

7Declare the winner, if you decide to

The call is yours, not the agent's. Say it plainly: call it for Short copy, I accept that it's a manual call. Claude Code runs ef splits variants 318 to match names to node codes, then ef splits winner 318 "Short copy" --yes.

Claude Code runs ef splits variants 318, then ef splits winner 318 Short copy --yes; the CLI warns the server has not named a winner, finalizes test 318 and sends all traffic to Short copy, and the decision is logged in split-tests.md
The page's graph changed on the server, so pull it (ef pages events pull) before anyone edits it.

The command first prints the p-value and the sample still needed, warns that this is a manual call, then finalizes the test and sends all its traffic to the winner. Claude Code then records the decision, both arms' numbers, the range and the timezone in elasticfunnels/split-tests.md.

Pitfall: don't let the agent call a test early on its own. ef stats can't change anything, and a winner is only declared when you ask for it. --yes is needed because Claude Code is not an interactive terminal.

8Have it write a developer brief

End with something a person can act on: write this up for a developer: ranked by money, with links and sample sessions. Claude Code writes a Markdown file in the project (research/main-vsl-dev-brief.md here) with an issue table, then per issue: the evidence, dashboard links, sample session and order ids, what to check, how to tell it's fixed, and the commands that reproduce the numbers.

Claude Code writes research/main-vsl-dev-brief.md with the range, timezone and an issue table, then lists four issues ranked by money: the upsell 1 price, sale buyers skipping upsells, a dead upsell 3 and page views to check on the Social funnel
The brief holds session and order ids, never customer names or emails.

Read it before you send it. Each issue should point back to a number you saw in an earlier step; anything the agent inferred rather than measured should say so.

Pitfall: a brief without its range and timezone can't be reproduced. The developer should get the same numbers from the same commands.

Common Claude Code analysis mistakes

  • Reading "unavailable" as zero. Metrics differ per brand. When one is missing, the CLI says Not available for this brand: report that as "not tracked", never as 0.
  • Skipping the timezone. Set analyticsTz once, and have every answer state its range and zone. Two people comparing numbers from different zones will both be right and still disagree.
  • Calling the comparison year over year. The VS column is the period right before, of the same length. A 30-day range compares with the 30 days before it.
  • Concluding from a cut table. --limit truncates and prints N of M rows. Read the row count before you sum or rank.
  • Mixing sessions and buyers. Upsell sessions include reloads and repeat visits and miss some buyers. Take per buyer comes from ef orders buyers, not from sales per session.
  • Flagging a checkout page as "not wired". Checkout pages are not steps in the funnel graph: the checkout is picked when the buyer clicks the buy link, from the domain's active merchant, unless a page event overrides it.
  • Calling a split test early. Read the significance result the app computed. A trend with no winner is "trending, not conclusive"; ending it is a business decision you make and record, not a statistical result.

Keep going

The full worked analysis, with the agent's corrections: Claude Code funnel analysis. Building and split-testing pages with an agent instead: Claude Code for marketing. Page edits from Claude Code: add an MCP server to Claude Code. Everything the CLI does: the ef CLI. Test the upsell change you decide on: post-purchase upsell and downsell. All tutorials: the Academy.

FAQ

Claude Code data analysis FAQ

How do I use Claude Code for data analysis?

Give it a tool that returns the data and a method for reading it. For funnel data that is the ef CLI in a folder bound to your brand, plus the skills ef claude installs. Then ask in plain English, one question at a time, and check each answer against the table it came from.

How do I prompt Claude for data analysis?

Name the object, the range and the problem: "walk me through the Main VSL funnel for the last 30 days, the upsell take is low". Ask it to check claims against orders, and to state the range and timezone with every number.

How good is Claude Code at data analysis?

Good at joining tables, spotting numbers that can't be right and tracing single sessions, and it can still be confidently wrong. In the analysis behind this tutorial it took back two claims once orders and session traces disagreed. Challenge any finding that isn't tied to a number.

Can Claude Code read my ElasticFunnels data?

Yes, through the ef CLI: ef stats for metrics and breakdowns, ef orders for orders and per-buyer upsell take, ef sessions for single visits, ef funnels for the funnel structure. The folder's key opens one brand only.

What is funnel analysis?

Measuring how people move through each step of a funnel, from the first page to the last upsell, and where they stop. The step table in step 3 is one: every page in buyer order with its offer, sessions, sales and rate.

Can you give an example of funnel analysis?

Step 3: a front end at 2.0% of sessions, upsell 1 at 4.6%, a half-price downsell at 12.1%, then two late upsells that barely sell. The downsell beating the upsell points at price, not at the offer.

What are Claude Code skills?

Folders with a SKILL.md file of instructions that Claude Code loads when a task matches. ef claude installs five for ElasticFunnels: ef-stats, ef-funnel-analysis, ef-upsell-diagnosis, ef-funnel-performance and ef-page-events.

Can Claude Code change my funnel while it analyzes?

Not through ef stats, ef orders or ef sessions: they only read. A split test ends only when you ask for ef splits winner, and Claude Code asks before it runs commands unless you have allowed them.

Does Claude Code see my customers' personal data?

The tables in this tutorial don't show it. ef orders leaves out customer emails, names, phone numbers and addresses unless someone passes --include-pii, and ef orders buyers groups buyers by a hash. Don't ask for PII; the analysis never needs it.

Why doesn't Claude Code's number match my dashboard?

Usually a different range or timezone. Every CLI report names both, so set the dashboard to the same range and zone. If they still differ, ask Claude Code to reconcile the two numbers before you trust either.

Is a 2.5% conversion rate good?

It depends on the traffic. In the worked example, cold mobile traffic to a VSL converted in the 2% range while a pre-sold email list converted around 15% on a sale page. Compare a page with itself across sources, not with an industry average.

Do I need the MCP server for this?

No. Claude Code runs the ef CLI in its terminal for every step here. The MCP server is for editing pages: see add an MCP server to Claude Code.

Can I do the same with Codex or Cursor?

The commands are the same. ef init also writes AGENTS.md for Codex and a Cursor rule; the step-by-step skills are Claude Code skills.

Is the ef CLI included in my plan?

Yes. The ef CLI is included on every ElasticFunnels plan; you need a Claude account that can run Claude Code.

Let Claude Code read your funnel numbers

Every feature on every plan. Start a 14-day free trial.