# Anatomy of an App

URL: /products/app/anatomy · Id: `page:products/app/anatomy`

> What one App declaration compiles, where each rule lives, how the four App kinds differ, and which host a Customer calls.

An [App](/business/nouns/app) is one declaration over a [Product](/business/nouns/product)'s [Nouns](/business/nouns/noun) and [Verbs](/business/nouns/verb). [SoftwareBuilder](/code/builders/software) compiles every screen, route, package and plan from it, so no part carries a second copy of a rule.

## Compiled from one declaration
Leaseline declares a `Lease` Noun, with Verbs such as `Lease.renew` and `Lease.notify`. Its App folder adds who signs in and what each [Persona](/business/nouns/persona) may call:

```mdx title="apps/portal/app.mdx"
---
kind: saas
mount: /app
nouns: [Lease]
personas:
  manager: { may: [Lease.create, Lease.renew, Lease.notify] }
  resident: { may: [Lease.get] }
---
```

Every part below compiles from that file and the records it names.

Compiled from one declaration, `apps/portal/app.mdx`:

| Part | What you get | Compiled from |
| --- | --- | --- |
| [Screens](/products/app/app-shell) | A list and a record per Noun, a form per Verb, at leaseline.app/app | Nouns and each Persona’s Verbs |
| [API](/products/api) | Every Verb as a route at api.leaseline.app | Verbs |
| [SDK, CLI and MCP](/code/builders/software/interfaces) | The leaseline packages and MCP server | Verbs |
| [Webhooks](/products/app/life-of-a-request) | Every Event, signed Leaseline-Signature | Events |
| [Tenants](/products/app/tenancy-and-identity) | One per Customer, made when it accepts an Offer | Offers |
| [Sign-in and members](/products/app/tenancy-and-identity) | Passkeys, email links, single sign-on and invitations | Personas and Access Levels |
| [Plans in the App](/products/app/sell) | Locked buttons, usage caps, seats and billing screens | Offers and Entitlements |
| [Admin](/products/app/your-back-office) | Every record, the data editor and Settings | Nouns |
| [Docs](/code/builders/software/publication) | leaseline.app/docs, with llms.txt and Markdown per page | Nouns and Verbs |
| [Agent renderings](/business/nouns/dashboard) | Every screen as Markdown and JSON | the same screens |

Add `Lease.answer` to the definition, and one merge adds its route, SDK method, CLI command, MCP tool, webhook [Event](/business/nouns/event) and button on every [Interface](/business/nouns/interface). A [Function](/business/nouns/function) runs behind each Verb, written as code, run by a model, or done by a person, and the caller never sees which.

## Rules live in Verbs
A rule belongs to the Verb that enforces it, never to a field or a screen. `Lease.renew` runs only on a lease in `renewing`, so its button appears only there.

A call that breaks a rule returns a `refused` [Action](/business/nouns/action) that names the rule, on every Interface. So the App never holds a rule the API lacks. A person clicking and an [Agent](/business/nouns/agent) calling always agree.

## App kinds
The `kind` key picks the App's shape. Each kind compiles the shared parts above, plus what its own users need.

| `kind` | What it adds | Example |
| --- | --- | --- |
| `saas` | A [Tenant](/business/nouns/tenant) per [Customer](/business/nouns/customer), sign-in, members, and the plan inside the App | Leaseline's App for property managers |
| `admin` | Every record across Tenants, the data editor and [Settings](/business/nouns/setting) | Leaseline's admin App, which every App gets |
| `directory` | Public list and record pages over a [Collection](/business/nouns/collection), with search | Ratebook's sales-tax rates by state |
| `commerce` | A public catalog of [Offers](/business/nouns/offer), a cart, checkout and the buyer's [Orders](/business/nouns/order) | Kiln Bakery's weekly loaf |

### `saas`
A `saas` App is private and per Customer, and no record crosses from one Tenant to another. It compiles a Tenant on each accepted Offer, with sign-in by passkey, email link or single sign-on. Invitations, and the plan's locks and caps, reach every screen.

### `admin`
An `admin` App is for the people and agents who run the business. It shows every record of every Noun across Tenants, the [data editor](/code/systems/data-editor), Settings, and each [Approval](/business/nouns/approval) waiting on the reader. Every App ships one at `/admin`, and a Customer's admins get the same screens scoped to their own Tenant.

### `directory`
A `directory` App is public. It compiles a list page and a record page for each member of a Collection, with search and filters, and readers need no account. A Verb behind an Offer, such as a bulk download, asks the reader to buy first.

### `commerce`
A `commerce` App sells in public. It compiles a catalog of Offers, a cart, checkout and each buyer's Orders and receipts. A buyer signs in only to see past Orders.

## Two planes
Two kinds of caller reach the same records, on two hosts.

| Caller | Host | Package and key | Sees |
| --- | --- | --- | --- |
| Leaseline's Customers and their agents | `api.leaseline.app`, an alias of `leaseline.app/api` | `leaseline`, `LEASELINE_API_KEY` | Their own Tenant, and only the Verbs their plan grants |
| Leaseline's builders: the founder and the agents | `api.sb/leaseline.app` | `startup-builder`, `STARTUP_BUILDER_API_KEY` | Every Tenant, every Verb, and the definition itself |

Examples on these pages switch between the two with **As your customer** and **As the builder**. A Customer never sees the builder's host, packages or key names. [What Customers see](/code/builders/software/publication) lists every part of that boundary.

## Next
[Life of a request](/products/app/life-of-a-request) follows one click through the parts above.