# Startup root file

URL: /code/project-structure/startup-root · Id: `convention:startup-root`

> The Startup root file marks a Startup and holds its name, the Startup Templates it extends, and its own values, in TypeScript, MDX, or JSON.

The [Startup](/business/nouns/startup) root file marks a Startup and holds its name, the [Startup Templates](/business/nouns/startup-template) it extends, and its own values, in TypeScript, MDX, or JSON.

| Property | Value |
| --- | --- |
| Path | `startup.ts` |
| Holds | [Startup](/business/nouns/startup) |
| Kind | file |
| Leaders | db-first, git-first |
| Team | [Founding Team](/agents/founding) |
| Written by | [Startup.create](/business/nouns/startup/create), [Template.extend](/business/nouns/template/extend), [Change.merge](/business/nouns/change/merge) |
| Compiled by | [StartupBuilder](/code/builders/startup) |

### Example
`startup.ts` in a Startup repository.

```ts title="startup.ts"
import { Startup } from 'startup-builder'

export default Startup({
  name: 'Closewise',
  domain: 'closewise.com',
  extends: 'agent-run-services',
  idea: 'Monthly books for small agencies, reconciled and reviewed.',
  hypothesis: {
    customer: 'Agencies with 5 to 50 staff and no in-house bookkeeper',
    problem: 'Month-end takes three weeks and still misses entries',
    approach: 'Agents reconcile every entry, and a controller reviews each month',
    switch: 'A part-time bookkeeper and a spreadsheet',
    differentiation: 'Books done within three business days of month end',
  },
  msc: { metric: 'outside-revenue', value: 5000, by: '2027-06-30' },
  signup: 'magicLink',
  refundWindow: '14d',
  offers: {
    'monthly-close': {
      price: { amount: 499, currency: 'USD' },
      interval: 'month',
      terms: 'Books done within three business days of month end, tied out to the bank.',
    },
  },
})
```

### Exports
| Export | Kind | Type |
| --- | --- | --- |
| `default` | default | `Startup` |

### Signature
```ts
Startup(definition: StartupDefinition): Startup
```

### Generates
[StartupBuilder](/code/builders/startup) compiles it into these records, Verbs and routes.

| Kind | What |
| --- | --- |
| Records | [Startup](/business/nouns/startup), [Setting](/business/nouns/setting), [Interface](/business/nouns/interface) |
| Verbs | [Startup.create](/business/nouns/startup/create), [Template.extend](/business/nouns/template/extend) |
| Routes | `/{ns}`, `/{ns}/api` |

### Keys
Every key the root file takes, in TypeScript, MDX frontmatter or JSON. A key under a `map` sits below one member, written `*`.

| Key | Type | Default | Description |
| --- | --- | --- | --- |
| <a id="name"></a>`name` | `string` | Required | The Startup’s name, as buyers see it. Example: `'Closewise'`. Read by [StartupBuilder](/code/builders/startup). |
| <a id="domain"></a>`domain` | `url` | None. | Its home Domain; its Sites, API and docs serve there. Example: `'closewise.com'`. Read by [SiteBuilder](/code/builders/site). |
| <a id="extends"></a>`extends` | `startup-template` | None. | The Startup Template it extends; everything it does not set is inherited from it. Example: `'agent-run-services'`. Read by [StartupBuilder](/code/builders/startup). |
| <a id="idea"></a>`idea` | `text` | None. | The Idea in one sentence. Example: `'Monthly books for small agencies, reconciled and reviewed.'`. Read by [StartupBuilder](/code/builders/startup). |
| <a id="hypothesis"></a>`hypothesis` | `object` | None. | The Founding Hypothesis, one key per slot. Read by [StartupBuilder](/code/builders/startup). |
| <a id="hypothesis-customer"></a>`hypothesis.customer` | `text` | None. | Who it is for. Example: `'Agencies with 5 to 50 staff and no in-house bookkeeper'`. Read by [StartupBuilder](/code/builders/startup). |
| <a id="hypothesis-problem"></a>`hypothesis.problem` | `text` | None. | What they struggle with. Example: `'Month-end takes three weeks and still misses entries'`. Read by [StartupBuilder](/code/builders/startup). |
| <a id="hypothesis-approach"></a>`hypothesis.approach` | `text` | None. | How the Startup solves it. Example: `'Agents reconcile every entry, and a controller reviews each month'`. Read by [StartupBuilder](/code/builders/startup). |
| <a id="hypothesis-switch"></a>`hypothesis.switch` | `text` | None. | What they use today and would leave. Example: `'A part-time bookkeeper and a spreadsheet'`. Read by [StartupBuilder](/code/builders/startup). |
| <a id="hypothesis-differentiation"></a>`hypothesis.differentiation` | `text` | None. | Why they would switch. Example: `'Books done within three business days of month end'`. Read by [StartupBuilder](/code/builders/startup). |
| <a id="msc"></a>`msc` | `object` | None. | The Minimum Success Criteria: the Metric, the value and the date that make the Startup worth keeping. Read by [StartupBuilder](/code/builders/startup). |
| <a id="msc-metric"></a>`msc.metric` | `metric` | None. | The Metric it is judged on. Example: `'outside-revenue'`. Read by [StartupBuilder](/code/builders/startup). |
| <a id="msc-value"></a>`msc.value` | `number` | None. | The value the Metric must reach. Example: `5000`. Read by [StartupBuilder](/code/builders/startup). |
| <a id="msc-by"></a>`msc.by` | `date` | None. | The date it must reach it by. Example: `'2027-06-30'`. Read by [StartupBuilder](/code/builders/startup). |
| <a id="reserve"></a>`reserve` | `object` | None. | The reserve page’s two values nothing else supplies: the ship date and the threshold. Read by [SalesBuilder](/code/builders/sales). |
| <a id="reserve-ships"></a>`reserve.ships` | `date` | None. | The date reservers are told the product ships. Example: `'2027-01-15'`. Read by [SalesBuilder](/code/builders/sales). |
| <a id="reserve-threshold"></a>`reserve.threshold` | `object` | None. | The bar the reserve test must clear, fixed before the page goes live. Read by [SalesBuilder](/code/builders/sales). |
| <a id="reserve-threshold-deposits"></a>`reserve.threshold.deposits` | `number` | None. | How many outside deposits pass the test. Example: `8`. Read by [SalesBuilder](/code/builders/sales). |
| <a id="reserve-threshold-reached"></a>`reserve.threshold.reached` | `number` | None. | How many people the page must reach. Example: `40`. Read by [SalesBuilder](/code/builders/sales). |
| <a id="reserve-threshold-by"></a>`reserve.threshold.by` | `date` | None. | The date the deposits must arrive by. Example: `'2026-11-05'`. Read by [SalesBuilder](/code/builders/sales). |
| <a id="offers"></a>`offers` | `map` | None. | Its own Offers, keyed by id; a larger Offer lives in `offers/`. Read by [SalesBuilder](/code/builders/sales). |
| <a id="offers-price"></a>`offers.*.price` | `money` | None. | The amount and currency it charges each interval. Example: `{ amount: 499, currency: 'USD' }`. Read by [SalesBuilder](/code/builders/sales). |
| <a id="offers-interval"></a>`offers.*.interval` | `string` | None. | How often it bills: `once`, `day`, `week`, `month` or `year`. Example: `'month'`. Read by [SalesBuilder](/code/builders/sales). |
| <a id="offers-terms"></a>`offers.*.terms` | `text` | None. | What the buyer gets, in one sentence. Example: `'Books done within three business days of month end.'`. Read by [SalesBuilder](/code/builders/sales). |
| <a id="routes"></a>`routes` | `map` | None. | Routes to a Custom Implementation, keyed by path; every other route is generated. Read by [SoftwareBuilder](/code/builders/software). |
| <a id="routes-to"></a>`routes.*.to` | `string` | None. | The program in `code/` that serves the route. Example: `'code/legacy-webhook'`. Read by [SoftwareBuilder](/code/builders/software). |
| <a id="routes-reason"></a>`routes.*.reason` | `text` | Required | Why no Verb, saved query or MCP tool could serve it. Example: `'A partner posts form-encoded webhooks that no Verb accepts.'`. Read by [SoftwareBuilder](/code/builders/software). |
| <a id="locale"></a>`locale` | `string` | `'en-US'` | The language and region its Pages and Messages are written for. Example: `'en-GB'`. Read by [SiteBuilder](/code/builders/site). |
| <a id="signup"></a>`signup` | `string` | `'email'` | How a buyer signs up: `email`, `workEmail`, `magicLink`, `keyless`, `apiKey`, `oauth` or `agentIdentity`. Example: `'magicLink'`. Read by [SoftwareBuilder](/code/builders/software). |
| <a id="double-opt-in"></a>`doubleOptIn` | `boolean` | `false` | Whether a Waitlist sign-up confirms by email before it counts. Example: `true`. Read by [SiteBuilder](/code/builders/site). |
| <a id="price-unit"></a>`priceUnit` | `string` | `'seat'` | The unit its Prices count by default. Example: `'month'`. Read by [SalesBuilder](/code/builders/sales). |
| <a id="trial"></a>`trial` | `string` | `'14d'` | How long a trial runs before the first charge. Example: `'30d'`. Read by [SalesBuilder](/code/builders/sales). |
| <a id="agreement"></a>`agreement` | `string` | `'clickwrap'` | How a buyer accepts the terms: `clickwrap` or `msa`. Example: `'msa'`. Read by [SalesBuilder](/code/builders/sales). |
| <a id="terms-template"></a>`termsTemplate` | `string` | `'standard'` | Which terms Template its `/terms` Page is built from: `standard`, `developer`, `b2b`, `consumer` or `agent`. Example: `'b2b'`. Read by [SalesBuilder](/code/builders/sales). |
| <a id="tax-display"></a>`taxDisplay` | `string` | `'exclusive'` | Whether Prices show tax: `exclusive`, `inclusive` or `reverseCharge`. Example: `'inclusive'`. Read by [SalesBuilder](/code/builders/sales). |
| <a id="refund-window"></a>`refundWindow` | `string` | `'30d'` | How long after a charge a refund is granted without review. Example: `'14d'`. Read by [SalesBuilder](/code/builders/sales). |
| <a id="consent"></a>`consent` | `string` | `'strictest'` | Whose consent rules apply: the strictest everywhere, or each region’s own. Example: `'byRegion'`. Read by [SiteBuilder](/code/builders/site). |
| <a id="approval-hours"></a>`approvalHours` | `number` | `48` | How long an Approval waits before it escalates. Example: `24`. Read by [StartupBuilder](/code/builders/startup). |
| <a id="budget"></a>`budget` | `number` | `200` | Its monthly spend budget, in USD, before an Approval. Example: `500`. Read by [StartupBuilder](/code/builders/startup). |
| <a id="auto-upgrade"></a>`autoUpgrade` | `string` | `'onGreen'` | When a Startup Template upgrade merges: `onGreen`, `qualityGates` or `manual`. Example: `'manual'`. Read by [StartupBuilder](/code/builders/startup). |
| <a id="close-by-day"></a>`closeByDay` | `number` | `5` | The business day of the month by which the books close. Example: `3`. Read by [StartupBuilder](/code/builders/startup). |

### Errors
A push whose root file breaks a key fails `sb/parse` with one of these, naming the line.

| Error | Cause | Keys |
| --- | --- | --- |
| [Wrong type](/code/api/errors/wrong-type) | A key in the Startup root file holds a value of another type than the key takes. | Every key |
| [Not literal](/code/api/errors/not-literal) | A key in the Startup root file is computed by a loop, a call or an expression, so it cannot be parsed. | Every key |
| [Missing key](/code/api/errors/missing-key) | The Startup root file leaves out a key it requires, such as the Startup’s name. | [`name`](#name), [`routes.*.reason`](#routes-reason) |
| [Setting set twice](/code/api/errors/setting-set-twice) | A Setting is set both in the Startup root file and in the Settings file, so its value has two homes. | 14 keys |