Browse documentationWorkspace selection

Identity

Select the workspace for the operation

A Duet client resolves its target workspace before starting work. A human key identifies the person, and current membership and role determine access to the workspace named by the operation. Changing that target does not change the login. App and OAuth credentials retain their explicit workspace boundaries; see API keys and access.

Keep human choice visible

When a user belongs to several workspaces, display the selected workspace and persist its stable identity with the integration configuration. Do not guess from the most recently visited browser page or fall back to the first membership.

Slugs are addresses

Slugs make workspace routes and scopes readable, but they are still protocol identifiers. Validate them with the shared contract grammar, encode dynamic path segments, and plan for a rename to break old public URLs rather than hiding the break behind an ambiguous redirect.

Choose local or remote CLI work explicitly

duet workspace use <slug> saves a default for remote commands and Duet model billing. An explicit workspace address or --workspace <slug> selects an operation target. If a file address and a workspace flag name different workspaces, the command fails before sending a request.

Prompts run locally. memory and train run locally unless --workspace selects the remote operation. A saved default never turns local work into a remote command:

duet memory recall "notes" \
  --workspace acme
duet train --workspace acme \
  --file ./sessions.jsonl

Human model requests send x-duet-workspace to select the workspace that pays. The gateway checks live access and payer policy; an omitted target never silently chooses the first membership.

Invite workspace members

Use a workspace owner's key with the members capability to create, list, or revoke invitations. Creating an invitation sends the recipient a Duet email; your integration does not need to send another message. Invitations are bound to one canonical email, expire after seven days, and grant either editor or viewer access.

The recipient follows the email link and signs in with the invited email address. Duet accepts the invitation and opens that workspace, without requiring personal workspace setup. A new account created through this link joins the invited workspace without creating a personal one. An existing account keeps its other workspaces.

If the recipient signs up normally instead, they get the normal personal workspace setup and can accept the pending invitation from the bar in the Duet app. Acceptance belongs to the recipient's account: the recipient's human login can list and accept their invitations; an app or OAuth grant cannot act as that person's account. Your integration manages outgoing invitations through the workspace endpoints below; the recipient completes the handoff in Duet.

Workspace owners may change member roles, but the durable workspace domain preserves two invariants: every workspace retains an owner, and the designated payer remains an owner until billing is reassigned. Consumers should surface the conflict rather than trying to sequence a client-side workaround.

Audit events are returned newest-first with opaque cursors. Treat a cursor as a continuation token, not as a timestamp or stable event identifier.

Set the agent tier fallback

Owners can set a workspace's default tier through the single-purpose default-model endpoint using a tier selection. For example, { "tier": "openai-frontier" } chooses a stable provider alias. The accepted session selections apply here too. This is a fallback for sessions without a sticky choice, not a rewrite of queued prompts or existing session preferences. Every selection is available to every workspace. Explicit provider aliases survive subscription-plan changes.

Lifecycle and path repair

Workspace creation returns while provisioning continues. Reprovisioning is an owner-only recovery operation, not a retry strategy for ordinary request failures. Renaming requires an explicit acknowledgement because workspace-scoped URLs change.

Apps, publishes, and share roots retain path anchors. List anchors to diagnose a moved path; repair only an anchor in the broken state, using the capability that owns its kind.

Read VM telemetry history

Workspace members can read the VM's recent CPU, memory, and disk history. The optional sinceAt query value is a Unix timestamp in milliseconds; without it, the service returns the retained 30-day window. Long windows are downsampled to a bounded chart response, so treat points as trend buckets rather than exact latest readings. Memory and disk expose used and total values separately, and an absent metric means that sample could not observe it.

Export a workspace backup

Use the workspace admin capability to capture a private ZIP in the background. The workspace agent's normal credential includes this capability. A files-only key cannot export the workspace.

Send a unique request ID when starting an export; reuse that ID if the response is lost. The response is 202 with a durable backup record. Only one capture runs per workspace. A distinct request while capture is active returns 409 backup_in_progress and the active backup ID.

{
  "requestId": "backup-2026-09-29-release"
}
curl -X POST "https://ctl.duet.so/v1/ws/$WORKSPACE/backups" \
  -H "Authorization: Bearer $DUET_API_KEY" \
  -H "Content-Type: application/json" \
  --data '{"requestId":"backup-2026-09-29-release"}'

Poll the returned backup ID until it is ready or failed. Progress shows observed files, records, and bytes rather than a percentage. A failed capture has no download; retry with a new request ID to create a fresh attempt. Closing the client does not cancel capture.

The ZIP contains the complete Drive, including hidden files, .env secrets, dependencies, and symlinks, plus portable workspace configuration and session history with image bytes. It excludes workspace membership and Duet platform credentials. Capture runs alongside live writers; it is not a transaction snapshot and cannot detect every change. A ready backup marked partial is still downloadable: read its warnings before relying on it. The archive's root README.md explains recovery through current APIs. Historical chats remain files; there is no chat-history import or running-process continuation promise.

Mint a download URL only when needed. It expires, but the stored backup remains until explicitly deleted, including when its source VM is unavailable. Request a new URL after expiry; do not persist the URL alongside the backup record. The response includes archive bytes and SHA-256 so an agent can verify the downloaded ZIP.

Deletion immediately removes download access and cancels active capture. A 202 means storage cleanup is still pending; an absent backup is an idempotent success. A backup needed by an accepted workspace operation cannot be deleted yet. If emptyDriveOnNextStart is true, deletion removed an archived workspace's recovery backup: its next start uses an empty Drive while keeping its workspace records. This does not remove a running workspace's files or another retained backup.

Backups

5 operations
POST/v1/ws/{workspaceSlug}/backups

Start a durable workspace ZIP capture; returns 202 and replays the same request ID.

Scope
ws:{workspaceSlug}:admin
Request
Request JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "requestId": {
      "type": "string",
      "minLength": 1,
      "maxLength": 128
    }
  },
  "required": [
    "requestId"
  ],
  "additionalProperties": false
}
Response
Response JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "backup": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string"
        },
        "workspaceId": {
          "type": "string"
        },
        "purpose": {
          "type": "string",
          "enum": [
            "export",
            "archive",
            "reprovision"
          ]
        },
        "status": {
          "type": "string",
          "enum": [
            "queued",
            "running",
            "ready",
            "failed",
            "deleting"
          ]
        },
        "phase": {
          "type": "string",
          "enum": [
            "metadata",
            "files",
            "upload",
            "finalizing"
          ]
        },
        "createdAt": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991
        },
        "updatedAt": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991
        },
        "startedAt": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991
        },
        "completedAt": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991
        },
        "progress": {
          "type": "object",
          "properties": {
            "processedFiles": {
              "type": "integer",
              "minimum": 0,
              "maximum": 9007199254740991
            },
            "processedRecords": {
              "type": "integer",
              "minimum": 0,
              "maximum": 9007199254740991
            },
            "capturedBytes": {
              "type": "integer",
              "minimum": 0,
              "maximum": 9007199254740991
            },
            "uploadedBytes": {
              "type": "integer",
              "minimum": 0,
              "maximum": 9007199254740991
            },
            "warningCount": {
              "type": "integer",
              "minimum": 0,
              "maximum": 9007199254740991
            },
            "warningSummary": {
              "maxItems": 32,
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "code": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 80
                  },
                  "count": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 9007199254740991
                  }
                },
                "required": [
                  "code",
                  "count"
                ],
                "additionalProperties": false
              }
            }
          },
          "required": [
            "processedFiles",
            "processedRecords",
            "capturedBytes",
            "uploadedBytes",
            "warningCount",
            "warningSummary"
          ],
          "additionalProperties": false
        },
        "completeness": {
          "type": "string",
          "enum": [
            "complete",
            "partial"
          ]
        },
        "bytes": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991
        },
        "sha256": {
          "type": "string",
          "pattern": "^[a-f0-9]{64}$"
        },
        "error": {
          "type": "object",
          "properties": {
            "code": {
              "type": "string",
              "enum": [
                "vm_unavailable",
                "interrupted",
                "stalled",
                "capture_failed",
                "upload_failed",
                "object_mismatch",
                "cleanup_failed"
              ]
            },
            "message": {
              "type": "string",
              "maxLength": 1024
            }
          },
          "required": [
            "code",
            "message"
          ],
          "additionalProperties": false
        },
        "lifecycle": {
          "type": "object",
          "properties": {
            "kind": {
              "type": "string",
              "enum": [
                "reprovision",
                "archive",
                "servicing"
              ]
            },
            "status": {
              "type": "string",
              "enum": [
                "capturing",
                "restoring",
                "complete",
                "failed",
                "deferred",
                "abandoned"
              ]
            },
            "reason": {
              "type": "string"
            }
          },
          "required": [
            "kind",
            "status"
          ],
          "additionalProperties": false
        }
      },
      "required": [
        "id",
        "workspaceId",
        "purpose",
        "status",
        "createdAt",
        "updatedAt",
        "progress"
      ],
      "additionalProperties": false
    }
  },
  "required": [
    "backup"
  ],
  "additionalProperties": false
}
Errors
Error body JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "error": {
      "type": "string",
      "const": "backup_in_progress"
    },
    "backupId": {
      "type": "string"
    }
  },
  "required": [
    "error",
    "backupId"
  ],
  "additionalProperties": false
}
Delivery
Standard response
Retry
Declared idempotent
GET/v1/ws/{workspaceSlug}/backups

Page retained workspace backups, newest first, without download grants.

Scope
ws:{workspaceSlug}:admin
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": {
          "id": {
            "type": "string"
          },
          "workspaceId": {
            "type": "string"
          },
          "purpose": {
            "type": "string",
            "enum": [
              "export",
              "archive",
              "reprovision"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "running",
              "ready",
              "failed",
              "deleting"
            ]
          },
          "phase": {
            "type": "string",
            "enum": [
              "metadata",
              "files",
              "upload",
              "finalizing"
            ]
          },
          "createdAt": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "updatedAt": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "startedAt": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "completedAt": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "progress": {
            "type": "object",
            "properties": {
              "processedFiles": {
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "processedRecords": {
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "capturedBytes": {
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "uploadedBytes": {
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "warningCount": {
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "warningSummary": {
                "maxItems": 32,
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 80
                    },
                    "count": {
                      "type": "integer",
                      "minimum": 0,
                      "maximum": 9007199254740991
                    }
                  },
                  "required": [
                    "code",
                    "count"
                  ],
                  "additionalProperties": false
                }
              }
            },
            "required": [
              "processedFiles",
              "processedRecords",
              "capturedBytes",
              "uploadedBytes",
              "warningCount",
              "warningSummary"
            ],
            "additionalProperties": false
          },
          "completeness": {
            "type": "string",
            "enum": [
              "complete",
              "partial"
            ]
          },
          "bytes": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "sha256": {
            "type": "string",
            "pattern": "^[a-f0-9]{64}$"
          },
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string",
                "enum": [
                  "vm_unavailable",
                  "interrupted",
                  "stalled",
                  "capture_failed",
                  "upload_failed",
                  "object_mismatch",
                  "cleanup_failed"
                ]
              },
              "message": {
                "type": "string",
                "maxLength": 1024
              }
            },
            "required": [
              "code",
              "message"
            ],
            "additionalProperties": false
          },
          "lifecycle": {
            "type": "object",
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "reprovision",
                  "archive",
                  "servicing"
                ]
              },
              "status": {
                "type": "string",
                "enum": [
                  "capturing",
                  "restoring",
                  "complete",
                  "failed",
                  "deferred",
                  "abandoned"
                ]
              },
              "reason": {
                "type": "string"
              }
            },
            "required": [
              "kind",
              "status"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "id",
          "workspaceId",
          "purpose",
          "status",
          "createdAt",
          "updatedAt",
          "progress"
        ],
        "additionalProperties": false
      }
    },
    "nextCursor": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ]
    }
  },
  "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}/backups/{backupId}

Read durable capture status, counters, and warning summary.

Scope
ws:{workspaceSlug}:admin
Request
No JSON request body
Response
Response JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "backup": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string"
        },
        "workspaceId": {
          "type": "string"
        },
        "purpose": {
          "type": "string",
          "enum": [
            "export",
            "archive",
            "reprovision"
          ]
        },
        "status": {
          "type": "string",
          "enum": [
            "queued",
            "running",
            "ready",
            "failed",
            "deleting"
          ]
        },
        "phase": {
          "type": "string",
          "enum": [
            "metadata",
            "files",
            "upload",
            "finalizing"
          ]
        },
        "createdAt": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991
        },
        "updatedAt": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991
        },
        "startedAt": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991
        },
        "completedAt": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991
        },
        "progress": {
          "type": "object",
          "properties": {
            "processedFiles": {
              "type": "integer",
              "minimum": 0,
              "maximum": 9007199254740991
            },
            "processedRecords": {
              "type": "integer",
              "minimum": 0,
              "maximum": 9007199254740991
            },
            "capturedBytes": {
              "type": "integer",
              "minimum": 0,
              "maximum": 9007199254740991
            },
            "uploadedBytes": {
              "type": "integer",
              "minimum": 0,
              "maximum": 9007199254740991
            },
            "warningCount": {
              "type": "integer",
              "minimum": 0,
              "maximum": 9007199254740991
            },
            "warningSummary": {
              "maxItems": 32,
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "code": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 80
                  },
                  "count": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 9007199254740991
                  }
                },
                "required": [
                  "code",
                  "count"
                ],
                "additionalProperties": false
              }
            }
          },
          "required": [
            "processedFiles",
            "processedRecords",
            "capturedBytes",
            "uploadedBytes",
            "warningCount",
            "warningSummary"
          ],
          "additionalProperties": false
        },
        "completeness": {
          "type": "string",
          "enum": [
            "complete",
            "partial"
          ]
        },
        "bytes": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991
        },
        "sha256": {
          "type": "string",
          "pattern": "^[a-f0-9]{64}$"
        },
        "error": {
          "type": "object",
          "properties": {
            "code": {
              "type": "string",
              "enum": [
                "vm_unavailable",
                "interrupted",
                "stalled",
                "capture_failed",
                "upload_failed",
                "object_mismatch",
                "cleanup_failed"
              ]
            },
            "message": {
              "type": "string",
              "maxLength": 1024
            }
          },
          "required": [
            "code",
            "message"
          ],
          "additionalProperties": false
        },
        "lifecycle": {
          "type": "object",
          "properties": {
            "kind": {
              "type": "string",
              "enum": [
                "reprovision",
                "archive",
                "servicing"
              ]
            },
            "status": {
              "type": "string",
              "enum": [
                "capturing",
                "restoring",
                "complete",
                "failed",
                "deferred",
                "abandoned"
              ]
            },
            "reason": {
              "type": "string"
            }
          },
          "required": [
            "kind",
            "status"
          ],
          "additionalProperties": false
        }
      },
      "required": [
        "id",
        "workspaceId",
        "purpose",
        "status",
        "createdAt",
        "updatedAt",
        "progress"
      ],
      "additionalProperties": false
    }
  },
  "required": [
    "backup"
  ],
  "additionalProperties": false
}
Delivery
Standard response
Retry
Not declared idempotent
POST/v1/ws/{workspaceSlug}/backups/{backupId}/download

Mint a fresh short-lived private download URL for a ready backup.

Scope
ws:{workspaceSlug}:admin
Request
No request body
Response
Response JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "url": {
      "type": "string",
      "format": "uri"
    },
    "expiresAt": {
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    },
    "filename": {
      "type": "string"
    },
    "bytes": {
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    },
    "sha256": {
      "type": "string",
      "pattern": "^[a-f0-9]{64}$"
    }
  },
  "required": [
    "url",
    "expiresAt",
    "filename",
    "bytes",
    "sha256"
  ],
  "additionalProperties": false
}
Delivery
Standard response
Retry
Not declared idempotent
DELETE/v1/ws/{workspaceSlug}/backups/{backupId}

Cancel capture and delete its artifact; returns 202 while cleanup is pending.

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

Identity

29 operations
GET/v1/whoami

Inspect the authenticated user, workspace memberships, and granted scopes.

Scope
api_key
Request
No JSON request body
Response
Response JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "user": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string"
        },
        "email": {
          "type": "string",
          "format": "email",
          "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
        },
        "name": {
          "type": "string"
        }
      },
      "required": [
        "id",
        "email"
      ],
      "additionalProperties": false
    },
    "workspaces": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "slug": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "provisioning",
              "active",
              "unhealthy",
              "archived",
              "retired",
              "deleted"
            ]
          },
          "servicingStatus": {
            "type": "string",
            "enum": [
              "active",
              "paused",
              "banned"
            ]
          },
          "servicingStatusChangedAt": {
            "type": "integer",
            "exclusiveMinimum": 0,
            "maximum": 9007199254740991
          },
          "role": {
            "type": "string",
            "enum": [
              "owner",
              "editor",
              "viewer"
            ]
          },
          "billingUserId": {
            "type": "string"
          },
          "funding": {
            "type": "object",
            "properties": {
              "plan": {
                "anyOf": [
                  {
                    "type": "string",
                    "enum": [
                      "starter",
                      "pro",
                      "max"
                    ]
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "active": {
                "type": "boolean"
              },
              "trialEndsAt": {
                "type": "integer",
                "exclusiveMinimum": 0,
                "maximum": 9007199254740991
              }
            },
            "required": [
              "plan",
              "active"
            ],
            "additionalProperties": false
          },
          "creditRecovery": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "subscribe",
                  "topup"
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "defaultTier": {
            "type": "object",
            "properties": {
              "configured": {
                "type": "string",
                "enum": [
                  "frontier",
                  "balanced",
                  "openai-frontier",
                  "openai-max",
                  "anthropic-frontier",
                  "anthropic-max"
                ]
              },
              "effective": {
                "type": "string",
                "enum": [
                  "frontier",
                  "balanced",
                  "openai-frontier",
                  "openai-max",
                  "anthropic-frontier",
                  "anthropic-max"
                ]
              }
            },
            "required": [
              "effective"
            ],
            "additionalProperties": false
          },
          "duetName": {
            "type": "string",
            "minLength": 1,
            "maxLength": 32,
            "pattern": "^[^[\\]<>`\\p{Cc}]*$"
          },
          "purpose": {
            "type": "string",
            "minLength": 1,
            "maxLength": 1000
          },
          "onboardedAt": {
            "type": "integer",
            "exclusiveMinimum": 0,
            "maximum": 9007199254740991
          },
          "onboarding": {
            "type": "object",
            "properties": {
              "starterAgents": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            },
            "required": [
              "starterAgents"
            ],
            "additionalProperties": false
          },
          "adminMessage": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "slug",
          "name",
          "status",
          "servicingStatus",
          "role",
          "billingUserId",
          "funding",
          "creditRecovery",
          "defaultTier"
        ],
        "additionalProperties": false
      }
    },
    "scopes": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "versions": {
      "type": "object",
      "properties": {
        "api": {
          "type": "number",
          "const": 1
        }
      },
      "required": [
        "api"
      ],
      "additionalProperties": false
    },
    "internalAdmin": {
      "type": "boolean"
    },
    "credential": {
      "type": "object",
      "properties": {
        "kind": {
          "type": "string",
          "enum": [
            "user",
            "system_vm",
            "app",
            "impersonation",
            "browser_session",
            "oauth"
          ]
        },
        "audience": {
          "type": "string",
          "format": "uri"
        }
      },
      "required": [
        "kind"
      ],
      "additionalProperties": false
    }
  },
  "required": [
    "user",
    "workspaces",
    "scopes",
    "versions",
    "internalAdmin"
  ],
  "additionalProperties": false
}
Delivery
Standard response
Retry
Not declared idempotent
POST/v1/workspaces

Create a workspace and begin asynchronous provisioning.

Scope
api_key
Request
Request JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "slug": {
      "type": "string"
    },
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 200
    }
  },
  "required": [
    "slug",
    "name"
  ]
}
Response
Response JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "workspaceId": {
      "type": "string"
    },
    "slug": {
      "type": "string"
    },
    "status": {
      "type": "string",
      "const": "provisioning"
    }
  },
  "required": [
    "workspaceId",
    "slug",
    "status"
  ],
  "additionalProperties": false
}
Delivery
Standard response
Retry
Not declared idempotent
POST/v1/ws/{workspaceSlug}/reprovision

Replace an owner-managed workspace runtime after an explicit recovery request.

Scope
ws:{workspaceSlug}:admin
Request
No request body
Response
Response JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "oneOf": [
    {
      "type": "object",
      "properties": {
        "status": {
          "type": "string",
          "const": "backup_pending"
        },
        "workspaceId": {
          "type": "string"
        },
        "backupId": {
          "type": "string"
        }
      },
      "required": [
        "status",
        "workspaceId",
        "backupId"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "properties": {
        "status": {
          "type": "string",
          "const": "provisioning"
        },
        "workspaceId": {
          "type": "string"
        },
        "scheduled": {
          "type": "boolean"
        },
        "oldVmName": {
          "type": "string"
        },
        "imageRef": {
          "type": "string"
        }
      },
      "required": [
        "status",
        "workspaceId",
        "scheduled"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "properties": {
        "status": {
          "type": "string",
          "const": "deferred"
        },
        "reason": {
          "type": "string",
          "const": "active_workspace_work"
        },
        "activeAgentSessions": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991
        },
        "activeTrainJobs": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991
        }
      },
      "required": [
        "status",
        "reason",
        "activeAgentSessions",
        "activeTrainJobs"
      ],
      "additionalProperties": false
    }
  ]
}
Delivery
Standard response
Retry
Not declared idempotent
PATCH/v1/workspaces/{workspaceSlug}

Rename a workspace after acknowledging that its public addresses will break.

Scope
ws:{workspaceSlug}:admin
Request
Request JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "slug": {
      "type": "string"
    },
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 200
    },
    "publicUrlBreakAcknowledged": {
      "type": "boolean",
      "const": true
    }
  },
  "required": [
    "slug",
    "publicUrlBreakAcknowledged"
  ]
}
Response
Response JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "ok": {
      "type": "boolean",
      "const": true
    },
    "breaksPublicUrls": {
      "type": "boolean",
      "const": true
    }
  },
  "required": [
    "ok",
    "breaksPublicUrls"
  ],
  "additionalProperties": false
}
Delivery
Standard response
Retry
Not declared idempotent
PUT/v1/ws/{workspaceSlug}/admin/suspension

Suspend or resume an owner-managed workspace.

Scope
ws:{workspaceSlug}:admin
Request
Request JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "suspended": {
      "type": "boolean"
    },
    "reason": {
      "type": "string"
    }
  },
  "required": [
    "suspended"
  ]
}
Response
Response JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "oneOf": [
    {
      "type": "object",
      "properties": {
        "suspended": {
          "type": "boolean",
          "const": true
        },
        "suspendedAt": {
          "type": "number"
        },
        "suspensionReason": {
          "type": "string"
        }
      },
      "required": [
        "suspended",
        "suspendedAt"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "properties": {
        "suspended": {
          "type": "boolean",
          "const": false
        }
      },
      "required": [
        "suspended"
      ],
      "additionalProperties": false
    }
  ]
}
Delivery
Standard response
Retry
Not declared idempotent
GET/v1/ws/{workspaceSlug}/admin/suspension

Read whether the workspace is suspended, since when, and why.

Scope
ws:{workspaceSlug}:admin
Request
No JSON request body
Response
Response JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "oneOf": [
    {
      "type": "object",
      "properties": {
        "suspended": {
          "type": "boolean",
          "const": true
        },
        "suspendedAt": {
          "type": "number"
        },
        "suspensionReason": {
          "type": "string"
        }
      },
      "required": [
        "suspended",
        "suspendedAt"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "properties": {
        "suspended": {
          "type": "boolean",
          "const": false
        }
      },
      "required": [
        "suspended"
      ],
      "additionalProperties": false
    }
  ]
}
Delivery
Standard response
Retry
Not declared idempotent
GET/v1/ws/{workspaceSlug}/anchors

List path anchors and their current health.

Scope
ws:{workspaceSlug}:files:read
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": {
          "id": {
            "type": "string"
          },
          "workspaceId": {
            "type": "string"
          },
          "path": {
            "type": "string"
          },
          "kind": {
            "type": "string",
            "enum": [
              "app",
              "agent",
              "publish",
              "share-root",
              "share-mount"
            ]
          },
          "settings": {},
          "state": {
            "type": "string",
            "enum": [
              "active",
              "broken",
              "orphaned"
            ]
          },
          "createdAt": {
            "type": "number"
          },
          "updatedAt": {
            "type": "number"
          }
        },
        "required": [
          "id",
          "workspaceId",
          "path",
          "kind",
          "settings",
          "state",
          "createdAt",
          "updatedAt"
        ],
        "additionalProperties": false
      }
    },
    "nextCursor": {
      "anyOf": [
        {
          "type": "string",
          "minLength": 1
        },
        {
          "type": "null"
        }
      ]
    }
  },
  "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
POST/v1/ws/{workspaceSlug}/anchors/{anchorId}/reanchor

Repair a broken anchor after its workspace path moves.

Scope
ws:{workspaceSlug}:apps or ws:{workspaceSlug}:publish or ws:{workspaceSlug}:share
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": {
    "anchor": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string"
        },
        "workspaceId": {
          "type": "string"
        },
        "path": {
          "type": "string"
        },
        "kind": {
          "type": "string",
          "enum": [
            "app",
            "agent",
            "publish",
            "share-root",
            "share-mount"
          ]
        },
        "settings": {},
        "state": {
          "type": "string",
          "enum": [
            "active",
            "broken",
            "orphaned"
          ]
        },
        "createdAt": {
          "type": "number"
        },
        "updatedAt": {
          "type": "number"
        }
      },
      "required": [
        "id",
        "workspaceId",
        "path",
        "kind",
        "settings",
        "state",
        "createdAt",
        "updatedAt"
      ],
      "additionalProperties": false
    }
  },
  "required": [
    "anchor"
  ],
  "additionalProperties": false
}
Delivery
Standard response
Retry
Not declared idempotent
GET/v1/ws/{workspaceSlug}/members

List current workspace members and the designated payer.

Scope
ws:{workspaceSlug}:sessions or ws:{workspaceSlug}:files:read
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
    },
    "search": {
      "type": "string",
      "minLength": 1,
      "maxLength": 32
    }
  },
  "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"
          },
          "email": {
            "type": "string",
            "format": "email",
            "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
          },
          "name": {
            "type": "string"
          },
          "role": {
            "type": "string",
            "enum": [
              "owner",
              "editor",
              "viewer"
            ]
          },
          "isBillingUser": {
            "type": "boolean"
          }
        },
        "required": [
          "id",
          "email",
          "role",
          "isBillingUser"
        ],
        "additionalProperties": false
      }
    },
    "nextCursor": {
      "anyOf": [
        {
          "type": "string",
          "minLength": 1
        },
        {
          "type": "null"
        }
      ]
    }
  },
  "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
PATCH/v1/ws/{workspaceSlug}/members/{userId}

Change a member role while preserving payer and final-owner invariants.

Scope
ws:{workspaceSlug}:admin
Request
Request JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "role": {
      "type": "string",
      "enum": [
        "owner",
        "editor",
        "viewer"
      ]
    }
  },
  "required": [
    "role"
  ]
}
Response
Response JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "member": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string"
        },
        "email": {
          "type": "string",
          "format": "email",
          "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
        },
        "name": {
          "type": "string"
        },
        "role": {
          "type": "string",
          "enum": [
            "owner",
            "editor",
            "viewer"
          ]
        },
        "isBillingUser": {
          "type": "boolean"
        }
      },
      "required": [
        "id",
        "email",
        "role",
        "isBillingUser"
      ],
      "additionalProperties": false
    }
  },
  "required": [
    "member"
  ],
  "additionalProperties": false
}
Delivery
Standard response
Retry
Not declared idempotent
DELETE/v1/ws/{workspaceSlug}/members/{userId}

Remove a member after payer and final-owner checks pass.

Scope
ws:{workspaceSlug}:admin
Request
No JSON request body
Response
Response JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "removed": {
      "type": "boolean"
    }
  },
  "required": [
    "removed"
  ],
  "additionalProperties": false
}
Delivery
Standard response
Retry
Not declared idempotent
PUT/v1/ws/{workspaceSlug}/default-model

Set the workspace model role used when a session has no sticky choice.

Scope
ws:{workspaceSlug}:admin
Request
Request JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "tier": {
      "type": "string",
      "enum": [
        "frontier",
        "balanced",
        "openai-frontier",
        "openai-max",
        "anthropic-frontier",
        "anthropic-max"
      ]
    }
  },
  "required": [
    "tier"
  ]
}
Response
Response JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "tier": {
      "type": "string",
      "enum": [
        "frontier",
        "balanced",
        "openai-frontier",
        "openai-max",
        "anthropic-frontier",
        "anthropic-max"
      ]
    }
  },
  "required": [
    "tier"
  ],
  "additionalProperties": false
}
Delivery
Standard response
Retry
Not declared idempotent
GET/v1/ws/{workspaceSlug}/audit

Page through newest-first workspace audit events.

Scope
ws:{workspaceSlug}:files:read
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": {
          "id": {
            "type": "string"
          },
          "event": {
            "type": "string"
          },
          "actorId": {
            "type": "string"
          },
          "at": {
            "type": "integer",
            "exclusiveMinimum": 0,
            "maximum": 9007199254740991
          },
          "provenance": {
            "type": "object",
            "properties": {
              "action": {
                "type": "string"
              },
              "activeAgentSessions": {
                "type": "number"
              },
              "activeTrainJobs": {
                "type": "number"
              },
              "actor": {
                "type": "string"
              },
              "acknowledged": {
                "type": "boolean"
              },
              "agentVersion": {
                "type": "string"
              },
              "anchorId": {
                "type": "string"
              },
              "appId": {
                "type": "string"
              },
              "appSlug": {
                "type": "string"
              },
              "agentId": {
                "type": "string"
              },
              "archiveStorageId": {
                "type": "string"
              },
              "lifecycleBackupId": {
                "type": "string"
              },
              "breaksPublicUrls": {
                "type": "boolean"
              },
              "canonicalEmail": {
                "type": "string"
              },
              "candidates": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "fromPath": {
                      "type": "string"
                    },
                    "toPath": {
                      "type": "string"
                    },
                    "confidence": {
                      "type": "number"
                    },
                    "inodeMatch": {
                      "type": "boolean"
                    },
                    "markerMatch": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "fromPath",
                    "toPath",
                    "confidence",
                    "inodeMatch",
                    "markerMatch"
                  ],
                  "additionalProperties": false
                }
              },
              "conflictingAnchorId": {
                "type": "string"
              },
              "conflictingPath": {
                "type": "string"
              },
              "confidence": {
                "type": "number"
              },
              "consecutiveMissingPolls": {
                "type": "number"
              },
              "deleted": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "deviceCode": {
                "type": "string"
              },
              "deviceId": {
                "type": "string"
              },
              "deviceName": {
                "type": "string"
              },
              "defaultModelId": {
                "type": "string"
              },
              "tier": {
                "type": "string",
                "enum": [
                  "frontier",
                  "balanced",
                  "openai-frontier",
                  "openai-max",
                  "anthropic-frontier",
                  "anthropic-max",
                  "economy"
                ]
              },
              "expiresAt": {
                "type": "number"
              },
              "fromPath": {
                "type": "string"
              },
              "fromWorkspaceId": {
                "type": "string"
              },
              "runtimeVersion": {
                "type": "string"
              },
              "gatewayVersion": {
                "type": "string"
              },
              "generation": {
                "type": "string"
              },
              "imageRef": {
                "type": "string"
              },
              "imageVersion": {
                "type": "string"
              },
              "inodeMatch": {
                "type": "boolean"
              },
              "installMode": {
                "type": "string",
                "enum": [
                  "subscribe",
                  "clone_once"
                ]
              },
              "kind": {
                "type": "string",
                "enum": [
                  "app",
                  "agent",
                  "publish",
                  "share-root",
                  "share-mount",
                  "file",
                  "folder"
                ]
              },
              "lastHeartbeatAt": {
                "type": "number"
              },
              "listingId": {
                "type": "string"
              },
              "listingSlug": {
                "type": "string"
              },
              "markerMatch": {
                "type": "boolean"
              },
              "memberUserId": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "newBillingUserId": {
                "type": "string"
              },
              "mode": {
                "type": "string",
                "enum": [
                  "read",
                  "write"
                ]
              },
              "mountPath": {
                "type": "string"
              },
              "newSlug": {
                "type": "string"
              },
              "previousStatus": {
                "type": "string"
              },
              "oldPrefixes": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "oldBillingUserId": {
                "type": "string"
              },
              "oldSlug": {
                "type": "string"
              },
              "parentShareId": {
                "type": "string"
              },
              "path": {
                "type": "string"
              },
              "prefix": {
                "type": "string"
              },
              "prefixes": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "previousVmName": {
                "type": "string"
              },
              "publishId": {
                "type": "string"
              },
              "reason": {
                "type": "string"
              },
              "revokedShareIds": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "role": {
                "type": "string",
                "enum": [
                  "owner",
                  "editor",
                  "viewer"
                ]
              },
              "oldRole": {
                "type": "string",
                "enum": [
                  "owner",
                  "editor",
                  "viewer"
                ]
              },
              "scopes": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "sessionId": {
                "type": "string"
              },
              "shareId": {
                "type": "string"
              },
              "slug": {
                "type": "string"
              },
              "source": {
                "type": "string"
              },
              "subscriptionId": {
                "type": "string"
              },
              "targetEmail": {
                "type": "string"
              },
              "toPath": {
                "type": "string"
              },
              "toWorkspaceId": {
                "type": "string"
              },
              "userCode": {
                "type": "string"
              },
              "visibility": {
                "type": "string",
                "enum": [
                  "folder",
                  "public"
                ]
              },
              "vmName": {
                "type": "string"
              }
            },
            "additionalProperties": false
          }
        },
        "required": [
          "id",
          "event",
          "actorId",
          "at"
        ],
        "additionalProperties": false
      }
    },
    "nextCursor": {
      "anyOf": [
        {
          "type": "string",
          "minLength": 1
        },
        {
          "type": "null"
        }
      ]
    }
  },
  "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}/telemetry

Read the workspace VM CPU, memory, and disk telemetry history.

Scope
workspace_member
Request
No JSON request body
Query
Query parameters JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "sinceAt": {
      "type": "number",
      "minimum": 0
    }
  }
}
Response
Response JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "samples": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "at": {
            "type": "number",
            "minimum": 0
          },
          "cpuPct": {
            "type": "number",
            "minimum": 0,
            "maximum": 100
          },
          "memUsedMb": {
            "type": "number",
            "minimum": 0
          },
          "memTotalMb": {
            "type": "number",
            "minimum": 0
          },
          "diskUsedMb": {
            "type": "number",
            "minimum": 0
          },
          "diskTotalMb": {
            "type": "number",
            "minimum": 0
          }
        },
        "required": [
          "at"
        ],
        "additionalProperties": false
      }
    }
  },
  "required": [
    "samples"
  ],
  "additionalProperties": false
}
Delivery
Standard response
Retry
Not declared idempotent
GET/v1/user/profile

Read the signed-in user profile.

Scope
human
Request
No JSON request body
Response
Response JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "id": {
      "type": "string"
    },
    "email": {
      "type": "string",
      "format": "email",
      "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
    },
    "firstName": {
      "type": "string"
    },
    "lastName": {
      "type": "string"
    },
    "name": {
      "type": "string"
    }
  },
  "required": [
    "id",
    "email"
  ],
  "additionalProperties": false
}
Delivery
Standard response
Retry
Not declared idempotent
PATCH/v1/user/profile

Update the signed-in user profile.

Scope
human
Request
Request JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "firstName": {
      "type": "string",
      "maxLength": 100
    },
    "lastName": {
      "type": "string",
      "maxLength": 100
    }
  }
}
Response
Response JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "id": {
      "type": "string"
    },
    "email": {
      "type": "string",
      "format": "email",
      "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
    },
    "firstName": {
      "type": "string"
    },
    "lastName": {
      "type": "string"
    },
    "name": {
      "type": "string"
    }
  },
  "required": [
    "id",
    "email"
  ],
  "additionalProperties": false
}
Delivery
Standard response
Retry
Not declared idempotent
GET/v1/user/api-keys

List ordinary API keys without returning their secrets.

Scope
human
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": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "prefix": {
            "type": "string"
          },
          "createdAt": {
            "type": "number",
            "exclusiveMinimum": 0
          },
          "expiresAt": {
            "type": "number",
            "exclusiveMinimum": 0
          },
          "lastUsedAt": {
            "type": "number",
            "exclusiveMinimum": 0
          },
          "revokedAt": {
            "type": "number",
            "exclusiveMinimum": 0
          }
        },
        "required": [
          "id",
          "prefix",
          "createdAt"
        ],
        "additionalProperties": false
      }
    },
    "nextCursor": {
      "anyOf": [
        {
          "type": "string",
          "minLength": 1
        },
        {
          "type": "null"
        }
      ]
    }
  },
  "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
POST/v1/user/api-keys

Issue a human identity key and reveal its secret once.

Scope
human
Request
Request JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1
    },
    "expiresAt": {
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 9007199254740991
    }
  },
  "required": [
    "name"
  ],
  "additionalProperties": false
}
Response
Response JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "key": {
      "type": "string"
    },
    "record": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string"
        },
        "name": {
          "type": "string"
        },
        "prefix": {
          "type": "string"
        },
        "createdAt": {
          "type": "number",
          "exclusiveMinimum": 0
        },
        "expiresAt": {
          "type": "number",
          "exclusiveMinimum": 0
        },
        "lastUsedAt": {
          "type": "number",
          "exclusiveMinimum": 0
        },
        "revokedAt": {
          "type": "number",
          "exclusiveMinimum": 0
        }
      },
      "required": [
        "id",
        "prefix",
        "createdAt"
      ],
      "additionalProperties": false
    }
  },
  "required": [
    "key",
    "record"
  ],
  "additionalProperties": false
}
Delivery
Standard response
Retry
Not declared idempotent
DELETE/v1/user/api-keys/{keyId}

Revoke one ordinary API key owned by the signed-in user.

Scope
human
Request
No JSON request body
Response
Response JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "prefix": {
      "type": "string"
    },
    "revokedAt": {
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 9007199254740991
    }
  },
  "required": [
    "prefix",
    "revokedAt"
  ],
  "additionalProperties": false
}
Delivery
Standard response
Retry
Declared idempotent
GET/v1/user/oauth-grants

List OAuth grants owned by the signed-in user without credential material.

Scope
human
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": {
          "id": {
            "type": "string"
          },
          "clientId": {
            "type": "string",
            "minLength": 1
          },
          "clientName": {
            "type": "string"
          },
          "redirectHost": {
            "type": "string",
            "minLength": 1
          },
          "workspace": {
            "type": "object",
            "properties": {
              "slug": {
                "type": "string"
              },
              "name": {
                "type": "string"
              }
            },
            "required": [
              "slug",
              "name"
            ],
            "additionalProperties": false
          },
          "scopes": {
            "minItems": 1,
            "maxItems": 64,
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128
            }
          },
          "createdAt": {
            "type": "number",
            "exclusiveMinimum": 0
          },
          "lastUsedAt": {
            "type": "number",
            "exclusiveMinimum": 0
          },
          "revokedAt": {
            "type": "number",
            "exclusiveMinimum": 0
          }
        },
        "required": [
          "id",
          "clientId",
          "clientName",
          "redirectHost",
          "workspace",
          "scopes",
          "createdAt"
        ],
        "additionalProperties": false
      }
    },
    "nextCursor": {
      "anyOf": [
        {
          "type": "string",
          "minLength": 1
        },
        {
          "type": "null"
        }
      ]
    }
  },
  "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
DELETE/v1/user/oauth-grants/{grantId}

Revoke one OAuth grant family owned by the signed-in user.

Scope
human
Request
No JSON request body
Response
Response JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "grantId": {
      "type": "string"
    },
    "revokedAt": {
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 9007199254740991
    }
  },
  "required": [
    "grantId",
    "revokedAt"
  ],
  "additionalProperties": false
}
Delivery
Standard response
Retry
Declared idempotent
POST/v1/user/sync-machines

Register a non-secret sync machine for the signed-in user.

Scope
human
Request
Request JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1
    },
    "syncthingDeviceId": {
      "type": "string",
      "pattern": "^[A-Z2-7]{7}(-[A-Z2-7]{7})*$"
    }
  },
  "required": [
    "name",
    "syncthingDeviceId"
  ],
  "additionalProperties": false
}
Response
Response JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "machineId": {
      "type": "string",
      "minLength": 1
    },
    "name": {
      "type": "string"
    },
    "syncthingDeviceId": {
      "type": "string",
      "pattern": "^[A-Z2-7]{7}(-[A-Z2-7]{7})*$"
    },
    "createdAt": {
      "type": "number",
      "exclusiveMinimum": 0
    },
    "lastUsedAt": {
      "type": "number",
      "exclusiveMinimum": 0
    },
    "removedAt": {
      "type": "number",
      "exclusiveMinimum": 0
    }
  },
  "required": [
    "machineId",
    "name",
    "syncthingDeviceId",
    "createdAt",
    "lastUsedAt"
  ],
  "additionalProperties": false
}
Delivery
Standard response
Retry
Declared idempotent
GET/v1/user/sync-machines

List the signed-in user’s sync machines with creation and last use.

Scope
human
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": {
          "machineId": {
            "type": "string",
            "minLength": 1
          },
          "name": {
            "type": "string"
          },
          "syncthingDeviceId": {
            "type": "string",
            "pattern": "^[A-Z2-7]{7}(-[A-Z2-7]{7})*$"
          },
          "createdAt": {
            "type": "number",
            "exclusiveMinimum": 0
          },
          "lastUsedAt": {
            "type": "number",
            "exclusiveMinimum": 0
          },
          "removedAt": {
            "type": "number",
            "exclusiveMinimum": 0
          }
        },
        "required": [
          "machineId",
          "name",
          "syncthingDeviceId",
          "createdAt",
          "lastUsedAt"
        ],
        "additionalProperties": false
      }
    },
    "nextCursor": {
      "anyOf": [
        {
          "type": "string",
          "minLength": 1
        },
        {
          "type": "null"
        }
      ]
    }
  },
  "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
DELETE/v1/user/sync-machines/{machineId}

Remove one sync machine and detach its workspace mirrors.

Scope
human
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
    },
    "machineId": {
      "type": "string",
      "minLength": 1
    },
    "removedAt": {
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 9007199254740991
    }
  },
  "required": [
    "ok",
    "machineId",
    "removedAt"
  ],
  "additionalProperties": false
}
Delivery
Standard response
Retry
Declared idempotent
GET/v1/user/invitations

List pending workspace invitations addressed to the signed-in user.

Scope
human
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": {
          "id": {
            "type": "string"
          },
          "workspace": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "slug": {
                "type": "string"
              }
            },
            "required": [
              "id",
              "name",
              "slug"
            ],
            "additionalProperties": false
          },
          "inviter": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "email": {
                    "type": "string",
                    "format": "email",
                    "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                  }
                },
                "required": [
                  "email"
                ],
                "additionalProperties": false
              },
              {
                "type": "null"
              }
            ]
          },
          "role": {
            "type": "string",
            "enum": [
              "editor",
              "viewer"
            ]
          },
          "expiresAt": {
            "type": "integer",
            "exclusiveMinimum": 0,
            "maximum": 9007199254740991
          }
        },
        "required": [
          "id",
          "workspace",
          "inviter",
          "role",
          "expiresAt"
        ],
        "additionalProperties": false
      }
    },
    "nextCursor": {
      "anyOf": [
        {
          "type": "string",
          "minLength": 1
        },
        {
          "type": "null"
        }
      ]
    }
  },
  "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
POST/v1/user/invitations/{inviteId}/accept

Accept an invitation addressed to the signed-in user and return its workspace.

Scope
human
Request
No request body
Response
Response JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "workspaceId": {
      "type": "string"
    },
    "workspaceSlug": {
      "type": "string"
    }
  },
  "required": [
    "workspaceId",
    "workspaceSlug"
  ],
  "additionalProperties": false
}
Delivery
Standard response
Retry
Declared idempotent
POST/v1/ws/{workspaceSlug}/invites

Invite an editor or viewer by canonical email address.

Scope
ws:{workspaceSlug}:members
Request
Request JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "email": {
      "type": "string",
      "format": "email",
      "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
    },
    "role": {
      "description": "Defaults to editor.",
      "type": "string",
      "enum": [
        "editor",
        "viewer"
      ]
    }
  },
  "required": [
    "email"
  ]
}
Response
Response JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "id": {
      "type": "string"
    },
    "email": {
      "type": "string",
      "format": "email",
      "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
    },
    "role": {
      "type": "string",
      "enum": [
        "editor",
        "viewer"
      ]
    },
    "expiresAt": {
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 9007199254740991
    },
    "revokedAt": {
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 9007199254740991
    },
    "consumedAt": {
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 9007199254740991
    }
  },
  "required": [
    "id",
    "email",
    "role",
    "expiresAt"
  ],
  "additionalProperties": false
}
Delivery
Standard response
Retry
Not declared idempotent
GET/v1/ws/{workspaceSlug}/invites

List recent invitations for a workspace.

Scope
ws:{workspaceSlug}:members
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": {
          "id": {
            "type": "string"
          },
          "email": {
            "type": "string",
            "format": "email",
            "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
          },
          "role": {
            "type": "string",
            "enum": [
              "editor",
              "viewer"
            ]
          },
          "expiresAt": {
            "type": "integer",
            "exclusiveMinimum": 0,
            "maximum": 9007199254740991
          },
          "revokedAt": {
            "type": "integer",
            "exclusiveMinimum": 0,
            "maximum": 9007199254740991
          },
          "consumedAt": {
            "type": "integer",
            "exclusiveMinimum": 0,
            "maximum": 9007199254740991
          }
        },
        "required": [
          "id",
          "email",
          "role",
          "expiresAt"
        ],
        "additionalProperties": false
      }
    },
    "nextCursor": {
      "anyOf": [
        {
          "type": "string",
          "minLength": 1
        },
        {
          "type": "null"
        }
      ]
    }
  },
  "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
DELETE/v1/ws/{workspaceSlug}/invites/{inviteId}

Revoke an invitation before it is consumed.

Scope
ws:{workspaceSlug}:members
Request
No JSON request body
Response
Response JSON schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "revokedAt": {
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 9007199254740991
    }
  },
  "required": [
    "revokedAt"
  ],
  "additionalProperties": false
}
Delivery
Standard response
Retry
Declared idempotent