---
title: "Definition and compile"
url: /definition
---

# Definition and compile

> One file becomes a checked, versioned Definition that every Interface, price and record reads, and every change arrives as its diff.

Definition and compile turns one file into a checked, versioned [Definition](/reference/platform.md#definition) that every [Interface](/every-product.md), price and record reads. A deploy is the only way it changes, and the diff is the change.

## Capability families
| Family | What it does |
| --- | --- |
| The grammar | Nouns with fields and [Relationships](/patterns/headless-saas.md), Verbs, lifecycles, [Sources](/patterns/dataset-api.md#how-a-field-is-filled), [Triggers](/patterns.md#the-blocks), [Workflows](/workflow.md), Offers, Roles, staffing and terms, in one typed `definition.ts` |
| The check | Refuses a file that does not fit the grammar, and a business that does not add up |
| The plan | Compares the file with the live [Version](/reference/platform.md#version): every change, each marked when it breaks a caller, with each price and your margin per Verb |
| Deploy and cutover | Publishes the file as a Version with its [Digest](/reference/platform.md#digest), and moves every Interface to it at once |
| Pinning and migration | Keeps each [Key](/reference/platform.md#key), run and open case on the Version it started on, and moves live records to a new shape once, checked first |
| Rollback | Moves every Interface back as one; publishing an older Digest is a rollback |
| Lineage | Stamps every output, from a reply to a docs page, with the Digest it came from |
| Layers | A template per pattern to start from, each Customer's extension inside the limits you set, and extensions other builders publish |
| Generation | Compiles routes, machines, prices, terms, the eleven Interfaces, the landing site, the portal, the docs, the files agents read and the UI contracts |

### What the check refuses
The check reads the business as well as the syntax. Every refusal is a [Problem](/reference.md#errors) with a code, a JSON Pointer `at` and its fix, and nothing that serves changes.

| Check | What it refuses |
| --- | --- |
| Grammar | A key the schema does not hold, a type out of order, a state no move enters |
| Names | A Verb on a reserved path, two Verbs on one name, a Relationship with one side |
| Economics | A Verb with no price, plan or outcome; a price below what its Sources cost you |
| Staffing | A human step whose Role no member, supplier or roster can hold |
| Authority | A move no Role can make, an agent with no mandate that pays for its tools, a legally human act given to an agent |
| Compatibility | A Customer's extension the new file no longer holds, unless that Customer stays on the Version before |

A breaking change is never silent. The plan names it, the deploy asks you to confirm it, and it reaches no caller pinned to the Version before.

## Lifecycles and states
| Thing | States | What moves it |
| --- | --- | --- |
| A deploy | `pending`, then `done` or `refused` | `npx apis.dev deploy`; a refused deploy changes nothing that serves |
| A Version | `live`, `superseded`, `deprecated`, `retired` | The next deploy supersedes it; you deprecate it with a window; it retires when the window ends and no Key, run or case is pinned to it |
| A migration | `planned`, `running`, then `done` or `halted` | It runs with the deploy that needs it; a halted one leaves every record on its old shape |
| A Customer's extension | `checked`, `live`, `held` | The Customer's admin deploys it; your deploy holds it when it no longer checks |

A deploy is an [Action](/workflow.md#the-lifecycle): it waits while it builds, and answers its Version or its Problems. A rollback makes the Version before live again, and the one it replaced is superseded, never deleted. A held extension keeps its Customer on the Version before, and that Customer's admin sees which line no longer checks.

## What you declare, what the platform does
| You declare | The platform does |
| --- | --- |
| `name`, `domain` and the five blocks | Gives every Verb one name on every Interface, and derives each state and Event from its move |
| [Prices](/reference/platform.md#price) in `offer` | Prints your margin per Verb, to you alone, and refuses a price below cost |
| A rename, with `was` | Moves live records to the new name once, and answers the old name to Keys pinned to the old Version |
| `extend`: what each Customer may add | Runs the same check on each Customer's extension, which lives in that Customer's [Namespace](/reference/platform.md#namespace) only |
| A Role on a move or a step | Checks that someone can hold it before the deploy goes live |
| Nothing else | The Digest, the changelog, docs pinned per Version, cutover, pinning, rollback and lineage |

### Example
A rename and an extension policy in one deploy, and the plan that shows both before anything serves.

```ts title="definition.ts"
import { define } from 'apis.dev'

/** Deals for each Customer, kicked off when won. */
export default define({
  name: 'pipeline', domain: 'pipeline.apis.dev',
  Company: { name: 'string', domain: 'url!#', deals: '<-Deal.company' },
  Deal: {
    title: 'string',
    amount: 'decimal(12,2)',  // [!code --]
    value: { type: 'decimal(12,2)', was: 'amount' },  // [!code ++]
    company: '->Company.deals',
    stage: { open: [], qualify: 'opened', win: { in: 'qualified', role: 'manager' },
             lose: ['opened', 'qualified'] },
  },
  extend: { Deal: { fields: 10, rules: true } },  // [!code ++]
  offer: {
    Free: { month: 0, seats: 1, includes: { 'Deal.open': 25 } },
    Team: { month: 49, seats: 5, seat: 9, includes: { 'Deal.open': 1000 } },
    'Deal.open': 0.001,
  },
})
```

```sh title="Terminal"
$ npx apis.dev plan
! breaking: Deal.amount is renamed to Deal.value
  each Key keeps v3, which still answers amount, until it sends Api-Version: v4
  migrate: 1,204 Deals in 38 Customers' Namespaces, checked
+ extend: each Customer may add 10 fields and its own rules to Deal
✓ 38 Customer extensions still check
✓ no price changes: Team 49, Deal.open 0.001
```

## Contracts with the other subsystems
The Definition is what may happen. Every other subsystem reads it and none writes it.

| Subsystem | What the Definition gives it | What it gives back |
| --- | --- | --- |
| Identity, access and policy | Roles, the Role on each move, approvals, the mandate an agent needs, the extension policy | Who deployed, under which Role or mandate: a deploy is a Verb like any other |
| Model and records | Nouns, fields, keys, Relationships, lifecycles, `was` renames | The live record a migration is checked against, Namespace by Namespace |
| Data and Sources | Sources, [Mappings](/patterns/dataset-api.md#how-a-field-is-filled), a ranked `from`, licence terms, schedules | What each Source costs you, which the economic check reads |
| Runtime | Compiled routes, machines, Triggers, [Functions](/patterns.md#function-api) and Workflows | Every Action stamped with its Digest; every run pinned to its Version |
| Work | Staffing: which Role does each human step, at which grade | The roster the staffing check reads |
| Commerce | Offers, the one source of every price | A plan's new price reaching each subscriber at renewal, with a Stripe notice |
| Interfaces and distribution | Everything they render, in one compile | Atomic cutover: every Interface, the site, the portal and the docs on one Version |
| Trust and operations | Test and Live, brakes, retention | The deploy's evidence, the changelog and the outside check of each Version |

## What Customers and their agents meet
Customers never see the file. They see its outputs, all from one Version at a time.

- **A stable contract.** A Key keeps the Version it first called until it sends `Api-Version`. A breaking change reaches no caller who did not ask for it.
- **One changelog.** The landing site prints each Version's changes, and the docs keep a page set per Version with its migration guide.
- **Their own extension.** A Customer's admin adds a field, a rule or a Workflow over any Interface, inside the limits your `extend` sets. The same check answers with the same Problems.
- **Agents read the change.** An agent reads `/openapi.json` and `llms.txt` per Version, sees `Api-Version` on every reply, and moves when its owner moves it.

---

One file, one check and one deploy, so nothing a Customer meets drifts from what the file says.