Spaces
Operations of the Space Registry API. Paths are relative to your deployment's API host.
GET /api/space-registry-api/spaces
List the caller org's Spaces (newest first). Org-less System Spaces are not enumerated here.
Authentication: bearer token (Authorization: Bearer <token>)
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
limit | query | number | no | Max rows to return (1–500, default 100). |
| Status | Description | Body |
|---|---|---|
| 200 | application/json SpaceDtoDataArrayEnvelope |
POST /api/space-registry-api/spaces
Declare a Space (idempotent on its canonical refUri). Requires the org admin role.
Nothing about the ancestry needs to exist first — a declaration on a project ref whose org ref has no row is valid, because ancestry is derived from the ref grammar rather than stored.
Authentication: bearer token (Authorization: Bearer <token>)
Request body: application/json CreateSpaceDto
| Status | Description | Body |
|---|---|---|
| 201 | application/json SpaceDtoDataEnvelope |
GET /api/space-registry-api/spaces/ancestors
Persisted ancestor chain (closest-first, self at index 0) up to System.
Same tenant rule as /spaces/resolve: the ref is fenced against the request-context organization. The org-less System tail of the chain is returned for every caller — it is what carries the inherited classification floor.
Authentication: bearer token (Authorization: Bearer <token>)
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
ref | query | string | yes |
| Status | Description | Body |
|---|---|---|
| 200 | application/json SpaceAncestorsDtoDataEnvelope |
GET /api/space-registry-api/spaces/classification
Resolve the effective classification over the ancestry, with its source.
The monotone JOIN over every declaration on the ref and its ancestors — NOT most-specific-wins, which is the whole safety property: a project declaring public cannot escape an org that declared secret. The response carries the ANSWER as well as the value — configured, source, the full inheritancePath (silent rungs included) and clampedByRefUri, the ancestor that overrode a nearer declaration. Same tenant rule as /spaces/resolve. A data-classification label is exactly the kind of metadata a cross-tenant read must not expose, so a ref naming another organization is refused with 403.
Authentication: bearer token (Authorization: Bearer <token>)
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
ref | query | string | yes |
| Status | Description | Body |
|---|---|---|
| 200 | application/json SpaceClassificationDtoDataEnvelope |
GET /api/space-registry-api/spaces/experience
Read the caller org's shell-presentation policy.
Presentation only. A member whose shell is portal-focused still reaches any surface they are authorized for; the fences are the per-surface guards and the PDP, for every member equally.
Authentication: bearer token (Authorization: Bearer <token>)
| Status | Description | Body |
|---|---|---|
| 200 | application/json OrgExperienceSettingsDtoDataEnvelope |
PUT /api/space-registry-api/spaces/experience
Write the caller org's shell-presentation policy. Requires the org admin role.
Administrators are never confined. This decides what the shell leads with, and grants or withholds nothing.
Authentication: bearer token (Authorization: Bearer <token>)
Request body: application/json UpdateOrgExperienceSettingsDto
| Status | Description | Body |
|---|---|---|
| 200 | application/json OrgExperienceSettingsDtoDataEnvelope |
GET /api/space-registry-api/spaces/experience/app-theme
Read the caller org's app theme. Any organization member.
An organization that states no theme returns 200 with configured: false, with appTheme: null, locked: false: the frontend applies its default theme. configured: true, appTheme: null, locked: true locks members to the org brand with no built-in pick. The id is opaque here; the web host checks it against its own theme registry.
Authentication: bearer token (Authorization: Bearer <token>)
| Status | Description | Body |
|---|---|---|
| 200 | application/json OrgAppThemeDtoDataEnvelope |
PUT /api/space-registry-api/spaces/experience/app-theme
State or clear the caller org's app theme. Requires the capability space:space.experience.app-theme.update@1 (org admins by default).
A kebab-case theme id (1..64 characters) states the theme; locked: true also stops members overriding it (omitted means false). appTheme: null, locked: true locks members to the org brand with no built-in pick; appTheme: null unlocked returns to the default. Only the shape is checked: a bad shape is refused (400), never normalised. Every change is audited. Presentation only; it grants and withholds nothing.
Authentication: bearer token (Authorization: Bearer <token>)
Request body: application/json UpdateOrgAppThemeDto
| Status | Description | Body |
|---|---|---|
| 200 | application/json OrgAppThemeDtoDataEnvelope |
GET /api/space-registry-api/spaces/governance
Read the caller org's classification-governance controls (separation of duties on downgrades).
An organization that has never armed anything returns 200 with configured: false — never a 404. Un-configured is an answer.
Authentication: bearer token (Authorization: Bearer <token>)
| Status | Description | Body |
|---|---|---|
| 200 | application/json OrgGovernanceSettingsDtoDataEnvelope |
PUT /api/space-registry-api/spaces/governance
Arm or disarm approval-on-downgrade for the caller org. Requires the org admin role.
OFF by default and on a fresh install. Arming requires a data-governance group — an armed control with nobody to ask refuses every downgrade and can approve none.
Authentication: bearer token (Authorization: Bearer <token>)
Request body: application/json UpdateOrgGovernanceSettingsDto
| Status | Description | Body |
|---|---|---|
| 200 | application/json OrgGovernanceSettingsDtoDataEnvelope |
GET /api/space-registry-api/spaces/growth
Read the caller org's growth policy (who may build and publish).
An organization that has never written one returns 200 with configured: false and permissive defaults — never a 404, and never a fence nobody armed. Un-configured is an answer.
Authentication: bearer token (Authorization: Bearer <token>)
| Status | Description | Body |
|---|---|---|
| 200 | application/json OrgGrowthSettingsDtoDataEnvelope |
PUT /api/space-registry-api/spaces/growth
Write the caller org's growth policy. Requires the org admin role.
Configuration TIGHTENS. Authoring and internal publishing are policy toggles that move in either direction; external publishing is a floor (always a Decision, never below org admin) and a looser value is refused. A field omitted here is CLEARED, not left standing.
Authentication: bearer token (Authorization: Bearer <token>)
Request body: application/json UpdateOrgGrowthSettingsDto
| Status | Description | Body |
|---|---|---|
| 200 | application/json OrgGrowthSettingsDtoDataEnvelope |
GET /api/space-registry-api/spaces/resolve
Resolve a Space by its xema:// URI.
The organization is selected through the X-Xema-Org-Id request context, NOT through the ref. A ref naming a different organization is refused with 403 SPACE_CROSS_ORG_ACCESS_FORBIDDEN — never silently preferred. Org-less refs (xema://system, xema://biomes/<id>, xema://users/<id>, xema://sessions/<id>) are platform-global and remain readable by every authenticated caller.
Authentication: bearer token (Authorization: Bearer <token>)
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
ref | query | string | yes |
| Status | Description | Body |
|---|---|---|
| 200 | application/json SpaceDtoDataEnvelope |
GET /api/space-registry-api/spaces/worker-egress
Resolve a Space's worker internet egress over its ancestry, with its source.
The most restrictive declaration on the ref and its ancestors — NOT most-specific-wins: a project declaring open cannot widen an org that declared governed. A chain in which nobody declares anything returns 200 with configured: false and a null value, never a 404 and never a default. This is the SPACE tier only: the pod's effective mode also joins the deployment's posture and the agent's and the session's narrowings. Same tenant rule as /spaces/resolve.
Authentication: bearer token (Authorization: Bearer <token>)
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
ref | query | string | yes |
| Status | Description | Body |
|---|---|---|
| 200 | application/json SpaceWorkerEgressDtoDataEnvelope |
GET /api/space-registry-api/spaces/{id}
Fetch a Space by opaque id.
A Space owned by another organization returns the SAME 404 as an unknown id — an opaque id names no tenant, so a distinct 403 would make this route a cross-tenant existence oracle.
Authentication: bearer token (Authorization: Bearer <token>)
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes |
| Status | Description | Body |
|---|---|---|
| 200 | application/json SpaceDtoDataEnvelope |
DELETE /api/space-registry-api/spaces/{id}
Delete a Space override by id. Requires the org admin role. Refuses system-managed Spaces (fail-fast).
A row is an override, not a node, so a delete orphans nothing: every descendant ref keeps resolving and simply loses one contribution to the classification join.
Authentication: bearer token (Authorization: Bearer <token>)
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes |
| Status | Description | Body |
|---|---|---|
| 204 | Space deleted. |
PATCH /api/space-registry-api/spaces/{id}/classification
Set/change a Space's own classification. Requires the org admin role. Downgrades require allowDowngrade, are audited, and may require approval.
RAISING sensitivity takes no extra path. LOWERING it requires allowDowngrade and writes a durable downgrade audit carrying the blast radius as measured at that moment. If the organization has armed separation of duties, the write does NOT happen: a Decision is opened for the data-governance group and this responds 409 SPACE_DOWNGRADE_AWAITING_DECISION with the decision id.
Authentication: bearer token (Authorization: Bearer <token>)
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes |
Request body: application/json UpdateClassificationDto
| Status | Description | Body |
|---|---|---|
| 200 | application/json SpaceDtoDataEnvelope |
PUT /api/space-registry-api/spaces/{id}/worker-egress
Set, change or clear a Space's own worker internet egress. Requires the org admin role.
Declared on an ORG or a PROJECT space only; any other tier is refused with 422 SPACE_WORKER_EGRESS_TIER_NOT_ADMISSIBLE. null clears the declaration. Every change is recorded in the same transaction and announced as space.worker-egress.changed; a write that changes nothing records and announces nothing. A declaration can only ever TIGHTEN what the deployment allows — open here widens nothing.
Authentication: bearer token (Authorization: Bearer <token>)
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes |
Request body: application/json UpdateWorkerEgressDto
| Status | Description | Body |
|---|---|---|
| 200 | application/json SpaceDtoDataEnvelope |