Browse documentationApps

Resource guide

An app binds a folder to a process

App registration connects a workspace path, start command, port, and stable slug. An optional name is the human-facing label; when it is unset, clients display the registered folder name. An optional icon is a safe path relative to that app folder, such as icon.png or assets/icon.png—it is not an image URL or embedded bytes. Keep the command reproducible from the registered folder and choose visibility separately from process configuration. The API returns the generated standalone canonicalUrl; clients should use that address rather than construct or persist a second app identity. An active custom hostname becomes this standalone address. The generated https://<app>--<workspace>.edge.duet.so/ address keeps working.

{
  "path": "apps/status",
  "command": "bun run start",
  "apiScopes": ["services"],
  "port": 4173,
  "slug": "status",
  "name": "Status Board",
  "icon": "assets/icon.png"
}

apiScopes is the app server's least-privilege declaration, not a list of features the UI happens to show. Declare only the capabilities required by Duet API routes the server actually calls, and send [] when it calls none. The capability grammar and credential boundaries live in API keys and scopes; admin is deliberately unavailable to apps.

Duet does not add an install-time consent step. Declared scopes are visible before and after an app is installed, with elevated access called out; a workspace removes that authority by disabling or uninstalling the app, not by maintaining a second approval record.

Runtime authority stays outside the drive

After registration, Duet mints a hidden key for each app row with a non-empty declaration in that workspace. Only the spawned service receives DUET_APP_API_KEY and DUET_API_URL; install commands do not receive the key. Read both from the process environment and keep the key in memory. Never write it to source, .env*, SQLite, logs, or another drive path: drive contents sync to devices and can be shared or published.

Changing apiScopes replaces stale authority and restarts that app with the new key. Disabling or deleting the app revokes its key. The platform owns refresh and recovery, so app code should treat the value as replaceable rather than cache it.

Reconcile, do not duplicate

List existing apps before creating one from automation. Update command, install command, or port on the existing slug; use deletion only when the public identity should disappear. Name and icon updates are metadata-only: they do not reinstall or restart the app, and sending the same icon path again deliberately advances updatedAt so clients can refresh bytes replaced at that path. Public visibility is a deliberate exposure boundary, not a health-check mechanism.

Runtime writes are complete only after Duet's computer accepts the workspace configuration. Apps report whether that reconciliation is pending, complete, or needs attention. A reconciliation failure is a structured API error: preserve the returned app, show the reason, and refresh the list instead of assuming the optimistic change became durable. Failed runtime edits retain the last accepted command, install command, and port while retaining name and icon changes from the request; failed deletes retain the app registration.

Shared apps arrive as replicas

Accepting a share whose folder registers apps materializes real app rows in the recipient workspace, tagged with their origin (sourceShareId, sourceAppId) and with the access that share grants (sourceShareMode). Its apiScopes declaration travels with the registration, but no key does: the recipient workspace mints its own runtime credential. A replica is a real app on the recipient's own computer at the recipient's own URL, so sharing an app is sharing files: a write-mode recipient may change its runtime and publish their copy, and doing so never changes the origin app's visibility. A read-mode recipient may do neither. The recipient's own control is the disabled flag: disabling a replica is durable — origin updates never resurrect it — and re-enabling is the same idempotent endpoint. A replica records who disabled it and when, so the state is auditable. A replica is removed by dropping the share, never by deleting the app.

Keep policy on the server

The apps scope permits access to this resource but does not replace workspace roles. Viewers can list and inspect apps. Editors can register apps, change runtime configuration, make a public app workspace-only, and delete it. Only owners can expose an app publicly.

Role alone cannot answer what a caller may do to a given app, because a replica lives in a workspace the recipient owns while its permissions come from the share. Every app therefore carries its own resolved controls (updateRuntime, makePublic, makePrivate, delete, manageDomain); the list-level capabilities answers only the workspace-wide question of whether this caller may register an app. Present controls from those values, and still handle authorization failures because roles and shares can change after a client loads.

A custom domain changes the address, not admission

Each app can attach one hostname. Editors and owners can manage it, including for a disabled, broken, shared, or installed app; viewers can inspect its status and DNS instructions. A binding belongs to this local app and does not travel with shared files or marketplace content.

Attach returns the durable reservation while provider work proceeds. Repeating the same hostname returns the same binding; another hostname on that app or a hostname already reserved elsewhere returns a conflict. Follow the returned DNS instructions and conflicts. Duet checks automatically while setup is pending; Recheck also requests a new check after DNS changes or retries an exhausted removal. Only active bindings serve content or become standalone addresses. Provider failures retain diagnostics so the user can repair setup and retry.

Full domain responses include checking: true while an active or failed binding has a queued or running recheck. An active hostname keeps serving during the check. Observe the domain detail or workspace collection until checking is absent and lastCheckedAt advances, then use the returned status and diagnostics as the result. Initial setup still uses pending and verifying.

Removal stops custom-host serving immediately and cleans up the provider assignment in the background. A removing binding keeps its reservation until cleanup finishes. When cleanup needs attention, retryRequired identifies the manual retry; the existing Duet address continues to work. The workspace collection uses the usual opaque continuation cursor and may return fewer rows than the requested limit.

A provider write with an uncertain outcome requires operator repair. operatorRepairRequired identifies this state; ordinary Recheck cannot clear it. The hostname stays reserved until support confirms the remote work has settled and resumes cleanup. This prevents a delayed provider add or delete from changing a later attachment.

Public custom-host content retains the app's indexing directives. Standard Duet addresses, private content, and platform authentication or error responses remain excluded from indexing.

A private app is reachable without being public

Visibility governs standalone access, not whether members can use the app. An anonymous browser opening a private app document can sign in through Duet and return to its original host and deep path. This works on its standard address and an active custom domain. API calls, iframe requests, and denied signed-in visitors receive the ordinary refusal instead of a sign-in redirect.

GET /v1/ws/{workspace}/apps/{slug}/launch mints the short-lived access grant after checking current app access. Its optional host and path query parameters must be supplied together; the host must be that app's standard address or current active custom domain. The path stays relative to that host, and any old duet_access parameter is replaced. The default launch always uses the standard Duet address. Embedded views use this host for both public and private apps, so customer DNS cannot interrupt an embedded view. Standalone Open and Copy link actions use the active custom address where offered; attaching never publishes the app.

Apps

14 operations
GET/v1/ws/{workspaceSlug}/app-domains

List current app domains in a workspace

Scope
ws:{workspaceSlug}:apps
Request
No JSON request body
Query
Query parameters JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "cursor": {
      "type": "string",
      "minLength": 1
    },
    "limit": {
      "default": 50,
      "type": "integer",
      "minimum": 1,
      "maximum": 100
    }
  },
  "additionalProperties": false
}
Response
Response JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "domain": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "workspaceId": {
                "type": "string"
              },
              "appId": {
                "type": "string"
              },
              "hostname": {
                "type": "string",
                "pattern": "^(?=.{1,253}$)[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)+$"
              },
              "status": {
                "type": "string",
                "enum": [
                  "pending",
                  "verifying",
                  "active",
                  "failed",
                  "removing"
                ]
              },
              "records": {
                "maxItems": 32,
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "type": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 32,
                      "pattern": "^[\\x20-\\x7e]+$"
                    },
                    "domain": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 253
                    },
                    "value": {
                      "type": "string",
                      "minLength": 1
                    },
                    "reason": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "type",
                    "domain",
                    "value"
                  ],
                  "additionalProperties": false
                }
              },
              "conflicts": {
                "maxItems": 32,
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 253
                    },
                    "type": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 32,
                      "pattern": "^[\\x20-\\x7e]+$"
                    },
                    "value": {
                      "type": "string",
                      "minLength": 1
                    }
                  },
                  "required": [
                    "name",
                    "type",
                    "value"
                  ],
                  "additionalProperties": false
                }
              },
              "lastError": {
                "type": "string",
                "maxLength": 2000
              },
              "createdAt": {
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "updatedAt": {
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "lastCheckedAt": {
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "verifiedAt": {
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "retryRequired": {
                "type": "boolean"
              },
              "operatorRepairRequired": {
                "type": "boolean",
                "const": true
              },
              "checking": {
                "type": "boolean",
                "const": true
              }
            },
            "required": [
              "id",
              "workspaceId",
              "appId",
              "hostname",
              "status",
              "records",
              "conflicts",
              "createdAt",
              "updatedAt"
            ],
            "additionalProperties": false
          },
          "app": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "slug": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "controls": {
                "type": "object",
                "properties": {
                  "manageDomain": {
                    "type": "boolean"
                  }
                },
                "required": [
                  "manageDomain"
                ],
                "additionalProperties": false
              }
            },
            "required": [
              "id",
              "slug",
              "controls"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "domain",
          "app"
        ],
        "additionalProperties": false
      }
    },
    "nextCursor": {
      "anyOf": [
        {
          "type": "string",
          "minLength": 1
        },
        {
          "type": "null"
        }
      ]
    }
  },
  "required": [
    "items",
    "nextCursor"
  ],
  "additionalProperties": false
}
Errors
Error body JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "anyOf": [
    {
      "type": "object",
      "properties": {
        "error": {
          "type": "string",
          "enum": [
            "invalid_request",
            "invalid_cursor",
            "forbidden",
            "domain_occupied",
            "hostname_in_use",
            "domain_cleanup_pending",
            "domain_not_configured",
            "not_found"
          ]
        }
      },
      "required": [
        "error"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "properties": {
        "error": {
          "type": "string",
          "const": "invalid_cursor"
        }
      },
      "required": [
        "error"
      ],
      "additionalProperties": false,
      "description": "Opaque collection cursor is malformed or bound to another walk (400)"
    }
  ]
}
Delivery
Standard response
Retry
Not declared idempotent
GET/v1/ws/{workspaceSlug}/apps/{slug}/domain

Inspect an app domain and its DNS instructions

Scope
ws:{workspaceSlug}:apps
Request
No JSON request body
Response
Response JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "domain": {
      "anyOf": [
        {
          "type": "object",
          "properties": {
            "id": {
              "type": "string"
            },
            "workspaceId": {
              "type": "string"
            },
            "appId": {
              "type": "string"
            },
            "hostname": {
              "type": "string",
              "pattern": "^(?=.{1,253}$)[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)+$"
            },
            "status": {
              "type": "string",
              "enum": [
                "pending",
                "verifying",
                "active",
                "failed",
                "removing"
              ]
            },
            "records": {
              "maxItems": 32,
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "type": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 32,
                    "pattern": "^[\\x20-\\x7e]+$"
                  },
                  "domain": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 253
                  },
                  "value": {
                    "type": "string",
                    "minLength": 1
                  },
                  "reason": {
                    "type": "string"
                  }
                },
                "required": [
                  "type",
                  "domain",
                  "value"
                ],
                "additionalProperties": false
              }
            },
            "conflicts": {
              "maxItems": 32,
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 253
                  },
                  "type": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 32,
                    "pattern": "^[\\x20-\\x7e]+$"
                  },
                  "value": {
                    "type": "string",
                    "minLength": 1
                  }
                },
                "required": [
                  "name",
                  "type",
                  "value"
                ],
                "additionalProperties": false
              }
            },
            "lastError": {
              "type": "string",
              "maxLength": 2000
            },
            "createdAt": {
              "type": "integer",
              "minimum": 0,
              "maximum": 9007199254740991
            },
            "updatedAt": {
              "type": "integer",
              "minimum": 0,
              "maximum": 9007199254740991
            },
            "lastCheckedAt": {
              "type": "integer",
              "minimum": 0,
              "maximum": 9007199254740991
            },
            "verifiedAt": {
              "type": "integer",
              "minimum": 0,
              "maximum": 9007199254740991
            },
            "retryRequired": {
              "type": "boolean"
            },
            "operatorRepairRequired": {
              "type": "boolean",
              "const": true
            },
            "checking": {
              "type": "boolean",
              "const": true
            }
          },
          "required": [
            "id",
            "workspaceId",
            "appId",
            "hostname",
            "status",
            "records",
            "conflicts",
            "createdAt",
            "updatedAt"
          ],
          "additionalProperties": false
        },
        {
          "type": "null"
        }
      ]
    }
  },
  "required": [
    "domain"
  ],
  "additionalProperties": false
}
Errors
Error body JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "error": {
      "type": "string",
      "enum": [
        "invalid_request",
        "invalid_cursor",
        "forbidden",
        "domain_occupied",
        "hostname_in_use",
        "domain_cleanup_pending",
        "domain_not_configured",
        "not_found"
      ]
    }
  },
  "required": [
    "error"
  ],
  "additionalProperties": false
}
Delivery
Standard response
Retry
Not declared idempotent
PUT/v1/ws/{workspaceSlug}/apps/{slug}/domain

Attach one custom hostname without changing app visibility

Scope
ws:{workspaceSlug}:apps
Request
Request JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "hostname": {
      "type": "string",
      "minLength": 1
    }
  },
  "required": [
    "hostname"
  ],
  "additionalProperties": false
}
Response
Response JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "domain": {
      "anyOf": [
        {
          "type": "object",
          "properties": {
            "id": {
              "type": "string"
            },
            "workspaceId": {
              "type": "string"
            },
            "appId": {
              "type": "string"
            },
            "hostname": {
              "type": "string",
              "pattern": "^(?=.{1,253}$)[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)+$"
            },
            "status": {
              "type": "string",
              "enum": [
                "pending",
                "verifying",
                "active",
                "failed",
                "removing"
              ]
            },
            "records": {
              "maxItems": 32,
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "type": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 32,
                    "pattern": "^[\\x20-\\x7e]+$"
                  },
                  "domain": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 253
                  },
                  "value": {
                    "type": "string",
                    "minLength": 1
                  },
                  "reason": {
                    "type": "string"
                  }
                },
                "required": [
                  "type",
                  "domain",
                  "value"
                ],
                "additionalProperties": false
              }
            },
            "conflicts": {
              "maxItems": 32,
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 253
                  },
                  "type": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 32,
                    "pattern": "^[\\x20-\\x7e]+$"
                  },
                  "value": {
                    "type": "string",
                    "minLength": 1
                  }
                },
                "required": [
                  "name",
                  "type",
                  "value"
                ],
                "additionalProperties": false
              }
            },
            "lastError": {
              "type": "string",
              "maxLength": 2000
            },
            "createdAt": {
              "type": "integer",
              "minimum": 0,
              "maximum": 9007199254740991
            },
            "updatedAt": {
              "type": "integer",
              "minimum": 0,
              "maximum": 9007199254740991
            },
            "lastCheckedAt": {
              "type": "integer",
              "minimum": 0,
              "maximum": 9007199254740991
            },
            "verifiedAt": {
              "type": "integer",
              "minimum": 0,
              "maximum": 9007199254740991
            },
            "retryRequired": {
              "type": "boolean"
            },
            "operatorRepairRequired": {
              "type": "boolean",
              "const": true
            },
            "checking": {
              "type": "boolean",
              "const": true
            }
          },
          "required": [
            "id",
            "workspaceId",
            "appId",
            "hostname",
            "status",
            "records",
            "conflicts",
            "createdAt",
            "updatedAt"
          ],
          "additionalProperties": false
        },
        {
          "type": "null"
        }
      ]
    }
  },
  "required": [
    "domain"
  ],
  "additionalProperties": false
}
Errors
Error body JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "error": {
      "type": "string",
      "enum": [
        "invalid_request",
        "invalid_cursor",
        "forbidden",
        "domain_occupied",
        "hostname_in_use",
        "domain_cleanup_pending",
        "domain_not_configured",
        "not_found"
      ]
    }
  },
  "required": [
    "error"
  ],
  "additionalProperties": false
}
Delivery
Standard response
Retry
Declared idempotent
POST/v1/ws/{workspaceSlug}/apps/{slug}/domain/recheck

Request a fresh domain check or retry exhausted removal

Scope
ws:{workspaceSlug}:apps
Request
No request body
Response
Response JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "domain": {
      "anyOf": [
        {
          "type": "object",
          "properties": {
            "id": {
              "type": "string"
            },
            "workspaceId": {
              "type": "string"
            },
            "appId": {
              "type": "string"
            },
            "hostname": {
              "type": "string",
              "pattern": "^(?=.{1,253}$)[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)+$"
            },
            "status": {
              "type": "string",
              "enum": [
                "pending",
                "verifying",
                "active",
                "failed",
                "removing"
              ]
            },
            "records": {
              "maxItems": 32,
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "type": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 32,
                    "pattern": "^[\\x20-\\x7e]+$"
                  },
                  "domain": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 253
                  },
                  "value": {
                    "type": "string",
                    "minLength": 1
                  },
                  "reason": {
                    "type": "string"
                  }
                },
                "required": [
                  "type",
                  "domain",
                  "value"
                ],
                "additionalProperties": false
              }
            },
            "conflicts": {
              "maxItems": 32,
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 253
                  },
                  "type": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 32,
                    "pattern": "^[\\x20-\\x7e]+$"
                  },
                  "value": {
                    "type": "string",
                    "minLength": 1
                  }
                },
                "required": [
                  "name",
                  "type",
                  "value"
                ],
                "additionalProperties": false
              }
            },
            "lastError": {
              "type": "string",
              "maxLength": 2000
            },
            "createdAt": {
              "type": "integer",
              "minimum": 0,
              "maximum": 9007199254740991
            },
            "updatedAt": {
              "type": "integer",
              "minimum": 0,
              "maximum": 9007199254740991
            },
            "lastCheckedAt": {
              "type": "integer",
              "minimum": 0,
              "maximum": 9007199254740991
            },
            "verifiedAt": {
              "type": "integer",
              "minimum": 0,
              "maximum": 9007199254740991
            },
            "retryRequired": {
              "type": "boolean"
            },
            "operatorRepairRequired": {
              "type": "boolean",
              "const": true
            },
            "checking": {
              "type": "boolean",
              "const": true
            }
          },
          "required": [
            "id",
            "workspaceId",
            "appId",
            "hostname",
            "status",
            "records",
            "conflicts",
            "createdAt",
            "updatedAt"
          ],
          "additionalProperties": false
        },
        {
          "type": "null"
        }
      ]
    }
  },
  "required": [
    "domain"
  ],
  "additionalProperties": false
}
Errors
Error body JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "error": {
      "type": "string",
      "enum": [
        "invalid_request",
        "invalid_cursor",
        "forbidden",
        "domain_occupied",
        "hostname_in_use",
        "domain_cleanup_pending",
        "domain_not_configured",
        "not_found"
      ]
    }
  },
  "required": [
    "error"
  ],
  "additionalProperties": false
}
Delivery
Standard response
Retry
Not declared idempotent
DELETE/v1/ws/{workspaceSlug}/apps/{slug}/domain

Stop serving a custom hostname and schedule provider cleanup

Scope
ws:{workspaceSlug}:apps
Request
No JSON request body
Response
Response JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "domain": {
      "anyOf": [
        {
          "type": "object",
          "properties": {
            "id": {
              "type": "string"
            },
            "workspaceId": {
              "type": "string"
            },
            "appId": {
              "type": "string"
            },
            "hostname": {
              "type": "string",
              "pattern": "^(?=.{1,253}$)[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)+$"
            },
            "status": {
              "type": "string",
              "enum": [
                "pending",
                "verifying",
                "active",
                "failed",
                "removing"
              ]
            },
            "records": {
              "maxItems": 32,
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "type": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 32,
                    "pattern": "^[\\x20-\\x7e]+$"
                  },
                  "domain": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 253
                  },
                  "value": {
                    "type": "string",
                    "minLength": 1
                  },
                  "reason": {
                    "type": "string"
                  }
                },
                "required": [
                  "type",
                  "domain",
                  "value"
                ],
                "additionalProperties": false
              }
            },
            "conflicts": {
              "maxItems": 32,
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 253
                  },
                  "type": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 32,
                    "pattern": "^[\\x20-\\x7e]+$"
                  },
                  "value": {
                    "type": "string",
                    "minLength": 1
                  }
                },
                "required": [
                  "name",
                  "type",
                  "value"
                ],
                "additionalProperties": false
              }
            },
            "lastError": {
              "type": "string",
              "maxLength": 2000
            },
            "createdAt": {
              "type": "integer",
              "minimum": 0,
              "maximum": 9007199254740991
            },
            "updatedAt": {
              "type": "integer",
              "minimum": 0,
              "maximum": 9007199254740991
            },
            "lastCheckedAt": {
              "type": "integer",
              "minimum": 0,
              "maximum": 9007199254740991
            },
            "verifiedAt": {
              "type": "integer",
              "minimum": 0,
              "maximum": 9007199254740991
            },
            "retryRequired": {
              "type": "boolean"
            },
            "operatorRepairRequired": {
              "type": "boolean",
              "const": true
            },
            "checking": {
              "type": "boolean",
              "const": true
            }
          },
          "required": [
            "id",
            "workspaceId",
            "appId",
            "hostname",
            "status",
            "records",
            "conflicts",
            "createdAt",
            "updatedAt"
          ],
          "additionalProperties": false
        },
        {
          "type": "null"
        }
      ]
    }
  },
  "required": [
    "domain"
  ],
  "additionalProperties": false
}
Errors
Error body JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "error": {
      "type": "string",
      "enum": [
        "invalid_request",
        "invalid_cursor",
        "forbidden",
        "domain_occupied",
        "hostname_in_use",
        "domain_cleanup_pending",
        "domain_not_configured",
        "not_found"
      ]
    }
  },
  "required": [
    "error"
  ],
  "additionalProperties": false
}
Delivery
Standard response
Retry
Declared idempotent
GET/v1/ws/{workspaceSlug}/apps

List workspace apps, optionally filtered by exact id, the deepest app containing a cwd, or drive path

Scope
ws:{workspaceSlug}:apps
Request
No JSON request body
Query
Query parameters JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "cursor": {
      "type": "string",
      "minLength": 1
    },
    "limit": {
      "default": 50,
      "type": "integer",
      "minimum": 1,
      "maximum": 100
    },
    "id": {
      "type": "string",
      "minLength": 1
    },
    "cwd": {
      "type": "string",
      "minLength": 1,
      "maxLength": 1024,
      "pattern": "^[^\\u0000-\\u001f\\u007f]+$"
    },
    "path": {
      "type": "string"
    },
    "scope": {
      "type": "string",
      "enum": [
        "subtree",
        "children",
        "self"
      ]
    }
  },
  "additionalProperties": false
}
Response
Response JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "workspaceId": {
            "type": "string"
          },
          "anchorId": {
            "type": "string"
          },
          "anchorPath": {
            "type": "string"
          },
          "anchorState": {
            "type": "string",
            "enum": [
              "active",
              "broken",
              "orphaned"
            ]
          },
          "command": {
            "type": "string",
            "minLength": 1
          },
          "apiScopes": {
            "maxItems": 64,
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "files:read",
                "files:write",
                "memory",
                "sessions",
                "agents",
                "services",
                "integrations",
                "apps",
                "share",
                "publish",
                "members"
              ]
            }
          },
          "installCommand": {
            "type": "string",
            "minLength": 1
          },
          "port": {
            "type": "integer",
            "minimum": 1,
            "maximum": 65535
          },
          "slug": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "icon": {
            "type": "string"
          },
          "visibility": {
            "type": "string",
            "enum": [
              "folder",
              "public"
            ]
          },
          "canonicalUrl": {
            "type": "string"
          },
          "customDomain": {
            "type": "object",
            "properties": {
              "hostname": {
                "type": "string",
                "pattern": "^(?=.{1,253}$)[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)+$"
              },
              "status": {
                "type": "string",
                "enum": [
                  "pending",
                  "verifying",
                  "active",
                  "failed",
                  "removing"
                ]
              }
            },
            "required": [
              "hostname",
              "status"
            ],
            "additionalProperties": false
          },
          "runtimeStatus": {
            "type": "string",
            "enum": [
              "reconciling",
              "reconciled",
              "reconcile_failed"
            ]
          },
          "reconciliationError": {
            "type": "string",
            "minLength": 1,
            "maxLength": 2000
          },
          "sourceShareId": {
            "type": "string"
          },
          "sourceShareMode": {
            "type": "string",
            "enum": [
              "read",
              "write"
            ]
          },
          "sourceAppId": {
            "type": "string"
          },
          "listingSubscriptionId": {
            "type": "string"
          },
          "disabledAt": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "disabledByUserId": {
            "type": "string"
          },
          "createdByUserId": {
            "type": "string"
          },
          "createdAt": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "updatedAt": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "controls": {
            "type": "object",
            "properties": {
              "manageDomain": {
                "type": "boolean"
              },
              "updateRuntime": {
                "type": "boolean"
              },
              "makePublic": {
                "type": "boolean"
              },
              "makePrivate": {
                "type": "boolean"
              },
              "delete": {
                "type": "boolean"
              }
            },
            "required": [
              "manageDomain",
              "updateRuntime",
              "makePublic",
              "makePrivate",
              "delete"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "id",
          "workspaceId",
          "anchorId",
          "anchorPath",
          "anchorState",
          "command",
          "apiScopes",
          "port",
          "slug",
          "visibility",
          "canonicalUrl",
          "runtimeStatus",
          "createdByUserId",
          "createdAt",
          "updatedAt",
          "controls"
        ],
        "additionalProperties": false
      }
    },
    "nextCursor": {
      "anyOf": [
        {
          "type": "string",
          "minLength": 1
        },
        {
          "type": "null"
        }
      ]
    },
    "meta": {
      "type": "object",
      "properties": {
        "capabilities": {
          "type": "object",
          "properties": {
            "register": {
              "type": "boolean"
            }
          },
          "required": [
            "register"
          ],
          "additionalProperties": false
        }
      },
      "required": [
        "capabilities"
      ],
      "additionalProperties": false
    }
  },
  "required": [
    "items",
    "nextCursor"
  ],
  "additionalProperties": false
}
Errors
Opaque collection cursor is malformed or bound to another walk (400)
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "error": {
      "type": "string",
      "const": "invalid_cursor"
    }
  },
  "required": [
    "error"
  ],
  "additionalProperties": false,
  "description": "Opaque collection cursor is malformed or bound to another walk (400)"
}
Delivery
Standard response
Retry
Not declared idempotent
GET/v1/ws/{workspaceSlug}/apps/{slug}/launch

Open an app through a short-lived access grant, optionally returning to its validated host and path

Scope
ws:{workspaceSlug}:apps
Request
No JSON request body
Query
Query parameters JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "host": {
      "type": "string"
    },
    "path": {
      "type": "string"
    }
  },
  "additionalProperties": false
}
Response
No structured response body
Delivery
Standard response
Retry
Not declared idempotent
POST/v1/ws/{workspaceSlug}/apps

Register a workspace folder as an app runtime with optional display metadata

Scope
ws:{workspaceSlug}:apps
Request
Request JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "path": {
      "type": "string",
      "minLength": 1
    },
    "command": {
      "type": "string"
    },
    "apiScopes": {
      "maxItems": 64,
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "files:read",
          "files:write",
          "memory",
          "sessions",
          "agents",
          "services",
          "integrations",
          "apps",
          "share",
          "publish",
          "members"
        ]
      }
    },
    "installCommand": {
      "type": "string"
    },
    "port": {
      "type": "integer",
      "minimum": 1,
      "maximum": 65535
    },
    "slug": {
      "type": "string"
    },
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 64
    },
    "icon": {
      "type": "string"
    }
  },
  "required": [
    "path",
    "command",
    "apiScopes",
    "slug"
  ]
}
Response
Response JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "app": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string"
        },
        "workspaceId": {
          "type": "string"
        },
        "anchorId": {
          "type": "string"
        },
        "anchorPath": {
          "type": "string"
        },
        "anchorState": {
          "type": "string",
          "enum": [
            "active",
            "broken",
            "orphaned"
          ]
        },
        "command": {
          "type": "string",
          "minLength": 1
        },
        "apiScopes": {
          "maxItems": 64,
          "type": "array",
          "items": {
            "type": "string",
            "enum": [
              "files:read",
              "files:write",
              "memory",
              "sessions",
              "agents",
              "services",
              "integrations",
              "apps",
              "share",
              "publish",
              "members"
            ]
          }
        },
        "installCommand": {
          "type": "string",
          "minLength": 1
        },
        "port": {
          "type": "integer",
          "minimum": 1,
          "maximum": 65535
        },
        "slug": {
          "type": "string"
        },
        "name": {
          "type": "string"
        },
        "icon": {
          "type": "string"
        },
        "visibility": {
          "type": "string",
          "enum": [
            "folder",
            "public"
          ]
        },
        "canonicalUrl": {
          "type": "string"
        },
        "customDomain": {
          "type": "object",
          "properties": {
            "hostname": {
              "type": "string",
              "pattern": "^(?=.{1,253}$)[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)+$"
            },
            "status": {
              "type": "string",
              "enum": [
                "pending",
                "verifying",
                "active",
                "failed",
                "removing"
              ]
            }
          },
          "required": [
            "hostname",
            "status"
          ],
          "additionalProperties": false
        },
        "runtimeStatus": {
          "type": "string",
          "enum": [
            "reconciling",
            "reconciled",
            "reconcile_failed"
          ]
        },
        "reconciliationError": {
          "type": "string",
          "minLength": 1,
          "maxLength": 2000
        },
        "sourceShareId": {
          "type": "string"
        },
        "sourceShareMode": {
          "type": "string",
          "enum": [
            "read",
            "write"
          ]
        },
        "sourceAppId": {
          "type": "string"
        },
        "listingSubscriptionId": {
          "type": "string"
        },
        "disabledAt": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991
        },
        "disabledByUserId": {
          "type": "string"
        },
        "createdByUserId": {
          "type": "string"
        },
        "createdAt": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991
        },
        "updatedAt": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991
        },
        "controls": {
          "type": "object",
          "properties": {
            "manageDomain": {
              "type": "boolean"
            },
            "updateRuntime": {
              "type": "boolean"
            },
            "makePublic": {
              "type": "boolean"
            },
            "makePrivate": {
              "type": "boolean"
            },
            "delete": {
              "type": "boolean"
            }
          },
          "required": [
            "manageDomain",
            "updateRuntime",
            "makePublic",
            "makePrivate",
            "delete"
          ],
          "additionalProperties": false
        }
      },
      "required": [
        "id",
        "workspaceId",
        "anchorId",
        "anchorPath",
        "anchorState",
        "command",
        "apiScopes",
        "port",
        "slug",
        "visibility",
        "canonicalUrl",
        "runtimeStatus",
        "createdByUserId",
        "createdAt",
        "updatedAt",
        "controls"
      ],
      "additionalProperties": false
    }
  },
  "required": [
    "app"
  ],
  "additionalProperties": false
}
Delivery
Standard response
Retry
Not declared idempotent
GET/v1/ws/{workspaceSlug}/apps/{appSlug}

Get one registered app by slug

Scope
ws:{workspaceSlug}:apps
Request
No JSON request body
Response
Response JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "app": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string"
        },
        "workspaceId": {
          "type": "string"
        },
        "anchorId": {
          "type": "string"
        },
        "anchorPath": {
          "type": "string"
        },
        "anchorState": {
          "type": "string",
          "enum": [
            "active",
            "broken",
            "orphaned"
          ]
        },
        "command": {
          "type": "string",
          "minLength": 1
        },
        "apiScopes": {
          "maxItems": 64,
          "type": "array",
          "items": {
            "type": "string",
            "enum": [
              "files:read",
              "files:write",
              "memory",
              "sessions",
              "agents",
              "services",
              "integrations",
              "apps",
              "share",
              "publish",
              "members"
            ]
          }
        },
        "installCommand": {
          "type": "string",
          "minLength": 1
        },
        "port": {
          "type": "integer",
          "minimum": 1,
          "maximum": 65535
        },
        "slug": {
          "type": "string"
        },
        "name": {
          "type": "string"
        },
        "icon": {
          "type": "string"
        },
        "visibility": {
          "type": "string",
          "enum": [
            "folder",
            "public"
          ]
        },
        "canonicalUrl": {
          "type": "string"
        },
        "customDomain": {
          "type": "object",
          "properties": {
            "hostname": {
              "type": "string",
              "pattern": "^(?=.{1,253}$)[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)+$"
            },
            "status": {
              "type": "string",
              "enum": [
                "pending",
                "verifying",
                "active",
                "failed",
                "removing"
              ]
            }
          },
          "required": [
            "hostname",
            "status"
          ],
          "additionalProperties": false
        },
        "runtimeStatus": {
          "type": "string",
          "enum": [
            "reconciling",
            "reconciled",
            "reconcile_failed"
          ]
        },
        "reconciliationError": {
          "type": "string",
          "minLength": 1,
          "maxLength": 2000
        },
        "sourceShareId": {
          "type": "string"
        },
        "sourceShareMode": {
          "type": "string",
          "enum": [
            "read",
            "write"
          ]
        },
        "sourceAppId": {
          "type": "string"
        },
        "listingSubscriptionId": {
          "type": "string"
        },
        "disabledAt": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991
        },
        "disabledByUserId": {
          "type": "string"
        },
        "createdByUserId": {
          "type": "string"
        },
        "createdAt": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991
        },
        "updatedAt": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991
        },
        "controls": {
          "type": "object",
          "properties": {
            "manageDomain": {
              "type": "boolean"
            },
            "updateRuntime": {
              "type": "boolean"
            },
            "makePublic": {
              "type": "boolean"
            },
            "makePrivate": {
              "type": "boolean"
            },
            "delete": {
              "type": "boolean"
            }
          },
          "required": [
            "manageDomain",
            "updateRuntime",
            "makePublic",
            "makePrivate",
            "delete"
          ],
          "additionalProperties": false
        }
      },
      "required": [
        "id",
        "workspaceId",
        "anchorId",
        "anchorPath",
        "anchorState",
        "command",
        "apiScopes",
        "port",
        "slug",
        "visibility",
        "canonicalUrl",
        "runtimeStatus",
        "createdByUserId",
        "createdAt",
        "updatedAt",
        "controls"
      ],
      "additionalProperties": false
    }
  },
  "required": [
    "app"
  ],
  "additionalProperties": false
}
Delivery
Standard response
Retry
Not declared idempotent
PATCH/v1/ws/{workspaceSlug}/apps/{appSlug}

Update app display metadata or reconcile changed runtime settings

Scope
ws:{workspaceSlug}:apps
Request
Request JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "command": {
      "type": "string"
    },
    "apiScopes": {
      "maxItems": 64,
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "files:read",
          "files:write",
          "memory",
          "sessions",
          "agents",
          "services",
          "integrations",
          "apps",
          "share",
          "publish",
          "members"
        ]
      }
    },
    "installCommand": {
      "type": "string"
    },
    "port": {
      "type": "integer",
      "minimum": 1,
      "maximum": 65535
    },
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 64
    },
    "icon": {
      "type": "string"
    }
  }
}
Response
Response JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "app": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string"
        },
        "workspaceId": {
          "type": "string"
        },
        "anchorId": {
          "type": "string"
        },
        "anchorPath": {
          "type": "string"
        },
        "anchorState": {
          "type": "string",
          "enum": [
            "active",
            "broken",
            "orphaned"
          ]
        },
        "command": {
          "type": "string",
          "minLength": 1
        },
        "apiScopes": {
          "maxItems": 64,
          "type": "array",
          "items": {
            "type": "string",
            "enum": [
              "files:read",
              "files:write",
              "memory",
              "sessions",
              "agents",
              "services",
              "integrations",
              "apps",
              "share",
              "publish",
              "members"
            ]
          }
        },
        "installCommand": {
          "type": "string",
          "minLength": 1
        },
        "port": {
          "type": "integer",
          "minimum": 1,
          "maximum": 65535
        },
        "slug": {
          "type": "string"
        },
        "name": {
          "type": "string"
        },
        "icon": {
          "type": "string"
        },
        "visibility": {
          "type": "string",
          "enum": [
            "folder",
            "public"
          ]
        },
        "canonicalUrl": {
          "type": "string"
        },
        "customDomain": {
          "type": "object",
          "properties": {
            "hostname": {
              "type": "string",
              "pattern": "^(?=.{1,253}$)[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)+$"
            },
            "status": {
              "type": "string",
              "enum": [
                "pending",
                "verifying",
                "active",
                "failed",
                "removing"
              ]
            }
          },
          "required": [
            "hostname",
            "status"
          ],
          "additionalProperties": false
        },
        "runtimeStatus": {
          "type": "string",
          "enum": [
            "reconciling",
            "reconciled",
            "reconcile_failed"
          ]
        },
        "reconciliationError": {
          "type": "string",
          "minLength": 1,
          "maxLength": 2000
        },
        "sourceShareId": {
          "type": "string"
        },
        "sourceShareMode": {
          "type": "string",
          "enum": [
            "read",
            "write"
          ]
        },
        "sourceAppId": {
          "type": "string"
        },
        "listingSubscriptionId": {
          "type": "string"
        },
        "disabledAt": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991
        },
        "disabledByUserId": {
          "type": "string"
        },
        "createdByUserId": {
          "type": "string"
        },
        "createdAt": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991
        },
        "updatedAt": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991
        },
        "controls": {
          "type": "object",
          "properties": {
            "manageDomain": {
              "type": "boolean"
            },
            "updateRuntime": {
              "type": "boolean"
            },
            "makePublic": {
              "type": "boolean"
            },
            "makePrivate": {
              "type": "boolean"
            },
            "delete": {
              "type": "boolean"
            }
          },
          "required": [
            "manageDomain",
            "updateRuntime",
            "makePublic",
            "makePrivate",
            "delete"
          ],
          "additionalProperties": false
        }
      },
      "required": [
        "id",
        "workspaceId",
        "anchorId",
        "anchorPath",
        "anchorState",
        "command",
        "apiScopes",
        "port",
        "slug",
        "visibility",
        "canonicalUrl",
        "runtimeStatus",
        "createdByUserId",
        "createdAt",
        "updatedAt",
        "controls"
      ],
      "additionalProperties": false
    }
  },
  "required": [
    "app"
  ],
  "additionalProperties": false
}
Delivery
Standard response
Retry
Not declared idempotent
POST/v1/ws/{workspaceSlug}/apps/{appSlug}/reanchor

Repair a broken app anchor by slug after the automatic move rail cannot recover its folder

Scope
ws:{workspaceSlug}:apps
Request
Request JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "path": {
      "type": "string"
    }
  },
  "required": [
    "path"
  ]
}
Response
Response JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "app": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string"
        },
        "workspaceId": {
          "type": "string"
        },
        "anchorId": {
          "type": "string"
        },
        "anchorPath": {
          "type": "string"
        },
        "anchorState": {
          "type": "string",
          "enum": [
            "active",
            "broken",
            "orphaned"
          ]
        },
        "command": {
          "type": "string",
          "minLength": 1
        },
        "apiScopes": {
          "maxItems": 64,
          "type": "array",
          "items": {
            "type": "string",
            "enum": [
              "files:read",
              "files:write",
              "memory",
              "sessions",
              "agents",
              "services",
              "integrations",
              "apps",
              "share",
              "publish",
              "members"
            ]
          }
        },
        "installCommand": {
          "type": "string",
          "minLength": 1
        },
        "port": {
          "type": "integer",
          "minimum": 1,
          "maximum": 65535
        },
        "slug": {
          "type": "string"
        },
        "name": {
          "type": "string"
        },
        "icon": {
          "type": "string"
        },
        "visibility": {
          "type": "string",
          "enum": [
            "folder",
            "public"
          ]
        },
        "canonicalUrl": {
          "type": "string"
        },
        "customDomain": {
          "type": "object",
          "properties": {
            "hostname": {
              "type": "string",
              "pattern": "^(?=.{1,253}$)[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)+$"
            },
            "status": {
              "type": "string",
              "enum": [
                "pending",
                "verifying",
                "active",
                "failed",
                "removing"
              ]
            }
          },
          "required": [
            "hostname",
            "status"
          ],
          "additionalProperties": false
        },
        "runtimeStatus": {
          "type": "string",
          "enum": [
            "reconciling",
            "reconciled",
            "reconcile_failed"
          ]
        },
        "reconciliationError": {
          "type": "string",
          "minLength": 1,
          "maxLength": 2000
        },
        "sourceShareId": {
          "type": "string"
        },
        "sourceShareMode": {
          "type": "string",
          "enum": [
            "read",
            "write"
          ]
        },
        "sourceAppId": {
          "type": "string"
        },
        "listingSubscriptionId": {
          "type": "string"
        },
        "disabledAt": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991
        },
        "disabledByUserId": {
          "type": "string"
        },
        "createdByUserId": {
          "type": "string"
        },
        "createdAt": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991
        },
        "updatedAt": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991
        },
        "controls": {
          "type": "object",
          "properties": {
            "manageDomain": {
              "type": "boolean"
            },
            "updateRuntime": {
              "type": "boolean"
            },
            "makePublic": {
              "type": "boolean"
            },
            "makePrivate": {
              "type": "boolean"
            },
            "delete": {
              "type": "boolean"
            }
          },
          "required": [
            "manageDomain",
            "updateRuntime",
            "makePublic",
            "makePrivate",
            "delete"
          ],
          "additionalProperties": false
        }
      },
      "required": [
        "id",
        "workspaceId",
        "anchorId",
        "anchorPath",
        "anchorState",
        "command",
        "apiScopes",
        "port",
        "slug",
        "visibility",
        "canonicalUrl",
        "runtimeStatus",
        "createdByUserId",
        "createdAt",
        "updatedAt",
        "controls"
      ],
      "additionalProperties": false
    }
  },
  "required": [
    "app"
  ],
  "additionalProperties": false
}
Delivery
Standard response
Retry
Not declared idempotent
POST/v1/ws/{workspaceSlug}/apps/{appSlug}/visibility

Make an app workspace-only or public

Scope
ws:{workspaceSlug}:apps
Request
Request JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "visibility": {
      "type": "string",
      "enum": [
        "folder",
        "public"
      ]
    }
  },
  "required": [
    "visibility"
  ]
}
Response
Response JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "app": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string"
        },
        "workspaceId": {
          "type": "string"
        },
        "anchorId": {
          "type": "string"
        },
        "anchorPath": {
          "type": "string"
        },
        "anchorState": {
          "type": "string",
          "enum": [
            "active",
            "broken",
            "orphaned"
          ]
        },
        "command": {
          "type": "string",
          "minLength": 1
        },
        "apiScopes": {
          "maxItems": 64,
          "type": "array",
          "items": {
            "type": "string",
            "enum": [
              "files:read",
              "files:write",
              "memory",
              "sessions",
              "agents",
              "services",
              "integrations",
              "apps",
              "share",
              "publish",
              "members"
            ]
          }
        },
        "installCommand": {
          "type": "string",
          "minLength": 1
        },
        "port": {
          "type": "integer",
          "minimum": 1,
          "maximum": 65535
        },
        "slug": {
          "type": "string"
        },
        "name": {
          "type": "string"
        },
        "icon": {
          "type": "string"
        },
        "visibility": {
          "type": "string",
          "enum": [
            "folder",
            "public"
          ]
        },
        "canonicalUrl": {
          "type": "string"
        },
        "customDomain": {
          "type": "object",
          "properties": {
            "hostname": {
              "type": "string",
              "pattern": "^(?=.{1,253}$)[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)+$"
            },
            "status": {
              "type": "string",
              "enum": [
                "pending",
                "verifying",
                "active",
                "failed",
                "removing"
              ]
            }
          },
          "required": [
            "hostname",
            "status"
          ],
          "additionalProperties": false
        },
        "runtimeStatus": {
          "type": "string",
          "enum": [
            "reconciling",
            "reconciled",
            "reconcile_failed"
          ]
        },
        "reconciliationError": {
          "type": "string",
          "minLength": 1,
          "maxLength": 2000
        },
        "sourceShareId": {
          "type": "string"
        },
        "sourceShareMode": {
          "type": "string",
          "enum": [
            "read",
            "write"
          ]
        },
        "sourceAppId": {
          "type": "string"
        },
        "listingSubscriptionId": {
          "type": "string"
        },
        "disabledAt": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991
        },
        "disabledByUserId": {
          "type": "string"
        },
        "createdByUserId": {
          "type": "string"
        },
        "createdAt": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991
        },
        "updatedAt": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991
        },
        "controls": {
          "type": "object",
          "properties": {
            "manageDomain": {
              "type": "boolean"
            },
            "updateRuntime": {
              "type": "boolean"
            },
            "makePublic": {
              "type": "boolean"
            },
            "makePrivate": {
              "type": "boolean"
            },
            "delete": {
              "type": "boolean"
            }
          },
          "required": [
            "manageDomain",
            "updateRuntime",
            "makePublic",
            "makePrivate",
            "delete"
          ],
          "additionalProperties": false
        }
      },
      "required": [
        "id",
        "workspaceId",
        "anchorId",
        "anchorPath",
        "anchorState",
        "command",
        "apiScopes",
        "port",
        "slug",
        "visibility",
        "canonicalUrl",
        "runtimeStatus",
        "createdByUserId",
        "createdAt",
        "updatedAt",
        "controls"
      ],
      "additionalProperties": false
    }
  },
  "required": [
    "app"
  ],
  "additionalProperties": false
}
Delivery
Standard response
Retry
Declared idempotent
POST/v1/ws/{workspaceSlug}/apps/{appSlug}/disabled

Disable or re-enable a shared app replica

Scope
ws:{workspaceSlug}:apps
Request
Request JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "disabled": {
      "type": "boolean"
    }
  },
  "required": [
    "disabled"
  ]
}
Response
Response JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "app": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string"
        },
        "workspaceId": {
          "type": "string"
        },
        "anchorId": {
          "type": "string"
        },
        "anchorPath": {
          "type": "string"
        },
        "anchorState": {
          "type": "string",
          "enum": [
            "active",
            "broken",
            "orphaned"
          ]
        },
        "command": {
          "type": "string",
          "minLength": 1
        },
        "apiScopes": {
          "maxItems": 64,
          "type": "array",
          "items": {
            "type": "string",
            "enum": [
              "files:read",
              "files:write",
              "memory",
              "sessions",
              "agents",
              "services",
              "integrations",
              "apps",
              "share",
              "publish",
              "members"
            ]
          }
        },
        "installCommand": {
          "type": "string",
          "minLength": 1
        },
        "port": {
          "type": "integer",
          "minimum": 1,
          "maximum": 65535
        },
        "slug": {
          "type": "string"
        },
        "name": {
          "type": "string"
        },
        "icon": {
          "type": "string"
        },
        "visibility": {
          "type": "string",
          "enum": [
            "folder",
            "public"
          ]
        },
        "canonicalUrl": {
          "type": "string"
        },
        "customDomain": {
          "type": "object",
          "properties": {
            "hostname": {
              "type": "string",
              "pattern": "^(?=.{1,253}$)[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)+$"
            },
            "status": {
              "type": "string",
              "enum": [
                "pending",
                "verifying",
                "active",
                "failed",
                "removing"
              ]
            }
          },
          "required": [
            "hostname",
            "status"
          ],
          "additionalProperties": false
        },
        "runtimeStatus": {
          "type": "string",
          "enum": [
            "reconciling",
            "reconciled",
            "reconcile_failed"
          ]
        },
        "reconciliationError": {
          "type": "string",
          "minLength": 1,
          "maxLength": 2000
        },
        "sourceShareId": {
          "type": "string"
        },
        "sourceShareMode": {
          "type": "string",
          "enum": [
            "read",
            "write"
          ]
        },
        "sourceAppId": {
          "type": "string"
        },
        "listingSubscriptionId": {
          "type": "string"
        },
        "disabledAt": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991
        },
        "disabledByUserId": {
          "type": "string"
        },
        "createdByUserId": {
          "type": "string"
        },
        "createdAt": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991
        },
        "updatedAt": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991
        },
        "controls": {
          "type": "object",
          "properties": {
            "manageDomain": {
              "type": "boolean"
            },
            "updateRuntime": {
              "type": "boolean"
            },
            "makePublic": {
              "type": "boolean"
            },
            "makePrivate": {
              "type": "boolean"
            },
            "delete": {
              "type": "boolean"
            }
          },
          "required": [
            "manageDomain",
            "updateRuntime",
            "makePublic",
            "makePrivate",
            "delete"
          ],
          "additionalProperties": false
        }
      },
      "required": [
        "id",
        "workspaceId",
        "anchorId",
        "anchorPath",
        "anchorState",
        "command",
        "apiScopes",
        "port",
        "slug",
        "visibility",
        "canonicalUrl",
        "runtimeStatus",
        "createdByUserId",
        "createdAt",
        "updatedAt",
        "controls"
      ],
      "additionalProperties": false
    }
  },
  "required": [
    "app"
  ],
  "additionalProperties": false
}
Delivery
Standard response
Retry
Declared idempotent
DELETE/v1/ws/{workspaceSlug}/apps/{appSlug}

Stop serving and unregister an app

Scope
ws:{workspaceSlug}:apps
Request
No JSON request body
Response
Response JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "ok": {
      "type": "boolean",
      "const": true
    }
  },
  "required": [
    "ok"
  ],
  "additionalProperties": false
}
Delivery
Standard response
Retry
Declared idempotent