Workspaces
Named entities used to group DAG runs via tag-based filtering in the Cockpit UI.
How It Works
A workspace is a named record stored on the server. When a DAG run is enqueued from the Cockpit UI, a workspace=<name> tag is injected into the in-memory YAML spec before submission. The Cockpit then filters DAG runs by this tag using the tags query parameter on GET /api/v1/dag-runs.
Workspaces do not modify DAG definitions on disk. The tag injection happens at enqueue time on a copy of the spec.
Storage
Each workspace is stored as a JSON file at {workspaces_dir}/{uuid}.json.
Configuration
# ~/.config/dagu/config.yaml
paths:
workspaces_dir: "/custom/path/to/workspaces"| Config key | Environment variable | Default |
|---|---|---|
paths.workspaces_dir | DAGU_WORKSPACES_DIR | {data_dir}/workspaces |
The default data_dir depends on your setup:
- With
DAGU_HOMEset:{DAGU_HOME}/data - XDG fallback:
~/.local/share/dagu/data
File Format
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "production",
"description": "Production workflows",
"created_at": "2026-03-06T10:00:00Z",
"updated_at": "2026-03-06T10:00:00Z"
}File permissions: 0600. Directory permissions: 0750.
The store maintains in-memory indices (byID and byName maps) rebuilt on startup by scanning the directory for .json files. Thread-safe via sync.RWMutex.
Name Constraints
Names must match [a-zA-Z0-9_-]. The UI strips any other characters on creation.
REST API
All endpoints accept the remoteNode query parameter for routing requests to remote nodes.
List Workspaces
GET /api/v1/workspaces?remoteNode=<node>No specific role required (any authenticated user).
Response (200):
{
"workspaces": [
{
"id": "a1b2c3d4-...",
"name": "production",
"description": "Production workflows",
"createdAt": "2026-03-06T10:00:00Z",
"updatedAt": "2026-03-06T10:00:00Z"
}
]
}Returns an empty array if no workspaces exist.
Create Workspace
POST /api/v1/workspaces?remoteNode=<node>Requires developer role or above (requireDeveloperOrAbove).
Request:
{
"name": "staging",
"description": "Optional description"
}name is required. description is optional.
Response (201): The created workspace object.
Response (400): Name is empty.
{ "code": "bad_request", "message": "Name is required" }Response (409): A workspace with this name already exists.
{ "code": "already_exists", "message": "Workspace with this name already exists" }Get Workspace
GET /api/v1/workspaces/{workspaceId}?remoteNode=<node>No specific role required (any authenticated user).
Response (200): The workspace object.
Response (404): Workspace not found.
Update Workspace
PATCH /api/v1/workspaces/{workspaceId}?remoteNode=<node>Requires developer role or above. PATCH semantics -- only provided fields are updated.
Request:
{
"name": "new-name",
"description": "Updated description"
}Both fields are optional. Empty string for name is ignored (the existing name is kept).
Response (200): The updated workspace object.
Response (404): Workspace not found.
Response (409): Another workspace with the new name already exists.
Delete Workspace
DELETE /api/v1/workspaces/{workspaceId}?remoteNode=<node>Requires developer role or above.
Response (204): No content. Workspace deleted.
Response (404): Workspace not found.
Response Object
All endpoints returning workspace data use this shape:
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | UUID v4, generated by github.com/google/uuid |
name | string | Yes | Workspace name |
description | string | No | Omitted from JSON when empty |
createdAt | string (date-time) | No | UTC timestamp, omitted when zero |
updatedAt | string (date-time) | No | UTC timestamp, omitted when zero |
Error Responses
When the workspace store is not configured (e.g., directory creation failed on startup), all endpoints return:
Response (503):
{ "code": "internal_error", "message": "Workspace store not configured" }Audit Logging
All write operations are logged with category workspace:
| Action | Logged fields |
|---|---|
workspace_create | id, name |
workspace_update | id, name |
workspace_delete | id, name |
Related
- Cockpit -- the UI that uses workspaces
