---
title: "Create a workspace"
method: POST
path: "/v1/workspaces"
tags: ["workspaces"]
---

# Create a workspace

`POST /v1/workspaces`

## Request

- Base URL: `https://api.hyperresearch.ai`
- URL: `https://api.hyperresearch.ai/v1/workspaces`
- Auth: one of:
  - HTTP bearer
  - API key in cookie `hr_session`

Creates the D1 row and provisions the WorkspaceVault Durable Object.

## Request body

- CreateWorkspaceBody
  - `name` string, required
  - `settings` WorkspaceSettings
    - `fetch` object
      - `rung_max` 'L0' | 'L1' | 'L2' | 'L3' | 'L4'
      - `max_html_bytes` integer
      - `max_pdf_bytes` integer
      - `allow_domains` string[]
      - `deny_domains` string[]
    - `robots` 'strict' | 'standard' | 'permissive'
    - `clarify_default` 'ask' | 'auto' | 'off': What every run in this workspace does about an ambiguous question, unless the request says otherwise: `ask` interviews the customer before anything is reserved, `auto` proceeds immediately on the stated assumptions and names them in the report, `off` skips the assessment entirely. Unset, the channel decides — `ask` from the console, `auto` from an API key, the CLI or MCP.
    - `provider_exclusions` string[]
    - `retention` object
      - `raw_days` integer
      - `assets_days` integer
    - `reuse` object
      - `default` union
        - boolean
        - 'all'
      - `max_age_days` integer

## Response `201`

Created

- Workspace
  - `id` string, required
  - `name` string, required
  - `display_name` string, required: What to show a customer where the workspace is named. The workspace name, or "Untitled workspace" when it has none — never the id.
  - `display_id` string, required: The id as a screen shows it: the prefix, an ellipsis and the last characters, the same treatment `#/keys` gives a key id. Support quotes an id by copying `id`, never by reading it off the page.
  - `settings` WorkspaceSettings, required
    - `fetch` object
      - `rung_max` 'L0' | 'L1' | 'L2' | 'L3' | 'L4'
      - `max_html_bytes` integer
      - `max_pdf_bytes` integer
      - `allow_domains` string[]
      - `deny_domains` string[]
    - `robots` 'strict' | 'standard' | 'permissive'
    - `clarify_default` 'ask' | 'auto' | 'off': What every run in this workspace does about an ambiguous question, unless the request says otherwise: `ask` interviews the customer before anything is reserved, `auto` proceeds immediately on the stated assumptions and names them in the report, `off` skips the assessment entirely. Unset, the channel decides — `ask` from the console, `auto` from an API key, the CLI or MCP.
    - `provider_exclusions` string[]
    - `retention` object
      - `raw_days` integer
      - `assets_days` integer
    - `reuse` object
      - `default` union
        - boolean
        - 'all'
      - `max_age_days` integer
  - `display_robots` object, required: The workspace robots handling as a sentence, beside the wire value (E2E6-12). `#/settings` rendered the bare enum — `strict / standard / permissive` — as the options of a select whose neighbour reads "Basic — the page as served". The value is unchanged and is still what PATCH takes; this is what to show. The full option list is `GET /v1/workspaces/robots-modes`.
    - `value` 'strict' | 'standard' | 'permissive', required
    - `label` string, required
    - `description` string, required
  - `vault_bytes` integer, required
  - `status` 'active' | 'deleting' | 'deleted', required
  - `created_at` string, required
  - `updated_at` string, required

## Other responses

- `400`: Invalid request
- `401`: Authentication failed
- `403`: Insufficient scope or plan
- `404`: Not found
- `429`: Rate limited or over quota
- `500`: Internal error

---

[API](https://skmtc.dev/hyperresearch/apis/hyperresearch-cloud-api.md) · [All operations](https://skmtc.dev/hyperresearch/apis/hyperresearch-cloud-api/llms.txt) · [OpenAPI document](https://skmtc.dev/hyperresearch/apis/hyperresearch-cloud-api/revisions/726ef831ebf4?raw)
