Definition and compile
Open in
Definition and compile turns one file into a checked, versioned Definition that every Interface, 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, Verbs, lifecycles, Sources, Triggers, Workflows, 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: 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, and moves every Interface to it at once |
| Pinning and migration | Keeps each 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 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: 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 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 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.
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)',
value: { type: 'decimal(12, 2)', was: 'amount' },
company: '->Company.deals',
stage: { open: [], qualify: 'opened', win: { in: 'qualified', role: 'manager' },
lose: ['opened', 'qualified'] },
},
extend: { Deal: { fields: 10, rules: true } },
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,
},
})$ 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.001Contracts 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, a ranked from, licence terms, schedules | What each Source costs you, which the economic check reads |
| Runtime | Compiled routes, machines, Triggers, Functions 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
extendsets. The same check answers with the same Problems. - Agents read the change. An agent reads
/openapi.jsonandllms.txtper Version, seesApi-Versionon 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.