URL: /code/files/funnels · Id: `page:/code/files/funnels`

# 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](https://startupbuilder.dev/business/nouns/lead) where they heard of you. SalesBuilder compiles it, and `show` traces every key.

```mdx title="funnels/signup.mdx"
---
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.
```

```text title="show"
$ 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      SalesBuilder
```

```text title="leaseline.app"
leaseline.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.lock
```

## The 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 (<Op verb="Acquisition.list" />) | — |

## Refusals
| Code | Fix, then the call that clears it |
| --- | --- |
| [`cluster`](/code/refusals#check-cluster) | Offer the plain trial; the account keeps every other term. Then <Op verb="Offer.trial" />. |

## Calls

```text title="funnels/ compiled · Ask"
Create our signup flow, then show where new people heard of us.
```

```ts title="funnels/ compiled · SDK"
import { $ } from 'startup-builder'

await $.Funnel.create({ steps: {} }, { mode: 'try' })   // funnels/signup.mdx
return await $.Acquisition.list({ limit: 20 })   // heardFrom writes one per signup
```

```json title="funnels/ compiled · Response · sample"
{
  "$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"
  }
}
```

| Call | What it does |
| --- | --- |
| <a id="lead-convert"></a><Op verb="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`](/code/events#lead-converted). |
| <a id="offer-trial"></a><Op verb="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`](/code/events#offer-trialed). |
| <a id="order-place"></a><Op verb="Order.place" /> | Place commits a Customer to buy an Offer once and records the Offer Version and price at that moment. Emits [`Order.placed`](/code/events#order-placed). |