# Earning first revenue

URL: /start/tutorials/first-revenue · Id: `page:start/tutorials/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](/business/nouns/startup) from one sentence on day 0 to its first outside paid [Order](/business/nouns/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](/business/nouns/idea) is cleanshelf.com, a [Solo SaaS](/start/templates/solo-saas) that cleans a small store's product catalog and keeps it clean. [Agents](/business/nouns/agent) hold every [Role](/business/nouns/role) but yours. You ask for money before you build, and you sell the first [Customers](/business/nouns/customer) yourself.

Two gates stand on the calendar. Build opens [Building](/business/lifecycle/states/building) on day 10:

Build reads 5 checks for `cleanshelf.com`, a [Solo SaaS](/start/templates/solo-saas) Startup: the ones every Startup passes. Some templates add more; the [launch checklist](/start/launch-checklist) lists them all.

| Check | Id | Kind | Passes when |
| --- | --- | --- | --- |
| Template chosen | `building-template` | `registry` | The Startup names its Startup Template, and every inherited default resolves. |
| Problem stated | `building-problem` | `registry` | The Startup states the problem, the workarounds Customers use today, and why now. |
| Brand named | `building-brand` | `registry` | The Brand has a name, a voice, a logo, and a theme. |
| Products declared | `building-products` | `registry` | Every Product names its kind: data, software, agent, or service. |
| Three slots at Commitment | `building-slots` | `grade` | The 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](/business/lifecycle/states/live) on day 18:

Launch reads 10 checks for `cleanshelf.com`, a [Solo SaaS](/start/templates/solo-saas) Startup: the ones every Startup passes. Some templates add more; the [launch checklist](/start/launch-checklist) lists them all.

| Check | Id | Kind | Passes when |
| --- | --- | --- | --- |
| Offers published | `live-offers` | `registry` | At least one Offer is published with a price and terms; launch refuses a Startup without one. |
| Work defined | `live-work` | `registry` | Every published Offer has a workflow that delivers it, with each step assigned to software, an Agent, or a person. |
| People assigned | `live-people` | `registry` | Every role the workflows need is held by an Agent or a person, with instructions and limits. |
| Site published | `live-site` | `ui` | The site serves home, pricing, terms, and privacy pages under the Brand, readable by people and agents. |
| Test run passed | `live-test-run` | `transcript` | A sample Customer completes every published Offer end to end in test, with no real charge or message. |
| Portal ready | `live-portal` | `ui` | The customer portal on the site shows each Customer their orders, deliveries, invoices, and messages. |
| Agent API open | `live-agent-api` | `contract` | The API, MCP server, OpenAPI document, llms.txt, and agents.json serve every published Offer and pass conformance. |
| Payouts connected | `live-payouts` | `contract` | Stripe takes payments for the Startup and pays out to its bank account. |
| Address resolves | `live-address` | `contract` | The 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 Commitment | `live-slots` | `grade` | All five Founding Hypothesis slots hold Commitment Evidence from outside people. Slots `customer`, `problem`, `approach`, `switch`, `differentiation` at Commitment or stronger, outside Evidence only. |

## Steps
1. **Day 0, 2026-11-02.** To start, create the Startup from its [Founding Hypothesis](/business/founding-hypothesis) and its [Minimum Success Criteria](/business/nouns/minimum-success-criteria):

   ```bash
   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" }
   }'
   ```

   ```text
   Created Cleanshelf in test
     Startup      startup_1
     State        Idea
     Hypothesis   hypothesis_1, 5 slots at None
     ICP          icp_1, from the customer slot
     MSC          $3,000 outside revenue a month by 2027-08-31: reachable at 21 Customers
     Claim token  ct_4Rn8sK
   ```

   The Startup opens in [Idea](/business/lifecycle/states/idea). Its state [Metric](/business/nouns/metric) is [Problem interviews](/agents/founding#problem-interviews), and it reads zero.

2. **Day 0.** To take real deposits, [claim](/business/nouns/startup/claim) the Startup, then [publish](/business/nouns/offer/publish) the reserve [Offer](/business/nouns/offer) the switch slot compiled:

   ```bash
   npx startup-builder do Startup.claim --json '{"startup":"startup_1","claimToken":"ct_4Rn8sK"}'
   npx startup-builder do Offer.publish --json '{"offer":"offer_1"}'
   ```

   ```text
   Claimed Cleanshelf. Finish payouts onboarding: https://connect.stripe.com/setup/c/acct_1Q8cLs
   Reserve page live at https://cleanshelf.com: refundable $149 deposit, $149 a month, ships 2026-11-23
     Threshold  8 outside deposits by 2026-11-16
   ```

   Until launch, the live domain serves only the [reserve page](/business/reserve-first) and its Offer. The threshold is the first [Key Result](/business/nouns/key-result), fixed before the first [Visitor](/business/nouns/visitor).

3. **Days 1 to 4.** To find people to talk to, list fifteen [Prospects](/business/nouns/prospect) that fit the [ICP](/business/nouns/icp):

   ```bash
   npx startup-builder do Prospect.list --json '{"where":"icp = icp_1","limit":15}'
   ```

   ```text
   15 Prospects for icp_1
     11  found by the Prospector in store directories and community threads
      4  added by you
   ```

   The [weekly test](/business/weekly-test) ranks the customer slot first, so the week opens with fifteen [Interviews](/business/nouns/interview). 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](/business/nouns/evidence) each Interview gave, then read the slots:

   ```bash
   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'
   ```

   ```text
   kind             grade       verdict
   customer         Commitment  Supported
   problem          Commitment  Supported
   approach         None        Open
   switch           None        Open
   differentiation  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](/business/nouns/mandate/authorize) the [Sales Lead](/agents/sales/sales-lead) under a [Mandate](/business/nouns/mandate) bounded by a [Limit](/business/nouns/limit):

   ```bash
   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:

   ```bash
   npx startup-builder show '/evidence?where=binds = Hypothesis#switch' --fields 'grade,source,quote,outside'
   ```

   ```text
   grade       source        quote                      outside
   Commitment  experiment_2  Paid the $149 deposit      true
   ```

   `outside` is true because the store shares no owner, account, [Agreement](/business/nouns/agreement), or sibling with your Startup. Customer, problem and switch now hold Commitment.

7. **Day 10, 2026-11-12.** To open Building, [build](/business/nouns/startup/build) the Startup:

   ```bash
   npx startup-builder do Startup.build --json '{"startup":"startup_1"}'
   ```

   ```text
   Built Cleanshelf: 5 of 5 Building checks pass
   ```

   Its state Metric is now [Committed ICP members](/agents/founding#committed-icp-members). The Agents build the [Site](/business/nouns/site), the [Portal](/business/nouns/portal) and every [Interface](/business/nouns/interface) while deposits keep arriving.

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

   ```bash
   npx startup-builder do Experiment.start --json '{"experiment":"experiment_3"}'
   ```

   ```text
   Started experiment_3: smoke page for approach at $149 a month
     Pass  3 outside accept attempts by 2026-11-19
     Kill  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](/business/nouns/offer/accept) the Offer, then [launch](/business/nouns/startup/launch):

   ```bash
   npx startup-builder do Offer.accept --json '{"offer":"offer_1","party":"Sample Store"}'
   npx startup-builder do Startup.launch --json '{"startup":"startup_1"}'
   ```

   ```text
   Launched Cleanshelf: 10 of 10 checks pass
   ```

   Its state Metric is now [Outside paying Customers](/agents/founding#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:

    ```bash
    npx startup-builder do Order.get --json '{"id":"order_1"}'
    ```

    ```json
    { "order": { "$id": "order_1", "status": "paid", "total": { "amount": 149, "currency": "USD" }, "outside": true } }
    ```

    The deposit pays the first [Invoice](/business/nouns/invoice). [Days to first outside Order](/agents/founding#days-to-first-outside-order) reads 3.

11. **Days 21 to 25.** Onboard customer one by hand with [Onboard a Customer](/workflows/processes/onboarding/onboard-customer), then read the first payout:

    ```bash
    npx startup-builder do Transaction.list --json '{"where":"kind = payout"}'
    ```

    ```json
    { "transactions": [ { "kind": "payout", "amount": { "amount": 1299.41, "currency": "USD" } } ] }
    ```

    Every step done by hand is logged. A step done three times becomes an [Issue](/business/nouns/issue) for the Agents to take over.

12. **Day 30, 2026-12-02.** [Office hours](/workflows/processes/office-hours) with the [Studio](/business/nouns/studio) partner Agent asks where each Customer came from and who is next. Record the [Decision](/business/nouns/decision):

    ```bash
    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"}'
    ```

    ```text
    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](/business/nouns/play) rather than through you are the first check of [Repeatable](/business/lifecycle/states/repeatable).

## Next steps
- [Earning first revenue by asking](/start/tutorials/first-revenue-by-asking): the same calendar as sentences to your agent, with no commands.
- [Weekly test](/business/weekly-test): how each slot's test is chosen, and why it closes early.
- [Repeatable](/business/lifecycle/states/repeatable): the checks that prove Customers arrive, pay, and stay.
- [Demand](/systems/sales/demand): choosing the Play that brings the next ten.
- [The operating week](/workflows/rhythm): the reviews that hold the dates.