---
url: https://saas.dev/docs/your-docs
md: https://saas.dev/docs/your-docs.md
---

# Your docs

`leaseclock.com/docs` has a page for every Noun and Verb, with examples that run against Test. Every page is also served as Markdown, so your customers' agents read the same docs your customers do.

## In short

[Leaseclock's docs page for renewing a lease](https://leaseclock.com/docs/lease#renew)

Your customers get a docs site at `/docs` on your domain, in your theme, and you write none of it. Each Noun has a page with its fields and the calls that list, read, create and update it. Each Verb has a section on its Noun's page, with its input and the same call in curl, TypeScript, the CLI and MCP. A field you add is documented the moment it exists.

[Open leaseclock.com/docs](https://leaseclock.com/docs)

## Leaseclock's docs

Leaseclock's docs open on Quickstart and API keys, then give Lease and Unit a page each. Priya Shah, the leasing coordinator at Northgate Rentals, opens [`leaseclock.com/docs/lease#renew`](https://leaseclock.com/docs/lease#renew) when she scripts the month's renewals. Every heading, row and example on that page comes from one file:

```yaml title="Noun/Lease.mdx"
---
name: Lease
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:
  renew:
    does: Move the end date forward
    input: { endsOn: { says: the new end date, type: date, required: true } }
    from: [active]
  end: { does: End the lease, from: [active], to: ended }
---
```

Each line decides something a reader sees:

| In the definition | On `leaseclock.com/docs` |
| --- | --- |
| `name: Lease` | The page `/docs/lease`, titled Lease, with its own group in the sidebar |
| `unit: { type: link, target: Unit }` | A `unit` field that links to the Unit page |
| `renter: { type: email }` | A `renter` field typed email, filled with Dana Whitfield's address in every Lease example |
| `indexed: true` | `endsOn` listed among the list call's filters and sort keys |
| `status: { type: choice, … }` | A `status` field with its two values, `active` and `ended` |
| `required: true` | A *required* mark, and the error a call without the field returns |
| `does: Move the end date forward` | A section titled "Renew a Lease" that opens with "Moves the end date forward" |
| `says: the new end date` | The `endsOn` input, described as "The new end date" |
| `from: [active]` | "Runs on an active Lease", and the error that renewing an ended Lease returns |
| `end: { …, to: ended }` | A section titled "End a Lease" that says the Lease moves to `ended` |
| `limits: { Unit: 200 }` in `Offer/pro.mdx` | "Leaseclock Pro allows 200 Units" on the Unit page, and the error the 201st Unit returns |

## Examples that run against Test

Every example comes in four forms: curl, TypeScript, the CLI and MCP. A signed-in reader's examples point at their own Test workspace, and **Run** sends the call there and shows the response in place. Test is a full copy of Leaseclock where no real charge happens, so Priya can renew 4B from the docs without touching Northgate's live leases.

These are the four forms of the renew example on `leaseclock.com/docs/lease#renew`:

**API**

```bash
curl -X POST https://leaseclock.com/api/leases/4b/renew \
  -H "Authorization: Bearer $LEASECLOCK_TOKEN" \
  -d '{ "endsOn": "2027-11-30" }'
```

**CLI**

```bash
npx leaseclock do Lease.renew 4b --endsOn 2027-11-30
```

**SDK**

```ts title="renew.ts"
import { Leaseclock } from 'leaseclock'

const $ = new Leaseclock({ token: process.env.LEASECLOCK_TOKEN })

const lease = await $.Lease.renew('4b', { endsOn: '2027-11-30' })
```

**MCP**

```json title="do"
{
  "verb": "Lease.renew",
  "id": "4b",
  "input": { "endsOn": "2027-11-30" }
}
```

Run shows what the API returns: the Lease as it now stands, and the link that undoes the renewal.

```json title="200 OK"
{
  "$id": "https://leaseclock.com/api/leases/4b",
  "$type": "Lease",
  "unit": "4b",
  "renter": "dana.whitfield@example.com",
  "endsOn": "2027-11-30",
  "status": "active",
  "renewedBy": "priya@northgaterentals.com",
  "undo": "https://leaseclock.com/api/leases/4b/undo"
}
```

Each push of your definition runs every example against Test before the new version is served. A call printed in your docs is a call your API accepts.

## Markdown for agents

Every docs page has a Markdown copy at the same path with `.md` added. A request for the page with `Accept: text/markdown` gets the same Markdown, and each page has a **Copy Markdown** button for pasting into Claude, ChatGPT or Cursor.

```bash
curl https://leaseclock.com/docs/lease.md
```

````md title="leaseclock.com/docs/lease.md"
## Renew a Lease

Moves the end date forward. Runs on an active Lease, and keeps its status.

| Input | Type | Description |
| --- | --- | --- |
| `endsOn` (required) | date | The new end date |

```bash
curl -X POST https://leaseclock.com/api/leases/4b/renew \
  -H "Authorization: Bearer $LEASECLOCK_TOKEN" \
  -d '{ "endsOn": "2027-11-30" }'
```

Returns the Lease. Undo it with `POST /api/leases/4b/undo`.
````

[`leaseclock.com/llms.txt`](https://leaseclock.com/llms.txt) lists every docs page with a one-line summary, so an agent finds the Lease page without crawling the site. The [Site](https://saas.dev/docs/site.md) page covers `llms.txt` and the OpenAPI file.

## Your own pages

Write a guide, such as one on renewing a building's leases in one pass, as an MDX file in `Docs/` and push it with the definition. `Docs/bulk-renewals.mdx` is served at `leaseclock.com/docs/bulk-renewals`, in the sidebar beside the generated pages, in your theme, with its own Markdown copy and its own line in `llms.txt`.

Text under a Noun's frontmatter opens that Noun's page:

```mdx title="Noun/Lease.mdx"
---
name: Lease
# fields and verbs as before
---

A Lease ties a renter to a Unit until a date. Renew it before `endsOn` and the renter keeps the unit.
```

To replace a generated page with your own React component, see [Defaults and overrides](https://saas.dev/docs/overrides.md).

## Questions

**When does a change reach the docs?**
On the next request after you push it. When Lease gained a `rent` field, `leaseclock.com/docs/lease` gained a `rent` field typed money, the create example gained a rent value, and the changelog entry "Leases now track rent" linked to the page. The [Blog](https://saas.dev/docs/blog.md) page covers the changelog.

**Do the docs carry my brand?**
Yes. They are served at `leaseclock.com/docs` in Leaseclock's teal theme, under Leaseclock's name. Nothing on them names SaaS.Dev.

**Who can read them?**
Anyone, without signing in. Run needs a signed-in reader, and sends calls only to that reader's own Test workspace. Each reader sees the Verbs their role may run, so a Verb kept to your team appears only in your team's docs.

**Which languages do the examples use?**
curl, TypeScript with the `leaseclock` package, the `npx leaseclock` CLI, and MCP tool calls. The [SDK](https://saas.dev/docs/sdk.md), [CLI](https://saas.dev/docs/cli.md) and [MCP](https://saas.dev/docs/mcp.md) pages cover each one.

**Can a customer's agent read the docs and act on them?**
Yes. The agent reads `leaseclock.com/docs/lease.md` to learn renew's input, then calls `do` on `leaseclock.com/mcp` with that same input, under the customer's own permissions.
