The funnels/ folder: one file and what it compiles to
What one funnels/ file holds, what each key compiles to, and the checks that read it.
One funnels/ file is one funnel, and the question that asks each new Lead where they heard of you. SalesBuilder compiles it, and show traces every key.
---
steps: [visit, signup, trial, paid]
heardFrom: { ask: "How did you hear about Leaseline?" , options: [search, ai-answer, newsletter, a-friend, other] }
---
The Pro signup, from the pricing Page to the first paid month. $ npx startup-builder show funnels/signup.mdx
steps [visit, signup, trial, paid] funnels/signup.mdx:2
heardFrom { ask: "How did you hear about Leaseline?", options: [search, ai-answer… funnels/signup.mdx:3
owner SalesBuilderleaseline.app/
├── plays/
│ ├── cold-email.mdx
│ ├── warm-intros.mdx
│ ├── signup-interviews.mdx
│ ├── lead-reactivation.mdx
│ └── events-and-webinars.mdx
├── audiences/
│ ├── small-property-managers.mdx
│ ├── lapsed-leads.mdx
│ └── renewal-season.mdx
├── sequences/
│ └── cold-email-thread-founder.mdx
├── funnels/ ← this folder
│ └── signup.mdx
├── workflows/
│ └── outbound.mdx
├── agents/
│ ├── sales/prospector.mdx
│ └── marketing/content-lead.mdx
├── systems/
│ └── sequences.mdx
├── domains/
│ └── leaseline.app.mdx
├── offers/
│ ├── pro.mdx
│ └── team.mdx
├── content/
│ └── webinars/60-day-notices.mdx
├── metrics/
│ ├── q4.mdx
│ └── positive-reply-rate.mdx
└── startups.lockThe file
| Key | On the page | Compiles to | Checked by |
|---|---|---|---|
steps | Steps | the funnel’s steps, each a conversion with n | — |
heardFrom | How they heard | one question on signup; each answer records an Acquisition the credit reads (GET /{namespace}/acquisitions) | — |
Refusals
| Code | Fix, then the call that clears it |
|---|---|
cluster | Offer the plain trial; the account keeps every other term. Then POST /{namespace}/offers/{offer}/trial. |
Calls
You, to your agent
Create our signup flow, then show where new people heard of us.
curl -X POST "https://api.sb/leaseline.app/funnels?mode=try" \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"steps":{}}'
curl "https://api.sb/leaseline.app/acquisitions?limit=20" \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"import { $ } from 'startup-builder'
await $.Funnel.create({ steps: {} }, { mode: 'try' }) // funnels/ signup.mdx
return await $.Acquisition.list({ limit: 20 }) // heardFrom writes one per signup
npx startup-builder do Funnel.create --json '{"steps":{}}' --try
npx startup-builder do Acquisition.list --json '{"limit":20}'{
"name": "do",
"arguments": {
"code": "await $.Funnel.create({ steps: {} }, { mode: 'try' }) // funnels/signup.mdx\nreturn await $.Acquisition.list({ limit: 20 }) // heardFrom writes one per signup",
"mode": "try"
}
}Response200
application/json{
"$type": "Acquisition",
"acquisitions": [
{
"$id": "https: //api.sb/ leaseline.app/ acquisitions/ acquisition_1",
"$type": "Acquisition",
"kind": "search",
"at": "2026-10-22T12: 00: 00Z"
}
],
"meta": {
"limit": 20,
"after": "cursor_2"
}
}
samplePreview| Call | What it does |
|---|---|
POST /{namespace}/leads/{lead}/convert | Convert ends a qualified Lead’s pursuit as a Lead: it opens a Deal or routes the Lead to self-serve checkout. Emits Lead.converted. |
POST /{namespace}/offers/{offer}/trial | Trial starts a Customer on an Offer free for a set number of days, with or without a card, converting or ending by its terms. Emits Offer.trialed. |
POST /{namespace}/orders/place | Place commits a Customer to buy an Offer once and records the Offer Version and price at that moment. Emits Order.placed. |
Compiled, not written: edit the records it reads (compile table; cap), then regenerate. Every step runs from a sentence or a line of code. In your words: the CRM words you know, and where each lives here.