Define Nouns and Verbs. The rest is generated.
Nouns are what your SaaS keeps; Verbs, what people and agents do. Leaseclock, below, is 27 lines, and nobody wrote anything else.
Rename or . Every address reprints.
: does: Move the end date forward input: { endsOn: { says: the new end date, type: date, required: true } } from: [active] fn: { kind: code, body: replace }
- App
Leases › 4B › Renew - API
POST /leases/4b/renew - CLI
do Lease.renew 4b - MCP
do Lease.renew - SDK
$.Lease.renew('4b', { endsOn }) - Docs
leaseclock.com/docs/lease#renew
Your first product is free; each after it is $49 a month. You keep your files, your records and your Stripe account. Export in one call
Rename or . Every address reprints.
---$type: Noun$id: leaseclock.com/nouns/Leasename: fields: unit: { type: link, target: Unit, required: true } renter: { type: email, required: true } endsOn: { type: date, required: true, indexed: true } status: { type: choice, options: [{ key: active }, { key: ended }] }verbs: : does: Move the end date forward input: { endsOn: { says: the new end date, type: date, required: true } } from: [active] fn: { kind: code, body: replace } end: { does: End the lease, from: [active], to: ended }---
Startup/leaseclock.com.mdx5pitch: No renewal slips past its date.+4 lines
---$type: Startup$id: leaseclock.comname: Leaseclockdescription: Tracks lease renewals for small property managers.pitch: No renewal slips past its date.icp: small property managersbrand: Leaseclock---
Noun/Unit.mdx4label: { type: text, required: true }+3 lines
---$type: Noun$id: leaseclock.com/nouns/Unitname: Unitfields: label: { type: text, required: true } building: { type: text }---
Offer/pro.mdx5name: Leaseclock Pro+4 lines
---$type: Offer$id: leaseclock.com/offers/proname: Leaseclock Proprice: { amount: 29, currency: USD, unit: month }limits: { Unit: 200 }personas: Property manager, Leasing coordinatorstatus: Live---
curl https://api.sb/leaseclock.com/leases/4b/renew"action": { "verb": "renew", "object": "leases/4b", "status": "Pending" }"input": { "endsOn": "the new end date" }- App
Leases › 4B › Renew - API
POST /leases/4b/renew - CLI
do Lease.renew 4b - MCP
do Lease.renew - SDK
$.Lease.renew('4b', { endsOn }) - Site
leaseclock.com/pricing - Docs
leaseclock.com/docs/lease#renew - Blog
leaseclock.com/blog - Stripe
Leaseclock Pro · monthly
| Unit | Renter | Ends on | Status | Verbs |
|---|---|---|---|---|
| 2A | ana.ruiz@example.com | 2026-09-30 | ended | |
| 4B | maya.ortiz@example.com | 2026-11-15 | active | Renew |
| 12 | sam.lee@example.com | 2027-03-31 | active |
Generated, never scaffolded.
Your agent could write all 34 into your repo for you to maintain. Here nothing is copied; each improvement reaches you on the next request.
- AppA 9-screen Admin for your team · A button for every Verb · SaaS App for your Customers · Customer sign-in4
- API18 operations on 2 Collections · Your own domain · Customer keys and Limits · One Tenant per Customer · Refusals that name the fix5
- CLIshow for every record · do for every Verb2
- MCPsearch, fetch and do · Tools for your Customers’ agents2
- SDKA typed $ with 14 methods · TypeScript, Zod and JSON Schema · Packages under your name3
- SiteHome, pricing and legal pages · /llms.txt, OpenAPI and agents.json2
- DocsA page per Noun and Verb · A Markdown twin of every page · Examples tested on every Interface3
- Blog/blog · A changelog2
- StripeA Product and Price per Offer · Checkout and signed webhooks · Monthly subscriptions · A billing portal · Payouts to your own account5
- Underneath every NounFour Access levels · Previews that run nothing · Try mode · Versions and undo · Test and Dev environments · Export in one call6
Define your first Noun.
Step 0 needs no key, and every write has an undo.
- This URL exists because Startup declares create.
curl https://api.sb/startups/create - Sign in once. Two export lines follow.
npx startup-builder login - Create your Startup: check it in try, then commit.
curl -X POST https://api.sb/startups/create \ -H "authorization: Bearer $SB_TOKEN" \ -H 'Prefer: mode=try' \ -d '{"domain":"<your-domain>"}' - Send the files you wrote: try, then commit.
curl -X POST https://api.sb/<your-domain>/nouns \ -H "authorization: Bearer $SB_TOKEN" \ -H 'Prefer: mode=try' \ -F file=@Noun/Unit.mdx -F file=@Noun/Lease.mdx - Your Site, Docs and llms.txt, on your own domain.
curl https://<your-domain>/llms.txt
Unit 96 · Lease 120216 screens, never drawn
{ "fonts": ["Libre Caslon Text:wght@700"], "light": { "accent": "#8A4B0F" }}
Batteries included.
Every output has a default. Override any style or component, and you maintain only what you override.
- ThemeThe token values
- CSSYour rules
- A field’s inputThat one input
- A Noun’s viewThat view’s layout
- A page or screenThat page’s or screen’s layout
- A Function bodyWhat the Verb does
Get paid with Stripe.
Write the price once. You never create a Stripe Product or Price.
From the Offer to your account/pricingup to 200 units- Checkoutsigned webhook
- Subscription
- Billing portal
$27.86per subscriber, after Stripe's standard card rate (2.9% + 30¢)
Your Customers pay you $29 a month for Leaseclock Pro, through your own Stripe account.
The constraints are the feature.
Every Noun takes one shape, SaaS.Dev's own included. That is why your agent gets yours right, and you can check all 27 lines yourself.
Read https://saas.dev/llms.txt. Write the Nouns, Verbs and Offer for <your product> in Leaseclock's shape. Check each file with Prefer: mode=try, fix every refusal, and show me the files before you commit.