---
title: "The Build and Operator planes"
url: /trust/planes
---

# The Build and Operator planes

> Every act a console offers you is a Verb on the platform API first, so your team, your CLI and your agents run the product with no UI.

A plane is the set of Verbs one kind of principal acts through. You build through the Build plane, and run Customers and money through the Operator plane, over the API, the CLI or MCP.

**Every console act is a Verb first.**

- A console, `npx apis.dev`, MCP tools and HTTP all call one platform API, `https://apis.dev/v1`.
- Each call meets one decision on the caller's Role or mandate. Pending waits for an approver or the Customer's consent; refused answers 402, 403 or 409 with its cure.
- Allowed reaches the Build plane: check, plan, deploy, rollback, [Versions](/reference/platform.md#version), secrets, Domains, the move to Live, your team.
- Or it reaches the Operator plane: Customers, refunds, support access, payouts, incidents, brakes, Customer operations.
- The gate commits the act, its Event and its evidence, and every Event reaches every console.

Four planes share the [one decision](/identity.md#decision). You, your team and your coding agent act through the [Build](#build) plane, and you, your staff and your operator agents through the [Operator](#operator) plane. Each Customer's members and agents use the Customer plane, which is [the developer portal](/interfaces/site-portal-docs.md#portal), and suppliers and workers use [the supply plane](/work/supply.md).

Each console renders one or more planes and invents nothing. A console that needs a state, a move or a reason no plane holds marks a capability the platform is missing.

## Capability families
### The Build plane
| Family | Verbs | What they do |
| --- | --- | --- |
| [Products](/reference/platform.md#product) | `Product.create`, `Product.list`, `Product.archive` | Start a product from a template, list yours, and archive one with its record kept |
| Check and plan | `Check.run`, `Plan.create` | Every [Problem](/reference.md#errors) and every breaking change, with price and margin per Verb, before anything serves |
| Deploy and roll back | `Deploy.create`, `Rollback.create` | Publish a [Version](/reference/platform.md#version) to every [Interface](/every-product.md) at once, or move them all back |
| Versions | `Version.list`, `Version.deprecate`, `Version.retire` | What each [Key](/reference/platform.md#key), run and case is pinned to; a deprecation with its window; retirement once nothing is pinned |
| Environments | `Environment.promote` | The move from Test to Live, which a person approves |
| Secrets | `Secret.set`, `Secret.rotate`, `Secret.delete` | A [Source](/patterns/dataset-api.md#how-a-field-is-filled)'s credentials, outside the file and never shown |
| Domains | `Domain.add`, `Domain.verify`, `Domain.remove` | Your Domains for the API, the site, the portal and the docs, beside the free [Host](/reference/platform.md#host) |
| Extensions | `Extension.list`, `Extension.get` | Each Customer's extension, and the line that holds one |
| Your team | `Teammate.invite`, `Teammate.remove`, `Teammate.assign`, `Token.create`, `Token.revoke` | Who on your team builds or operates, under which Role, and tokens for CI and agents |

### The Operator plane
| Family | Verbs | What they do |
| --- | --- | --- |
| Customers | `Customer.list`, `Customer.search`, `Customer.get` | Each Customer's plan, usage, spend, region, extension, members and open disputes |
| Plans and credits | `Subscription.change`, `Subscription.cancel`, `Credit.grant`, `Coupon.create` | A plan change, a cancellation, credits or a coupon, each at the Offer's prices |
| Refunds and disputes | `Refund.grant`, `Refund.decline`, `Dispute.answer` | Refunds outside the published rule, decided by the person you name; disputes answered with the receipt and the [call record](/reference/platform.md#call-record) |
| Payouts and the sales record | `Payout.list`, `Payout.get`, `Sale.list`, `Sale.export` | Every payout to you and to each supplier, and every sale, refund, fee and tax line behind it |
| Support access | `SupportGrant.request`, `SupportGrant.end`, `SupportGrant.reads` | Time-boxed access a Customer consents to, and every read made inside it |
| Incidents | `Incident.open`, `Incident.update`, `Incident.resolve` | Posts to the status page on your Domain and to every Watch |
| Calls and evidence | `Call.get`, `Call.replay`, `Log.follow`, `Trace.get` | Any call by its request id, replayed against its Version; logs as they happen; a trace across every hop |
| Brakes and approvals | `Brake.release`, `Approval.grant`, `Approval.decline` | A held run released, or a move held for a person decided |
| Customer operations | `Customer.provision`, `Customer.suspend`, `Customer.restore`, `Customer.move`, `Customer.offboard`, `Customer.erase` | Each with its reason and its Event, and the Customer told |
| Suppliers | `Supplier.verify`, `Supplier.pause`, `Supplier.remove` | Who may sell in a Marketplace or a [Service API](/patterns/service-api.md), and a stop with the record kept |
| Keys | `Key.revoke` | A leaked Key revoked, and its holder told |

The Operator plane sees each Customer's account, plan, usage and money. It never reads inside a Customer's [Namespace](/reference/platform.md#namespace) without a support grant.

A refund the published rule allows needs no plane, since it is paid with no person. A support desk, a sales funnel and the company's books run outside the product, on its Events and through these Verbs.

## Lifecycles and states
| Thing | States | What moves it |
| --- | --- | --- |
| A deploy | `pending`, then `done` or `refused` | `Deploy.create`; a refused deploy changes nothing that serves |
| A Version | `live`, `superseded`, `deprecated`, `retired` | The next deploy, a deprecation with its window, and retirement when nothing is pinned |
| An environment | `test`, then `live` | `Environment.promote`, approved by a person |
| A Domain | `added`, `verifying`, `verified`, `removed` | One DNS record verifies it; the free Host keeps answering throughout |
| A teammate | `invited`, `active`, `removed` | You or an admin on your team; a removal ends every token they made |
| A Customer account | `invited`, `active`, `past_due`, `suspended`, `closed`, `erased` | Sign-up, Stripe, and the Customer operations; a restore returns `suspended` to `active` |
| A support grant | `requested`, then `consented` or `declined`; a consented grant is `active`, then `ended` | The Customer's admin consents; the time box, the Customer or you end it |
| A `Refund` | `requested`, `granted` or `declined`, `paid` | The published rule with no person, or the approver you name |
| A `Dispute` | `opened`, `answered`, then `upheld` or `denied` | The Customer opens it with the receipt; you answer with the call record and terms |
| A `Payout` | `earned`, `pending`, `paid`, or `reversed` | Stripe's schedule; a refund or an upheld dispute reverses its line |
| An incident | `investigating`, `identified`, `monitoring`, `resolved` | A failing check opens it; each update posts to the status page and to Watches |
| A brake | `armed`, `tripped`, `held`, then `released` or `reset` | A cap reached before a call runs; a person releases it, or the period resets it |
| A supplier | `applied`, `verifying`, `verified`, `paused`, `removed` | Verification, then you or the supplier |

Each row is the same state the Customer, the supplier or the buyer sees on its own side. Each move writes its Event and its actor: a person under a Role, or an agent under a mandate.

## What you declare, what the platform does
| You declare | The platform does |
| --- | --- |
| Your team's [Roles](/reference/platform.md#role): who builds, who operates, and which Verbs each may call | Applies them to every plane Verb on every Interface; a missing Role answers 403 `role_required` |
| Approvals on operator moves: a refund above an amount, an erase, the move to Live | Holds the move, sends the Approval URL, and runs it once on the grant |
| What your agents may do alone | Requires a mandate on every agent call, and holds the moves you reserve for a person |
| How long support access lasts, and what it may read | Asks the Customer's admin to consent, opens the grant for that long, and records every read |
| Nothing else | Every plane Verb on the API, the CLI and MCP; an Event for every act; the evidence of every decision |

### Example
Pipeline's team splits support from finance, holds refunds above $100 for finance, and caps support access at two hours of reads.

```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)', company: '->Company.deals',
    stage: { open: [], qualify: 'opened', win: 'qualified', lose: ['opened', 'qualified'] },
  },
  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,
  },
  operate: {
    team: {                                               // your staff, not your Customers' members
      support: ['Customer.get', 'SupportGrant.request', 'Incident.update'],
      finance: ['Refund.grant', 'Credit.grant', 'Payout.list'],
    },
    approve: { 'Refund.grant': { above: 100, by: 'finance' }, 'Customer.erase': { by: 'owner' } },
    agents:  { approve: ['Customer.suspend'] },           // an operator agent's suspension waits for a person
    support: { for: '2h', see: ['Company', 'Deal'] },     // read-only, and only with consent
  },
})
```

The operator agent asks Acme for access to look into a refused move. Nothing is read until Acme's admin consents.

```http title="Response"
HTTP/1.1 202 Accepted
Content-Type: application/json
Location: /v1/products/pipeline/customers/cus_Acme/support-grants/grant_1
X-Action-Id: act_31
X-Cost: price=0, currency="USD"
X-Request-Id: req_2a7d90c4e1b35f68a0c2

{
  "id": "grant_1",
  "customer": "cus_Acme",
  "see": ["Company", "Deal"],
  "for": "2h",
  "status": "requested",
  "reason": "Deal.win refused with wrong_state since 09:00",
  "consent": "https://pipeline.apis.dev/consents/grant_1",
  "mandate": ["you", "agent_ops"]
}
```

That is `POST https://apis.dev/v1/products/pipeline/customers/cus_Acme/support-grants`, `npx apis.dev support request cus_Acme --for 2h` in the CLI, and `requestSupportGrant` over MCP. Acme's admin consents on the link or through the API, and each read lands in Acme's audit log as it happens.

## Contracts with the other subsystems
- **Definition and compile** runs check, plan, deploy and rollback as Verbs, each with its actor and [Digest](/reference/platform.md#digest).
- **Identity, access and policy** gives your team's Roles, operator mandates, approvals and consent, and holds support access as a grant the Customer owns.
- **Model and records** shows your Customers' accounts and views, and nothing inside a Namespace without a grant.
- **Data and Sources** reports each Source's health, and a Source's failure opens an incident with its trace.
- **Runtime** takes every plane act through the same gate as an [Action](/workflow.md#the-lifecycle), and holds runs for release.
- **Work** gives the queues, cases and suppliers that operators verify, pause or reassign.
- **Commerce** gives subscriptions, refunds, disputes, payouts and the sales record, and takes refunds outside the rule, credits and plan changes at the Offer's prices.
- **Interfaces and distribution** posts incidents and deprecation notices on your Domain, in the states the portal shows.
- **Trust and operations** gives incidents, brakes, the proof record and Customer operations, with the evidence of who moved each.

## What your team and your Customers meet
- **Your coding agent.** It writes the file, checks, plans, deploys and rolls back through the Build plane, under a token or mandate you give it.
- **Your operator agent.** It sees a Customer turn `past_due`, reads the account and proposes a suspension, which waits for a person. A refund above $100 waits for finance.
- **Your staff.** Each sees only the Verbs their Role holds, in any console or the CLI, and every act carries their name.
- **Customers.** Your support team reads nothing without its consent. A suspension names its reason and its cure, and every change you make shows in its portal as an Event.
- **A supplier.** A pause or a removal names its reason, and its payouts and track record are kept.

---

Every act a console offers is a Verb first, so the product runs the same whether a person clicks or an agent calls.