---
title: "Tenancy"
url: /identity/tenancy
---

# Tenancy

> Every record belongs to one scope; each Customer gets its own Namespace and its own layer of your file, and can sell to its own customers.

Tenancy says where every record lives and whose rules it follows. Each Customer gets its own [Namespace](/reference/platform.md#namespace) and its own layer of your file, and the platform is offered again inside it for its own customers.

**Tenancy goes down.**

- The platform › you › a product (one file) › each Customer org › its people, agents and its own customers.
- Each Customer org keeps its records, files and Events in its own Namespace, in its own region.
- The file layers the same way: a template, your file, then each Customer's extension, each narrowing the one above.
- Identity, the runtime, work and commerce are offered again inside each Customer org. Its own customers pay it on its own Stripe account, with your fee on each charge.

## Capability families
| Family | What it does |
| --- | --- |
| Scopes | The platform, then you, then each product, then each Customer org, then its principals. Every record, Event, [Key](/reference/platform.md#key) and receipt belongs to exactly one |
| Namespaces | Each Customer org's records, files, Events and backups in a Namespace of its own: the unit of residency, backup, export and erasure |
| Isolation | A Namespace on shared infrastructure, or on infrastructure of its own for a Customer who needs it; the [Interfaces](/every-product.md) and the file are the same on both |
| Layers of the file | A template per pattern, then your file, then each Customer's extension. Each layer changes only what the layer above leaves open |
| Installed extensions | Extensions other builders publish, installed into one Customer's layer and checked like its own |
| Provisioning | A Customer org and its Namespace made at first sign-up, in its region, on the [Version](/reference/platform.md#version) it first calls |
| Offered again | Identity, the runtime, work and commerce, offered inside each Customer org for its own members, customers and suppliers |
| Payments for your Customers | Each Customer charges its own customers on its own connected Stripe account, and your fee comes off each charge |
| Sharing across orgs | A grant that lets two orgs work one case. Records are never copied, and either org revokes the grant |

Nothing reads across Namespaces. A search, a metric, an export and an agent's tools stop at the Namespace's edge; the one way across is a grant both orgs accept.

The platform holds the templates, the [Verifier](/reference/platform.md#verifier) and the shared infrastructure. You hold your products, team, Stripe account and Domains, and act on them through the [Build and Operator planes](/trust/planes.md). A product holds its file, Versions, Offer, site, portal and docs.

A Customer org holds its Namespace, members, Keys, mandates, extension and connected account, and its members and agents act under its admin's Roles. Its own customers have accounts inside that Namespace.

Tenancy goes down and composition goes sideways. A product built on yours is another seller with scopes of its own, under [composition](/how-it-works.md#composition).

## Lifecycles and states
| Thing | States | What moves it |
| --- | --- | --- |
| A Customer account | `invited`, `active`, `past_due`, `suspended`, `closed`, `erased` | Sign-up, Stripe, and the Customer operations in [Trust and operations](/trust.md) |
| A Namespace | `provisioning`, `serving`, `moving`, `frozen`, `erased` | First sign-up provisions it; a suspension freezes it with every record kept; an erase follows an export |
| A move | `planned`, `copying`, then `done` or `halted` | A new region or isolation tier; the Namespace serves throughout and cuts over at once, and a halted move leaves it where it was |
| A Customer's extension | `checked`, `live`, `held` | The Customer's admin deploys it; your deploy holds it when it no longer checks |
| An installed extension | `installed`, `live`, `held`, `removed` | The Customer's admin; its publisher's new Version is checked before it reaches the layer |
| A connected account | `onboarding`, `enabled`, `restricted` | Stripe's onboarding of the Customer, and any later request Stripe makes |
| A cross-org grant | `offered`, `accepted`, `revoked` | One org offers, the other accepts, and either revokes; a revoke ends every read at once |

A frozen Namespace refuses calls with a reason and still answers its own export. Each move writes its Event: `Namespace.provisioned`, `Namespace.moved`, `Extension.held`, `Grant.revoked`.

## What you declare, what the platform does
| You declare | The platform does |
| --- | --- |
| Nothing for tenancy | Makes a Customer org and its Namespace at first sign-up, and scopes every read, write, search, Watch and export to it |
| The regions you serve | Provisions each Namespace in the region its admin picks, and moves it with its records, files and backups |
| `extend`: what each Customer may add | Checks each extension on every deploy, yours and theirs, and holds one that no longer fits |
| Isolation, by plan | Places each Namespace on shared infrastructure or its own, and moves it when the plan changes |
| `payments` in `offer`: your fee on your Customers' own sales | Onboards each Customer's connected account on Stripe, takes your fee on each charge, and prints it in the sales record |
| Roles your Customers may compose from | Gives each Customer's admin custom Roles for its own members and its own customers |

### Example
Pipeline lets each Customer add fields, rules and [Workflows](/workflow.md) to Deal, and serves the US and the EU. It takes 1% of what each Customer charges its own clients.

```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'] },
  },
  extend: { Deal: { fields: 10, rules: true, workflows: true } },  // each Customer's layer
  operate: { regions: ['us', 'eu'] },                              // each Customer picks one
  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,
    payments: { fee: 0.01 },             // your share of each charge a Customer makes
  },
})
```

One read answers where a Customer lives, what it has added, and how it takes payments.

```http title="Response"
HTTP/1.1 200 OK
Content-Type: application/json
X-Cost: price=0, currency="USD"
X-Request-Id: req_6e0b3f19a27c4d58e2a1

{
  "id": "cus_Acme",
  "product": "pipeline",
  "status": "active",
  "plan": "Team",
  "version": "v4",
  "namespace": { "region": "eu", "isolation": "shared", "status": "serving" },
  "extension": {
    "status": "live",
    "digest": "sha256:9f2c41d7",
    "adds": ["Deal.region", "Deal.win above 20000", "Deal.won: invoice"]
  },
  "payments": { "account": "acct_Acme", "status": "enabled", "fee": 0.01 },
  "members": 7,
  "agents": 2
}
```

That is `GET https://apis.dev/v1/products/pipeline/customers/cus_Acme`, `npx apis.dev customers get cus_Acme` in the CLI, and `getCustomer` over MCP. When Acme wins a Deal, its own Workflow invoices the Company on `acct_Acme`, under Acme's name, and 1% of the charge is yours.

## Contracts with the other subsystems
- **Definition and compile** gives your file and `extend`. Tenancy keeps a checked layer per Customer, and a held one keeps its Customer on the Version before.
- **Identity, access and policy** gives orgs, members, Roles, mandates and grants, and each acts inside one scope.
- **Model and records** keeps records, files, history and projections in one Namespace per Customer, so residency, backup, export and erasure act on it whole.
- **Data and Sources** connects each Customer's [Integrations](/patterns/headless-saas.md#integrations) with credentials held per Namespace, so one Customer's systems never answer another.
- **Runtime** keeps every gate decision, run, Watch and feed inside one Namespace, and runs a Customer's own Workflows in its layer.
- **Work** keeps a queue per Customer, and a grant opens a case two orgs share.
- **Commerce** books each Customer's own sales on its connected account, with your fee line by line.
- **Interfaces and distribution** shows a Customer's own fields and Verbs on its own Interfaces only, under its branding tokens for its own customers.
- **Trust and operations** provisions, suspends, restores, moves, offboards and erases one Namespace at a time.

## What Customers and their agents meet
- **Their own space.** Every list, search, metric and export shows only their records. An empty result says why.
- **Their region.** The admin picks a region at sign-up. Records, files and backups stay there, and a move keeps every record.
- **Their own shape.** The admin, or the admin's agent, adds fields, rules and Workflows inside your limits, over the API, the CLI or MCP. A held extension names the line that no longer fits.
- **Their own customers.** A Customer charges its own clients on its own Stripe account, and they see its name on every invoice and receipt.
- **Their agents, fenced.** An agent's mandate starts at its org and narrows from there. It never reaches another Customer's Namespace.
- **Nothing locked in.** Export takes the whole Namespace, extension included, and an erase follows it.

---

Every record has one home, and every layer of the file narrows the one above, so no Customer's space leaks into another's.