---
title: "Get-or-create a workspace (idempotent)"
method: POST
path: "/api/workspaces/ensure"
tags: ["Workspaces"]
---

# Get-or-create a workspace (idempotent)

`POST /api/workspaces/ensure`

## Request

- Base URL: `http://localhost:38200`
- URL: `http://localhost:38200/api/workspaces/ensure`
- Auth: one of:
  - HTTP bearer
  - API key in cookie `token`

Idempotent counterpart to `POST /api/workspaces`, reachable with a plain `write`-scoped API key instead of an admin JWT — the only path a programmatic caller (the Claude Code plugin's HTTP MCP surface, `ctx_workspace_ensure`) has to provision its own workspace. Resolves an existing, non-tombstoned workspace inside the caller's tenant by `slug` when given, else by the slugified `name`, and returns it with `created: false`; otherwise creates one and returns `created: true`. `workspaces.slug` is globally unique among non-deleted rows, so a created workspace may receive a suffixed slug that differs from the requested one — callers must persist the `slug` from this response rather than re-deriving it.

## Request body

- object
  - `name` string, required
  - `slug` string: Resolution hint only. A newly created workspace derives its slug from `name`.

## Response `200`

Existing workspace returned unchanged (created: false).

- object
  - `id` integer
  - `slug` string
  - `name` string
  - `tenantId` integer, nullable
  - `createdAt` string, date-time
  - `archivedAt` string, date-time, nullable
  - `archived` boolean
  - `contextCount` integer
  - `created` boolean

## Other responses

- `201`: Newly created workspace (created: true).
- `400`: Request body/query failed Zod validation.
- `401`: Missing or invalid credentials.
- `403`: The reserved `global` slug was requested.

---

[API](https://skmtc.dev/contextq/apis/contextq-api.md) · [All operations](https://skmtc.dev/contextq/apis/contextq-api/llms.txt) · [OpenAPI document](https://skmtc.dev/contextq/apis/contextq-api/revisions/7afc44056a22?raw)
