Skip to main content

Spaces API

Spaces are the primary workspace boundary for catalog, quality, governance, collaboration, and integration resources.

All endpoints below use the public API base path:

/api/v1.0

Scope And Access

Most space-scoped product APIs use a {slug} path parameter. The space resolver accepts either a space slug or a UUID string for many routes, but client code should prefer stable slugs in URLs.

Space access is enforced by authorize_space_only and get_current_space_context. Access succeeds when the authenticated user is a superadmin, has a direct UserSpaceRole, or has access through the parent organization where the route uses the DB-backed space access check. JWT-backed requests can also use embedded space grants.

GET /spaces/mine is more specific: for non-superadmins it currently lists direct space memberships from UserSpaceRole, while superadmins see every space.

Endpoint Overview

MethodEndpointDescription
GET/spaces/mineList spaces available in the space selector.
POST/spacesCreate a space. Superadmin only.
DELETE/spaces/{space_id}Delete a space and its contents. Superadmin only.
GET/spaces/{slug}/membersList direct space members.
POST/spaces/{slug}/membersAdd an existing user to the space by email.
PATCH/spaces/{slug}/members/{user_id}Update a member's platform role.
DELETE/spaces/{slug}/members/{user_id}Remove a direct space member.
PATCH/spaces/{slug}/default-workflowsSet the default request workflow. Superadmin only.
GET/spaces/{slug}/my-roleReturn the current user's direct platform role in the space.
GET/spaces/{slug}/my-governance-rolesReturn product governance roles held by the current user.
GET/spaces/{slug}/my-permissionsReturn effective resource actions for the current user.
GET/spaces/{slug}/attachmentsList unified attachments across the space.

The current /spaces router does not expose a public GET /spaces/{slug} detail endpoint or a general PATCH /spaces/{slug} update endpoint. Global list/update/settings operations are handled by the adjacent admin and organization APIs described in Adjacent Space APIs.

Space Object

Space responses use the platform SpaceResponse shape:

{
"id": "64bcfa65-2e1f-4c97-9a5f-c582a0b26d03",
"name": "Finance Data",
"slug": "finance-data",
"created_at": "2026-06-29T08:30:00Z",
"default_governance_workflow_id": "4f83b770-3b7a-40d5-8587-aa30a5c803ac",
"organization_id": "94a6c620-942f-4b6e-8b55-f613c8859544"
}

There is no description field on this response in the current schema.

List My Spaces

GET /api/v1.0/spaces/mine

Returns an array of spaces for the current user. The frontend SpaceProvider uses this endpoint to populate and persist the active space selection.

[
{
"id": "64bcfa65-2e1f-4c97-9a5f-c582a0b26d03",
"name": "Finance Data",
"slug": "finance-data",
"created_at": "2026-06-29T08:30:00Z",
"default_governance_workflow_id": null,
"organization_id": null
}
]

For non-superadmins, the list is based on direct space memberships. Use the Organizations API when you need organization membership, organization space assignment, or organization-level rollups.

Create Space

POST /api/v1.0/spaces

Requires superadmin access and enforces the catalog.max_spaces tier limit.

{
"name": "Finance Data",
"slug": "finance-data"
}

The service rejects duplicate slugs. After the row is created, default catalog metadata and document structure defaults are seeded for the space.

The same superadmin creation workflow is also exposed through POST /api/v1.0/admin/spaces.

Delete Space

DELETE /api/v1.0/spaces/{space_id}

Requires superadmin access. The path parameter is the space UUID, not the slug.

Deletion walks the foreign-key graph for space-owned resources, removes reachable child records first, and then deletes the space row.

{
"message": "Space 'Finance Data' deleted successfully"
}

Because this removes the space and its contents, integrations should treat it as a destructive administrative operation.

Members

Member responses include the user's ID, email, display name, current platform role, and optional avatar color:

{
"id": "1b8f697c-14d1-442a-a80f-90434255d941",
"email": "ana@example.com",
"full_name": "Ana Smith",
"role": "Admin",
"avatar_color": "#4f46e5"
}

Platform roles are stored by name. Seeded roles include Admin, Editor, Viewer, Data Governance Professional, Developer, and General User. role_name values must match a stored PlatformRole.name.

List Members

GET /api/v1.0/spaces/{slug}/members

Returns direct UserSpaceRole members for the space. Organization-level members are managed separately and are not returned as direct space members by this endpoint.

[
{
"id": "1b8f697c-14d1-442a-a80f-90434255d941",
"email": "ana@example.com",
"full_name": "Ana Smith",
"role": "Admin",
"avatar_color": "#4f46e5"
}
]

Add Member

POST /api/v1.0/spaces/{slug}/members

Adds an existing user by email. The caller must be a superadmin or a direct space member with the Admin role.

{
"email": "new.member@example.com",
"role_name": "Viewer"
}

Errors include unknown space, unknown user, unknown role, duplicate membership, or insufficient permission.

Update Member Role

PATCH /api/v1.0/spaces/{slug}/members/{user_id}
{
"role_name": "Editor"
}

The route requires space access. The service validates that the target user is a direct member and that the requested role exists, updates the UserSpaceRole, invalidates role/permission caches, and emits a space member audit event when an actor is available.

Remove Member

DELETE /api/v1.0/spaces/{slug}/members/{user_id}

The route requires space access. The service validates that the target user is a direct member, removes the UserSpaceRole, bumps the user's session version, invalidates role/permission caches, and emits a member removal audit event when an actor is available.

Response:

{
"message": "Member removed successfully"
}

Default Workflows

PATCH /api/v1.0/spaces/{slug}/default-workflows

Sets the default request workflow used for general requests such as access, recertification, or change workflows. The current route requires superadmin access.

{
"default_request_workflow_id": "10cd0804-f63b-4f9e-a890-f00118fe5e57"
}

Send null to clear the default request workflow.

{
"default_request_workflow_id": "10cd0804-f63b-4f9e-a890-f00118fe5e57",
"default_governance_workflow_id": "4f83b770-3b7a-40d5-8587-aa30a5c803ac"
}

Default governance workflow configuration is updated through the admin space update endpoint, not this route.

Viewer Context

The frontend ViewerContext and permission hooks use these endpoints to render space-aware actions.

My Role

GET /api/v1.0/spaces/{slug}/my-role

Returns the current user's direct platform role in the space. Superadmins receive Admin. Users who only have inherited organization access can receive null here.

{
"role": "Editor"
}

My Governance Roles

GET /api/v1.0/spaces/{slug}/my-governance-roles

Returns product-level governance roles held by the current user in the space.

[
{
"id": "2f69ad79-caf3-43df-9c65-aa9bba46dcfb",
"product_id": "8da2bc25-6358-4be6-af9a-5e545f00517f",
"product_name": "Customer Risk Scores",
"role_type": "owner"
}
]

My Permissions

GET /api/v1.0/spaces/{slug}/my-permissions

Returns the current user's effective allowed actions by resource type. Only resource types with at least one allowed action are included.

{
"permissions": {
"product": ["view", "create", "edit"],
"ticket": ["view"],
"request": ["view", "approve"]
}
}

Permissions are calculated from configurable permission rules first, then baseline RBAC behavior. The frontend usePermissions hook caches this map per active space and exposes a synchronous can(action, resourceType) helper.

Space Attachments Index

GET /api/v1.0/spaces/{slug}/attachments?entity_type=product&limit=50

Lists unified attachments across the space. This is an inventory/read endpoint; upload, download, and delete actions remain on each feature's attachment routes.

Query parameters:

ParameterTypeNotes
entity_typestringOptional filter such as product, meeting, ticket, document_page, analysis, repository, or another registered attachment entity type.
limitintegerDefaults to 50; capped at 100 by the route.

Response:

{
"attachments": [
{
"id": "1d5e36d0-0fc3-42a2-aa13-43c9d0924e67",
"entity_type": "product",
"file_name": "dq-runbook.md",
"file_type": "text/markdown",
"file_size_bytes": 2048,
"storage_uri": "uploads/products/...",
"storage_backend": "filesystem",
"markdown_snippet": null,
"created_at": "2026-06-29T08:35:00Z",
"product_id": "8da2bc25-6358-4be6-af9a-5e545f00517f",
"product_name": "Customer Risk Scores",
"uploader": {
"id": "1b8f697c-14d1-442a-a80f-90434255d941",
"display_name": "Ana Smith",
"email": "ana@example.com"
}
}
],
"total": 1,
"limit": 50
}

Adjacent Space APIs

Some space lifecycle and organization operations intentionally live outside the /spaces router:

APIPurpose
GET /api/v1.0/admin/spacesSuperadmin list of all spaces.
POST /api/v1.0/admin/spacesSuperadmin space creation.
PATCH /api/v1.0/admin/spaces/{space_id}Superadmin update of name, slug, and default_governance_workflow_id.
PATCH /api/v1.0/admin/spaces/{space_id}/settingsSuperadmin shallow merge of space_settings.
POST /api/v1.0/organizations/{slug}/spacesOrganization admin attaches a space to an organization by space_id.
DELETE /api/v1.0/organizations/{slug}/spaces/{space_id}Organization admin removes a space from an organization.

Use the Organizations API for organization membership and cross-space organization views. Use the Admin API for global space lifecycle operations and per-space system settings.

Failure Cases

StatusCommon cause
400Duplicate slug, missing required parameter, invalid organization-space assignment, or malformed request body.
403Caller lacks superadmin access, space access, direct space Admin rights for adding a member, or organization admin rights for organization assignment.
404Space, member, user, or role not found.
422Invalid UUID or request payload type.
500Space deletion failed during dependency cleanup.