tenants

Create

Provisions a new tenant. System-admin only — 403 for any other caller, since there is no existing tenant row yet for a resource-level check to apply to. owner_person_id is required: it names the person this workspace belongs to for workspace-plan accounting, and a workspace created without one would count against nobody's plan permanently (400 owner_person_id_required; 400 owner_person_not_found if it names no person). An operator provisioning a workspace FOR a customer names the customer — to own it themselves they pass their own person id. The owner's plan allowance is deliberately NOT enforced on this path: an operator grant may legitimately exceed a plan (a comp, a pilot), and the excess is then visible as owned above workspace_slots on getSelfServeTenantAllowance rather than hidden as an unowned workspace.

post/tenants

Request

  • Base URL: https://api.instruxi.dev/api/v1/enforcer
  • URL: https://api.instruxi.dev/api/v1/enforcer/tenants
  • Auth: one of:
    • API key in header Authorization
    • API key in header X-API-Key

Request body

auth_providerstring
descriptionstring
generate_codeboolean
namestring
owner_person_idstring

OwnerPersonID is the PERSON this workspace belongs to for workspace-plan accounting (tenants.owner_person_id, 000104). REQUIRED — a required field on an existing endpoint, added deliberately.

WHY IT IS REQUIRED. Until now this path wrote no owner at all, so every workspace an operator created was born belonging to nobody and counted against nobody's plan, permanently and silently. That is a revenue leak that grows with every operator action, and it is invisible: the customer sees "0 of 2 used" while running workspaces.

WHY NOT DEFAULT TO THE CREATING OPERATOR. It is the tempting non-breaking answer and it is worse than the leak. An operator provisioning fifty customer workspaces would appear to own fifty; and because a workspace can only be CLAIMED while it is unowned (claiming an owned one is a transfer, which does not exist yet), a wrongly-attributed workspace would be wrong FOREVER, with raw SQL the only remedy — the exact situation this change exists to end. An unowned workspace is at least repairable. So the operator is made to answer the question rather than have it answered wrongly on their behalf: to own it themselves they pass their own person id, which is a statement, not an accident.

An operator creating a workspace FOR a customer names the customer, and consumes none of their own slots — see Create for why no cap applies here.

privy_app_idstring
self_join_policy'open' | 'invite_only'
wallet_providerstring

Response

Created

successboolean

Example response

{
  "success": true
}

Changes

No recorded changes to this operation across all 1 revision of this API.