Skip to content
GuidesTutorials

Earning first revenue

A dated 30-day calendar from one sentence to the first outside paid Order, every step a command with its output and the gate it passes.

A solo founder takes a Startup from one sentence on day 0 to its first outside paid Order on day 21. Every step on the calendar is a command and the output it prints.

What you build

You ran catalog operations for online stores for ten years. Your brief: 15 hours a week, no paid ads, and no promise you cannot keep by hand.

Your Idea is cleanshelf.com, a Solo SaaS that cleans a small store's product catalog and keeps it clean. Agents hold every Role but yours. You ask for money before you build, and you sell the first Customers yourself.

Two gates stand on the calendar. Build opens Building on day 10:

Build reads 5 checks for cleanshelf.com, a Solo SaaS Startup: the ones every Startup passes. Some templates add more; the launch checklist lists them all.

CheckIdKindPasses when
Template chosenbuilding-templateregistryThe Startup names its Startup Template, and every inherited default resolves.
Problem statedbuilding-problemregistryThe Startup states the problem, the workarounds Customers use today, and why now.
Brand namedbuilding-brandregistryThe Brand has a name, a voice, a logo, and a theme.
Products declaredbuilding-productsregistryEvery Product names its kind: data, software, agent, or service.
Three slots at Commitmentbuilding-slotsgradeThe customer, problem and switch slots each hold Commitment Evidence from outside people. Slots customer, problem, switch at Commitment or stronger, outside Evidence only.

Launch opens Live on day 18:

Launch reads 10 checks for cleanshelf.com, a Solo SaaS Startup: the ones every Startup passes. Some templates add more; the launch checklist lists them all.

CheckIdKindPasses when
Offers publishedlive-offersregistryAt least one Offer is published with a price and terms; launch refuses a Startup without one.
Work definedlive-workregistryEvery published Offer has a workflow that delivers it, with each step assigned to software, an Agent, or a person.
People assignedlive-peopleregistryEvery role the workflows need is held by an Agent or a person, with instructions and limits.
Site publishedlive-siteuiThe site serves home, pricing, terms, and privacy pages under the Brand, readable by people and agents.
Test run passedlive-test-runtranscriptA sample Customer completes every published Offer end to end in test, with no real charge or message.
Portal readylive-portaluiThe customer portal on the site shows each Customer their orders, deliveries, invoices, and messages.
Agent API openlive-agent-apicontractThe API, MCP server, OpenAPI document, llms.txt, and agents.json serve every published Offer and pass conformance.
Payouts connectedlive-payoutscontractStripe takes payments for the Startup and pays out to its bank account.
Address resolveslive-addresscontractThe canonical Domain serves the Site over HTTPS with a valid certificate and, where it embeds a payment form, Stripe lists it as a payment method domain.
Five slots at Commitmentlive-slotsgradeAll five Founding Hypothesis slots hold Commitment Evidence from outside people. Slots customer, problem, approach, switch, differentiation at Commitment or stronger, outside Evidence only.

Steps

Terminal12 steps
  1. Day 0, 2026-11-02. To start, create the Startup from its Founding Hypothesis and its Minimum Success Criteria:

    npm create startups cleanshelf.com -- --template solo-saas --json '{"hypothesis": {"customer": "Owners of online apparel stores with 200 to 5,000 products and no catalog staff","problem": "Half my products have no size or material, so search on my own store misses them","approach": "saas","switch": "a freelancer paid by the project","differentiation": ["every product filled within 5 business days", "kept clean as products are added"]},"msc": { "metric": "outside-revenue", "value": 3000, "by": "2027-08-31" }}'
    Created Cleanshelf in testStartup      startup_1State        IdeaHypothesis   hypothesis_1, 5 slots at NoneICP          icp_1, from the customer slotMSC          $3,000 outside revenue a month by 2027-08-31: reachable at 21 CustomersClaim token  ct_4Rn8sK

    The Startup opens in Idea. Its state Metric is Problem interviews, and it reads zero.

  2. Day 0. To take real deposits, claim the Startup, then publish the reserve Offer the switch slot compiled:

    npx startup-builder do Startup.claim --json '{"startup":"startup_1","claimToken":"ct_4Rn8sK"}'npx startup-builder do Offer.publish --json '{"offer":"offer_1"}'
    Claimed Cleanshelf. Finish payouts onboarding: https://connect.stripe.com/setup/c/acct_1Q8cLsReserve page live at https://cleanshelf.com: refundable $149 deposit, $149 a month, ships 2026-11-23Threshold  8 outside deposits by 2026-11-16

    Until launch, the live domain serves only the reserve page and its Offer. The threshold is the first Key Result, fixed before the first Visitor.

  3. Days 1 to 4. To find people to talk to, list fifteen Prospects that fit the ICP:

    npx startup-builder do Prospect.list --json '{"where":"icp = icp_1","limit":15}'
    15 Prospects for icp_111  found by the Prospector in store directories and community threads4  added by you

    The weekly test ranks the customer slot first, so the week opens with fifteen Interviews. Ask about the last time the problem hit, what it cost, and who else has it.

  4. Day 4, 2026-11-06. Record the Evidence each Interview gave, then read the slots:

    npx startup-builder do Evidence.create --json '{"grade":"Commitment","binds":"Hypothesis#problem","source":"interview_6","quote":"Take my export on Thursday and fix fifty products. Call Dana at Fernhouse too."}'npx startup-builder show '/hypotheses?where=parent = hypothesis_1' --fields 'kind,grade,verdict'
    kind             grade       verdictcustomer         Commitment  Supportedproblem          Commitment  Supportedapproach         None        Openswitch           None        Opendifferentiation  None        Open

    Time and introductions grade Commitment. Praise grades Opinion and weighs zero. Six of fifteen gave something up by day 4, so the test crossed its pass line and closed, and the switch slot's test began.

  5. Days 4 to 9. To send ICP members to the reserve page in your name, authorize the Sales Lead under a Mandate bounded by a Limit:

    Terminal
    LIMIT=$(npx startup-builder do Limit.create --json '{"count":40,"period":"week","resets":"calendar"}' | jq -r '.limit["$id"] | split("/") | last')
    npx startup-builder do Mandate.authorize --json '{"agent":"sales-lead","verb":"Message.create","limit":"'"$LIMIT"'","channels":["channel_email"]}'
    Text
    Authorized sales-lead: Message.create as you, 40 email messages a week
      Mandate  mandate_1, pause any time with Mandate.pause

    You write to the fifteen interviewees. The Agent writes to the rest of the list. Every message shows in your stream, and you remain its author of record.

  6. Day 9, 2026-11-11. The first outside deposit lands. Read the Evidence it wrote:

    npx startup-builder show '/evidence?where=binds = Hypothesis#switch' --fields 'grade,source,quote,outside'
    grade       source        quote                      outsideCommitment  experiment_2  Paid the $149 deposit      true

    outside is true because the store shares no owner, account, Agreement, or sibling with your Startup. Customer, problem and switch now hold Commitment.

  7. Day 10, 2026-11-12. To open Building, build the Startup:

    npx startup-builder do Startup.build --json '{"startup":"startup_1"}'
    Built Cleanshelf: 5 of 5 Building checks pass

    Its state Metric is now Committed ICP members. The Agents build the Site, the Portal and every Interface while deposits keep arriving.

  8. Days 10 to 17. To grade approach and differentiation, start the smoke page at the real price:

    npx startup-builder do Experiment.start --json '{"experiment":"experiment_3"}'
    Started experiment_3: smoke page for approach at $149 a monthPass  3 outside accept attempts by 2026-11-19Kill  0 by 2026-11-19

    It crosses its pass line on day 13 and closes. The fake doors start that day, one per axis on the reserve page, and pass on day 17. Both grade Behavior.

  9. Day 18, 2026-11-20. To pass the test run, have a sample Customer accept the Offer, then launch:

    npx startup-builder do Offer.accept --json '{"offer":"offer_1","party":"Sample Store"}'npx startup-builder do Startup.launch --json '{"startup":"startup_1"}'
    Launched Cleanshelf: 10 of 10 checks pass

    Its state Metric is now Outside paying Customers. The first-revenue clock starts today.

  10. Day 21, 2026-11-23. On the ship date, nine of ten deposits convert; one refunded on request. Read the first converted Order:

    npx startup-builder do Order.get --json '{"id":"order_1"}'
    { "order": { "$id": "order_1", "status": "paid", "total": { "amount": 149, "currency": "USD" }, "outside": true } }

    The deposit pays the first Invoice. Days to first outside Order reads 3.

  11. Days 21 to 25. Onboard customer one by hand with Onboard a Customer, then read the first payout:

    npx startup-builder do Transaction.list --json '{"where":"kind = payout"}'
    { "transactions": [ { "kind": "payout", "amount": { "amount": 1299.41, "currency": "USD" } } ] }

    Every step done by hand is logged. A step done three times becomes an Issue for the Agents to take over.

  12. Day 30, 2026-12-02. Office hours with the Studio partner Agent asks where each Customer came from and who is next. Record the Decision:

    npx startup-builder do Decision.create --json '{"choice":"Persevere: 21 outside paying Customers by 2027-02-28","reason":"9 of 10 deposits converted, and 7 came from problem Interviews"}'
    Created decision_1: Persevere, stakes low

Result

You have nine outside paying Customers, $1,299.41 in your bank, and a Founding Hypothesis graded on all five slots. The calendar ran 30 days because each test closed the day it crossed its line.

The next date is in the Decision. Ten Customers who arrive through a Play rather than through you are the first check of Repeatable.

Next steps