Groundfloor Docs

Workspaces API

List, create, read, freeze, and export workspace metadata.

Base path: /v1/workspaces

See also: Workspaces

List workspaces

GET /v1/workspaces

Returns every workspace you can access: workspaces you hold a direct membership on, plus all workspaces under any organization you belong to.

Permission: implicit via membership

curl -s -H "Authorization: Bearer $TOKEN" \
  "https://platform.groundfloor.cloud/v1/workspaces" | jq .

Query parameters

NameTypeDefaultDescription
limitinteger100Max workspaces returned (1-500)

Response 200

[
  {
    "id": "8ca7d2a2-…",
    "account_id": "…",
    "organization_id": "…",
    "name": "Production",
    "slug": "production",
    "status": "active",
    "region": "us-east-1",
    "tenancy_model": "direct",
    "frozen_at": null,
    "deletion_requested_at": null,
    "scheduled_deletion_at": null,
    "created_at": "2026-05-01T12:00:00Z",
    "updated_at": "2026-05-01T12:00:00Z",
    "created_by": "…"
  }
]
FieldNotes
statusactive, frozen or archived
tenancy_modeldirect, subtenant_of or partner_managed
account_id / organization_idSame value; both are returned
frozen_atSet when the workspace was frozen
deletion_requested_at / scheduled_deletion_atSet only while a deletion request is pending
created_by, created_by_display_name, created_by_emailWho created the workspace, when known

Create workspace

POST /v1/workspaces

Starts setting up the workspace: its environments, data API and permissions. Returns 202 Accepted with a provisioning run ID — not the final workspace synchronously.

Permission: administer on the parent organization (and on the parent workspace when parent_workspace_id is set)

curl -s -X POST -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"account_id":"<organization_uuid>","name":"Development","slug":"development","tenancy_model":"direct"}' \
  "https://platform.groundfloor.cloud/v1/workspaces" | jq .

Request body

FieldTypeRequiredDescription
account_id (or organization_id)uuidYesParent organization. Send either name; if you send both they must be equal
namestringYesDisplay name, 1-255 characters
slugstringYesLowercase letters, digits and hyphens, 1-63 characters. Not generated for you. Must not collide with another workspace's branded host (409)
tenancy_modelstringYesdirect, subtenant_of or partner_managed. No default
regionstringNoDefaults to the cell's region. Must be a region available on that cell, otherwise 422
environmentsstring or arrayNo"default" (default) creates dev, staging and prod; "none" creates none; or pass a list of environment names. Ignored for subtenant_of, which always gets none
parent_workspace_iduuidOnly for subtenant_ofRequired when tenancy_model is subtenant_of; must be omitted for direct. The parent must be an active direct workspace in the same organization

A subtenant_of workspace gets no environments, so nothing can be deployed into it. The Client Portal no longer offers it. | settings_json | object | No | No keys are currently accepted from callers; any non-empty object is rejected with 422 |

Response 202

{
  "workspace_id": "8ca7d2a2-…",
  "provisioning_run_id": "…"
}

Errors

StatusWhen
400subtenant_of on an organization that is not an ISV organization; parent workspace does not use the direct model
403Missing administer on the organization or the parent workspace; parent belongs to a different organization
404Organization or parent workspace not found
409Plan workspace quota reached; organization is suspended or scheduled for deletion; parent workspace is not active; slug would collide with another workspace's host
422Missing slug or tenancy_model, invalid slug, region not available, or settings_json keys set
429Rate limit: 10 creates per minute

Get workspace

GET /v1/workspaces/{workspace_id}

Permission: read on workspace

List workspaces by organization

GET /v1/workspaces/by-organization/{organization_id}

/v1/workspaces/by-account/{organization_id} also works. Accepts the same limit parameter (1-500).

Permission: read on organization. Callers who only hold a workspace membership under the organization see just those workspaces.

List environments

GET /v1/workspaces/{workspace_id}/environments

Returns the workspace's environments. A workspace created with environments: "default" has dev, staging and prod; one created with "none" or a custom list has what you asked for, and environments can be added later (see Environments API).

Permission: read on workspace

Freeze a workspace

PATCH /v1/workspaces/{workspace_id}/status

Freeze a workspace. Freezing is a suspension: it sets no deletion date and nothing is erased. To delete a workspace, see Delete a workspace.

{ "status": "frozen" }

Freezing is one-way. frozen is the only accepted value and there is no route to unfreeze. Restoring a workspace only lifts the freeze that a deletion request sets, and a frozen workspace can't be scheduled for deletion; contact Groundfloor support to reactivate it. Once frozen, write requests to the workspace's routes fail with 423 Locked. Reads, export and changes that only remove access, such as deleting a secret or a deployment, keep working. Don't call this to test the API on a workspace you want to keep using.

Returns the updated workspace record.

Permission: administer on workspace

StatusWhen
409The workspace is already frozen, or cannot be frozen in its current state (for example it is archived)
422Any status value other than frozen

Set the default app

PUT /v1/workspaces/{workspace_id}/default-app

Sets, or clears, the workspace's default app. Idempotent. The app lists return it as default_app_slug. The Shell site doesn't use it yet: it opens the app the user last opened in the workspace, otherwise the first app.

{ "app_slug": "storefront" }

Send {"app_slug": null} to clear it. The slug must name a non-archived app of kind shell_federated in this workspace. Returns {"workspace_id": "…", "default_app_slug": "storefront"}.

Permission: write on workspace

StatusWhen
403Missing write
404Workspace or app slug not found
409The app is archived
422The app is not shell_federated, or the body is invalid
423The workspace is frozen

Export workspace metadata

GET /v1/workspaces/{workspace_id}/export

Streams one JSON file (Content-Disposition: attachment) with the workspace's metadata:

IncludedNot included
The workspace recordApp data, Data Vault records or database contents
MembershipsFiles
EnvironmentsSecrets
Provisioning runsDeployed code or Coderunner packages
Audit events (up to 10,000 per list)

This is not a backup and not a data-exit path for your application data. Use the Data Vault, Files and Databases APIs to move that data.

The response is JSON only. A legacy upload query flag is accepted and ignored.

The file leaves out internal platform details, and secret-like values in audit events are removed.

Permission: administer on the workspace: workspace Owners and Admins, and organization Owners and Admins. Everyone else gets 403. Export keeps working on a frozen workspace.

Workspace audit

GET /v1/workspaces/{workspace_id}/audit?limit=50

Permission: read on workspace

All scoped under /v1/workspaces/{workspace_id}/:

PillarPath prefix
Secrets/secrets
Files/files
Data Vault/vault
Process Log/logs
Apps/apps
Coderunners/coderunners