Skip to content
LogoLogo

Workspaces

Workspace lifecycle, membership, and invitations.

List access-filtered Workspace activity

GET/api/v1/workspaces/{workspace_id}/activity

Returns a newest-first, cursor-bounded page of meaningful work changes. Activity is projected from immutable domain events at read time using the caller's current access. Only registered activity types appear: progress, ownership, deadline, priority, milestone, description, blocking-dependency, comment, document, Project and Milestone changes. Personal preferences (following or muting), ordinary reactions, ordinary title corrections, configuration, security, session, identity, membership, integration, and Agent execution events never appear here; an ordinary edit remains available in that item's own history. action is a stable localization key, not a rendered sentence, and summary never includes comment, Document, or other free-form content. Events from one command or one editing session collapse into a single item: count says how many events it represents and affected lists up to 25 of the resources a bulk change touched. Private Project resources are filtered before pagination and grouping, so items, cursors, has_more, and affected cannot disclose inaccessible work. limit bounds the events examined, so a page may hold fewer items than limit; only has_more says whether history continues. provenance distinguishes mediated actions while preserving the stable Actor; a group carries the least direct classification among its members. Optional paired day and time_zone select one civil day's inclusive local midnight to exclusive next midnight, including DST changes. The indexed time range applies before pagination and counting; cursors are bound to that interval. Existing 90-day retention still applies.

Path Parameters

workspace_idRequired
string <uuid>
Example0198ac5e-f9b7-7000-8000-000000000001

Query Parameters

cursor
string·min 1·max 2048

Opaque continuation cursor returned by the preceding page.

limit
integer·min 1·max 100·default 50

Maximum number of resources to return.

day
string <date>

Civil date; requires time_zone. Invalid or unpaired inputs return 400 invalid_request.

time_zone
string

IANA timezone for day; requires day. Local is not accepted.

ExampleEurope/Budapest

Responses

Read shared Workspace defaults

GET/api/v1/workspaces/{workspace_id}/settings

Path Parameters

workspace_idRequired
string <uuid>
Example0198ac5e-f9b7-7000-8000-000000000001

Responses

Update shared Workspace defaults

PATCH/api/v1/workspaces/{workspace_id}/settings

Path Parameters

workspace_idRequired
string <uuid>
Example0198ac5e-f9b7-7000-8000-000000000001

Header Parameters

X-CSRF-TokenRequired
string·min 43·max 43

Session-bound CSRF token. It must exactly match the __Host-assign_csrf cookie sent with the request.

If-MatchRequired
string

Entity tag containing the resource version last observed by the client.

Request Body

application/json
description
string·max 500
default_timezone
string·max 64
default_locale
string·max 35
default_first_day_of_week
string
Values
sundaymonday
default_project_visibility
string
Values
workspaceprivate
default_task_status_category
string
Values
backlogtodoin_progress
default_task_priority
string
Values
nonelowmediumhighurgent
default_task_assignee
string
Values
unassignedcreator

Responses

Read Workspace Knowledge indexing settings and lifecycle state

GET/api/v1/workspaces/{workspace_id}/knowledge-settings

Path Parameters

workspace_idRequired
string <uuid>
Example0198ac5e-f9b7-7000-8000-000000000001

Responses

Update desired Workspace Knowledge indexing settings

PATCH/api/v1/workspaces/{workspace_id}/knowledge-settings

Path Parameters

workspace_idRequired
string <uuid>
Example0198ac5e-f9b7-7000-8000-000000000001

Header Parameters

X-CSRF-TokenRequired
string·min 43·max 43

Session-bound CSRF token. It must exactly match the __Host-assign_csrf cookie sent with the request.

If-MatchRequired
string

Entity tag containing the resource version last observed by the client.

Request Body

application/json
enabled
boolean

Saves an explicit enablement choice that survives billing changes. Enabling requires the active Knowledge entitlement and may precede Project selection.

index_task_descriptions
boolean
index_comments
boolean
index_attachments
boolean
index_external_urls
boolean
index_repositories
boolean
index_audio_video
boolean
session_learning
string
Values
offask
included_projects
string <uuid>[]·max 100

Responses

Associate a cropped S3-hosted Workspace icon

POST/api/v1/workspaces/{workspace_id}/icon

Path Parameters

workspace_idRequired
string <uuid>
Example0198ac5e-f9b7-7000-8000-000000000001

Header Parameters

X-CSRF-TokenRequired
string·min 43·max 43

Session-bound CSRF token. It must exactly match the __Host-assign_csrf cookie sent with the request.

If-MatchRequired
string

Entity tag containing the resource version last observed by the client.

Request Body

application/json
attachment_idRequired
string <uuid>

Opaque Assign-owned UUIDv7 identifier. Clients must not derive meaning from it.

Example0198ac5e-f9b7-7000-8000-000000000001

Responses

Remove the Workspace icon and retire its stored object

DELETE/api/v1/workspaces/{workspace_id}/icon

Path Parameters

workspace_idRequired
string <uuid>
Example0198ac5e-f9b7-7000-8000-000000000001

Header Parameters

X-CSRF-TokenRequired
string·min 43·max 43

Session-bound CSRF token. It must exactly match the __Host-assign_csrf cookie sent with the request.

If-MatchRequired
string

Entity tag containing the resource version last observed by the client.

Responses

Redirect to a short-lived inline S3 URL for the Workspace icon

GET/api/v1/workspaces/{workspace_id}/icon/content

Path Parameters

workspace_idRequired
string <uuid>
Example0198ac5e-f9b7-7000-8000-000000000001

Responses

200Image bytes after a client follows the redirect.
302Short-lived object-storage redirect.

Create the native caller's first Workspace

POST/api/v1/mobile/workspaces/bootstrap

Runs the same first-Workspace creation service and serialized account membership check as browser bootstrap. Existing memberships cause 409. Returns the Workspace without creating, switching or setting browser cookies. The native app selects the returned Workspace explicitly. No additional paid-plan or general Workspace-creation operation is admitted.

Request Body

application/json
nameRequired
string·min 1·max 100

Trimmed before validation.

slugRequired
string·min 1·max 63

The unique canonical Workspace URL segment.

Responses

Get the Workspace AI access policy

GET/api/v1/workspaces/{workspace_id}/ai-access-policy

Returns the revisioned policy checked on every MCP authorization and Workspace tool request. An absent stored row defaults to enabled at revision zero.

Path Parameters

workspace_idRequired
string <uuid>
Example0198ac5e-f9b7-7000-8000-000000000001

Responses

Update the Workspace AI access policy

PUT/api/v1/workspaces/{workspace_id}/ai-access-policy

Enables or disables external AI access for the current Workspace. Disabling takes effect for existing MCP grants on their next request without revoking those grants in another Workspace.

Path Parameters

workspace_idRequired
string <uuid>
Example0198ac5e-f9b7-7000-8000-000000000001

Header Parameters

X-CSRF-TokenRequired
string·min 43·max 43

Session-bound CSRF token. It must exactly match the __Host-assign_csrf cookie sent with the request.

If-MatchRequired
string

Entity tag containing the last policy revision; "0" creates the first persisted policy.

Request Body

application/json
enabledRequired
boolean

Responses

List Workspace MCP service credentials

GET/api/v1/workspaces/{workspace_id}/mcp-service-credentials

Lists at most 100 active, unexpired named service credentials. Raw credential values are never returned.

Path Parameters

workspace_idRequired
string <uuid>
Example0198ac5e-f9b7-7000-8000-000000000001

Responses

Create a Workspace MCP service credential

POST/api/v1/workspaces/{workspace_id}/mcp-service-credentials

Creates a non-human service actor and a Workspace-bound MCP credential. The raw credential is returned exactly once. An empty project_ids array permits every currently visible Project in the Workspace; a non-empty array narrows the credential to those Projects.

Path Parameters

workspace_idRequired
string <uuid>
Example0198ac5e-f9b7-7000-8000-000000000001

Header Parameters

X-CSRF-TokenRequired
string·min 43·max 43

Session-bound CSRF token. It must exactly match the __Host-assign_csrf cookie sent with the request.

Request Body

application/json
nameRequired
string·min 1·max 100
scopesRequired
string[]·min 1·max 37
Values
assign:activity:readassign:agents:readassign:agents:writeassign:attachments:readassign:attachments:write
project_idsRequired
string <uuid>[]·max 100
expires_at
string <date-time>

Optional expiry no more than one year after creation; defaults to 90 days.

Responses

Revoke a Workspace MCP service credential

DELETE/api/v1/workspaces/{workspace_id}/mcp-service-credentials/{credential_id}

Immediately refuses the credential on every instance while retaining its service actor for audit history.

Path Parameters

workspace_idRequired
string <uuid>
Example0198ac5e-f9b7-7000-8000-000000000001
credential_idRequired
string <uuid>
Example0198ac5e-f9b7-7000-8000-000000000001

Header Parameters

X-CSRF-TokenRequired
string·min 43·max 43

Session-bound CSRF token. It must exactly match the __Host-assign_csrf cookie sent with the request.

Responses

Create the caller's first Workspace

POST/api/v1/workspaces/bootstrap

Creates the first Workspace, owner membership, and Actor for a signed-in account that has no active Workspace memberships. The caller selects both the visible name and canonical URL segment.

Success rotates the account-only session into the new Workspace and replaces both browser-session cookies. Concurrent requests are serialized so at most one first Workspace is created for an account. A caller that already has a Workspace receives 409 and must use the normal session-switch operation instead.

Header Parameters

X-CSRF-TokenRequired
string·min 43·max 43

Session-bound CSRF token. It must exactly match the __Host-assign_csrf cookie sent with the request.

Request Body

application/json
nameRequired
string·min 1·max 100

Trimmed before validation.

slugRequired
string·min 1·max 63

The unique canonical Workspace URL segment.

Responses

Get native account Workspace-creation options

GET/api/v1/mobile/workspace-creation-options

Requires a first-party native bearer; browser cookies are not accepted. Paid choices are informational until native paid-checkout admission is qualified. Returns the signed-in human account's Free Workspace claim state and currently purchasable paid choices. Membership and the selected Workspace role do not affect this account-level eligibility. The Paid choices are present only when the configured provider and every required immutable local catalog mapping are available.

Responses

Create a Free Workspace with a native account

POST/api/v1/mobile/workspaces

Requires a first-party native bearer; browser cookies are not accepted. Creation does not select a Workspace or issue browser cookies. Claims and creates the signed-in human account's one active Free Workspace, provisioning the Workspace, owner membership, Actor, default workflow, claim, and events in one transaction. Membership and role in the selected Workspace do not grant or deny this account-level command.

The optional slug selects the canonical URL segment. When omitted, Core generates a collision-safe value from the name.

Creation does not switch the calling session onto the new Workspace. Changing scope is PUT /api/v1/auth/session/workspace, which always rotates the session and CSRF secrets; doing it as a side effect here would rotate them invisibly.

Header Parameters

Idempotency-KeyRequired
string·min 16·max 200

Opaque client-generated key for safely retrying this operation.

Request Body

application/json
nameRequired
string·min 1·max 100

Trimmed before validation.

slug
string·min 1·max 63

Optional unique canonical Workspace URL segment.

Responses

Get account Workspace-creation options

GET/api/v1/workspace-creation-options

Returns the signed-in human account's Free Workspace claim state and currently purchasable paid choices. Membership and the selected Workspace role do not affect this account-level eligibility. The Paid choices are present only when the configured provider and every required immutable local catalog mapping are available.

Responses

Create a Workspace

POST/api/v1/workspaces

Claims and creates the signed-in human account's one active Free Workspace, provisioning the Workspace, owner membership, Actor, default workflow, claim, and events in one transaction. Membership and role in the selected Workspace do not grant or deny this account-level command.

The optional slug selects the canonical URL segment. When omitted, Core generates a collision-safe value from the name.

Creation does not switch the calling session onto the new Workspace. Changing scope is PUT /api/v1/auth/session/workspace, which always rotates the session and CSRF secrets; doing it as a side effect here would rotate them invisibly.

Header Parameters

X-CSRF-TokenRequired
string·min 43·max 43

Session-bound CSRF token. It must exactly match the __Host-assign_csrf cookie sent with the request.

Idempotency-KeyRequired
string·min 16·max 200

Opaque client-generated key for safely retrying this operation.

Request Body

application/json
nameRequired
string·min 1·max 100

Trimmed before validation.

slug
string·min 1·max 63

Optional unique canonical Workspace URL segment.

Responses

List Workspace-wide workflow Statuses

GET/api/v1/workspaces/{workspace_id}/statuses

Returns a cursor-bounded, workflow-ordered page of Statuses whose project_id is null and which therefore apply to every Project in the Workspace. Active members with work:read may read the catalog.

Path Parameters

workspace_idRequired
string <uuid>
Example0198ac5e-f9b7-7000-8000-000000000001

Query Parameters

cursor
string·min 1·max 2048

Opaque continuation cursor returned by the preceding page.

limit
integer·min 1·max 100·default 50

Maximum number of resources to return.

include_archived
boolean·default false

Include archived Statuses; omitted or false returns active Statuses only.

Responses

Create a Workspace-wide workflow Status

POST/api/v1/workspaces/{workspace_id}/statuses

Appends a Status that applies to every Project in the Workspace. This requires workspace:manage: unlike a Project-local Status, the new catalog entry changes how all Workspace work is categorized.

Path Parameters

workspace_idRequired
string <uuid>
Example0198ac5e-f9b7-7000-8000-000000000001

Header Parameters

X-CSRF-TokenRequired
string·min 43·max 43

Session-bound CSRF token. It must exactly match the __Host-assign_csrf cookie sent with the request.

Idempotency-KeyRequired
string·min 16·max 200

Opaque client-generated key for safely retrying this operation.

Request Body

application/json
labelRequired
string·min 1·max 100
categoryRequired
string
Values
backlogtodoin_progressin_reviewdone
status_type
string

Canonical lifecycle meaning. Custom labels remain presentation; completed and cancelled are terminal.

Values
backlogunstartedstartedcompletedcancelled
icon
string
color
string

Responses

List the typed lifecycle behavior registry

GET/api/v1/lifecycle-behaviors

Returns every behavior key a stage can enable, the entity kinds it applies to and the domain consumer that owns its effect. The list is static for a server version and safe to cache briefly.

Responses

Resolve the status that completes an entity of a kind

GET/api/v1/workspaces/{workspace_id}/lifecycle-completion-targets

Requires Workspace read access. Completion is never inferred from labels. With one completing status the response names it. With several and no target_status_id the response is 409 completion_target_required listing the choices, so the caller must name one. An explicit target that does not count as completed is 422 completion_target_invalid; a kind without any completing status is 422 completion_target_unavailable.

Path Parameters

workspace_idRequired
string <uuid>
Example0198ac5e-f9b7-7000-8000-000000000001

Query Parameters

kindRequired
string
Values
taskmilestoneproject
definition_id
string <uuid>
Example0198ac5e-f9b7-7000-8000-000000000001
target_status_id
string <uuid>
Example0198ac5e-f9b7-7000-8000-000000000001

Responses

List lifecycle definitions with stages, policies and statuses

GET/api/v1/workspaces/{workspace_id}/lifecycle-definitions

Requires work:read. Returns the Workspace's definitions (optionally one kind) with every stage's complete typed behaviors and bound statuses in presentation order, so selectors and settings render from one read. The catalog is bounded by the lifecycle limits (20 definitions per kind, 100 stages per definition, 500 statuses per definition), so it is not paged. Behaviors that do not apply to the kind are absent.

Path Parameters

workspace_idRequired
string <uuid>
Example0198ac5e-f9b7-7000-8000-000000000001

Query Parameters

kind
string
Values
taskmilestoneproject
include_archived
boolean·default false

Responses

Preview moving statuses of a lifecycle definition

POST/api/v1/workspaces/{workspace_id}/lifecycle-definitions/{definition_id}/mapping-previews

Requires Workspace management authority. Validates that every source status has exactly one same-kind, same-Workspace, active destination that is not itself retired, and returns bounded per-status impact counts (capped at 10,000, truncated when reached) and the behavior keys whose value would change. If-Match binds the definition revision; a mismatch is 409 revision_conflict. Nothing is written. Pass the returned destination_revisions and source_revision back to apply.

Path Parameters

workspace_idRequired
string <uuid>
Example0198ac5e-f9b7-7000-8000-000000000001
definition_idRequired
string <uuid>
Example0198ac5e-f9b7-7000-8000-000000000001

Header Parameters

X-CSRF-TokenRequired
string·min 43·max 43

Session-bound CSRF token. It must exactly match the __Host-assign_csrf cookie sent with the request.

If-MatchRequired
string

Entity tag containing the resource version last observed by the client.

Request Body

application/json
mappingsRequired
object

Source status ID to destination status ID. A source mapped to itself keeps its ID and entities. Sources are exactly the keys.

destination_revisions
object

Apply only. The destination_revisions returned by the preview.

acknowledged
boolean

Apply only. Required when the preview reports requires_acknowledgement.

Responses

Apply a previewed status mapping as a durable migration job

POST/api/v1/workspaces/{workspace_id}/lifecycle-definitions/{definition_id}/mapping-applications

Requires Workspace management authority and an Idempotency-Key; a repeat with the same key and mapping returns the original job and a different mapping is 409 idempotency_key_conflict. The request is re-validated against If-Match and destination_revisions (409 lifecycle_preview_stale or revision_conflict), and material behavior changes or a default replacement need acknowledged: true (409 lifecycle_acknowledgement_required). Scopes within the 1,000-entity synchronous limit are moved before the response (200, status completed, or 202 when a retry is pending); larger scopes return 202 and a background worker moves bounded pages. A Workspace has one applying job (409 lifecycle_migration_pending).

Path Parameters

workspace_idRequired
string <uuid>
Example0198ac5e-f9b7-7000-8000-000000000001
definition_idRequired
string <uuid>
Example0198ac5e-f9b7-7000-8000-000000000001

Header Parameters

X-CSRF-TokenRequired
string·min 43·max 43

Session-bound CSRF token. It must exactly match the __Host-assign_csrf cookie sent with the request.

Idempotency-KeyRequired
string·min 16·max 200

Opaque client-generated key for safely retrying this operation.

If-MatchRequired
string

Entity tag containing the resource version last observed by the client.

Request Body

application/json
mappingsRequired
object

Source status ID to destination status ID. A source mapped to itself keeps its ID and entities. Sources are exactly the keys.

destination_revisions
object

Apply only. The destination_revisions returned by the preview.

acknowledged
boolean

Apply only. Required when the preview reports requires_acknowledgement.

Responses

Read a lifecycle migration job

GET/api/v1/workspaces/{workspace_id}/lifecycle-migrations/{job_id}

Requires Workspace management authority. Returns pending, processing, retry, completed or failed state with progress and a safe error code.

Path Parameters

workspace_idRequired
string <uuid>
Example0198ac5e-f9b7-7000-8000-000000000001
job_idRequired
string <uuid>
Example0198ac5e-f9b7-7000-8000-000000000001

Responses

Resume a failed lifecycle migration job

POST/api/v1/workspaces/{workspace_id}/lifecycle-migrations/{job_id}/retry

Requires Workspace management authority. Makes a failed job runnable again, keeping pages already moved; any other state is 404 not_found.

Path Parameters

workspace_idRequired
string <uuid>
Example0198ac5e-f9b7-7000-8000-000000000001
job_idRequired
string <uuid>
Example0198ac5e-f9b7-7000-8000-000000000001

Header Parameters

X-CSRF-TokenRequired
string·min 43·max 43

Session-bound CSRF token. It must exactly match the __Host-assign_csrf cookie sent with the request.

Responses

Read configured Milestone stages

GET/api/v1/workspaces/{workspace_id}/milestone-lifecycle

Requires work:read. Returns at most 100 retained stages in presentation order. A Workspace without a saved catalog returns the four default stages at revision 1.

Path Parameters

workspace_idRequired
string <uuid>
Example0198ac5e-f9b7-7000-8000-000000000001

Responses

Configure Milestone stages

PUT/api/v1/workspaces/{workspace_id}/milestone-lifecycle

Requires workspace:manage. Atomically replaces the bounded catalog under If-Match. Every semantic category retains active coverage. Referenced IDs and categories cannot be removed or changed. Archiving an in-use stage requires a same-category active replacement; at most 1000 active Milestones are moved atomically. Archived Milestones retain historical selections. Conflicts include revision_conflict, milestone_stage_in_use and lifecycle_migration_too_large. Names are trimmed; no transition graph is introduced.

Path Parameters

workspace_idRequired
string <uuid>
Example0198ac5e-f9b7-7000-8000-000000000001

Header Parameters

X-CSRF-TokenRequired
string·min 43·max 43

Session-bound CSRF token. It must exactly match the __Host-assign_csrf cookie sent with the request.

Idempotency-KeyRequired
string·min 16·max 200

Opaque client-generated key for safely retrying this operation.

If-MatchRequired
string

Entity tag containing the resource version last observed by the client.

Request Body

application/json
stagesRequired
object[]·min 4·max 100

replacements
object

Source stage ID to same-category active replacement stage ID for atomic archival migration.

Responses

Restore a former member

POST/api/v1/workspaces/{workspace_id}/members

Reactivates the membership of somebody who was removed or who left. It takes a user_id an administrator has already seen in the member list, and it is not a path for net-new people.

There is deliberately no address input. An endpoint that resolved an arbitrary email to an account would answer, for any caller who can manage members, whether that address is registered with Assign. Net-new people join through invitations, which prove control of the mailbox instead.

Reactivating an already-active membership is idempotent.

Path Parameters

workspace_idRequired
string <uuid>
Example0198ac5e-f9b7-7000-8000-000000000001

Header Parameters

X-CSRF-TokenRequired
string·min 43·max 43

Session-bound CSRF token. It must exactly match the __Host-assign_csrf cookie sent with the request.

Idempotency-KeyRequired
string·min 16·max 200

Opaque client-generated key for safely retrying this operation.

Request Body

application/json
user_idRequired
string <uuid>

Opaque Assign-owned UUIDv7 identifier. Clients must not derive meaning from it.

Example0198ac5e-f9b7-7000-8000-000000000001

Responses

Read a Workspace

GET/api/v1/workspaces/{workspace_id}

Returns the Workspace the caller's session is scoped to. Any active member may read it.

An archived Workspace is visible only to an owner, so un-archiving stays discoverable; every other member sees the same not-found response an absent Workspace produces.

Path Parameters

workspace_idRequired
string <uuid>
Example0198ac5e-f9b7-7000-8000-000000000001

Responses

Rename, change the URL, or restore a Workspace

PATCH/api/v1/workspaces/{workspace_id}

Changes exactly one of name, slug, or archived. Renaming and URL changes require the workspace:manage capability; archived: false restores an archived Workspace and is the only mutation an archived Workspace accepts.

archived: true is rejected here — archiving is DELETE /api/v1/workspaces/{workspace_id}, which additionally requires an owner and recent authentication.

slug is the canonical Workspace URL segment. It must be unique and use lowercase letters, numbers, and interior hyphens only.

Path Parameters

workspace_idRequired
string <uuid>
Example0198ac5e-f9b7-7000-8000-000000000001

Header Parameters

X-CSRF-TokenRequired
string·min 43·max 43

Session-bound CSRF token. It must exactly match the __Host-assign_csrf cookie sent with the request.

If-MatchRequired
string

Entity tag containing the resource version last observed by the client.

Idempotency-KeyRequired
string·min 16·max 200

Opaque client-generated key for safely retrying this operation.

Request Body

application/json
name
string·min 1·max 100
slug
string·min 1·max 63

The unique canonical Workspace URL segment.

icon_url
string·max 2048

An HTTPS image URL. An empty string removes the icon.

archived
boolean

Only false is accepted, which unarchives the Workspace. Archiving is DELETE /api/v1/workspaces/{workspace_id}, which is owner-only and requires recent authentication.

Responses

Archive a Workspace

DELETE/api/v1/workspaces/{workspace_id}

Archives the Workspace. Requires an owner and authentication within the last 15 minutes, so a borrowed session cannot pull a Workspace out from under its members.

No data is deleted. Every session scoped to the Workspace is revoked in the same transaction, the Workspace disappears from the default Workspace list, and every Workspace-scoped route answers not-found — except an owner's read and the restoring PATCH. Archival is therefore a real access boundary, not a display flag, and it is reversible.

A caller's last active Workspace cannot be archived. Account-only sessions are reserved for first-Workspace onboarding, so an existing scoped account cannot return to that state by archiving its Workspace. That case answers 409 last_workspace.

Path Parameters

workspace_idRequired
string <uuid>
Example0198ac5e-f9b7-7000-8000-000000000001

Header Parameters

X-CSRF-TokenRequired
string·min 43·max 43

Session-bound CSRF token. It must exactly match the __Host-assign_csrf cookie sent with the request.

If-MatchRequired
string

Entity tag containing the resource version last observed by the client.

Idempotency-KeyRequired
string·min 16·max 200

Opaque client-generated key for safely retrying this operation.

Responses

204The Workspace is archived.

Change a member's role or state

PATCH/api/v1/workspaces/{workspace_id}/members/{member_id}

Changes role, state, or both. An omitted field keeps its current value. state moves between active and suspended; suspending a member revokes their sessions in this Workspace immediately. Promotion to owner is permitted.

Demoting, suspending, or otherwise removing the last active owner is refused 409 last_owner. A caller may not change their own membership: self-demotion and self-suspension have no legitimate use and both produce a lockout the caller cannot then undo, so they answer 422 self_membership_mutation.

Path Parameters

workspace_idRequired
string <uuid>
Example0198ac5e-f9b7-7000-8000-000000000001
member_idRequired
string <uuid>
Example0198ac5e-f9b7-7000-8000-000000000001

Header Parameters

X-CSRF-TokenRequired
string·min 43·max 43

Session-bound CSRF token. It must exactly match the __Host-assign_csrf cookie sent with the request.

If-MatchRequired
string

Entity tag containing the resource version last observed by the client.

Idempotency-KeyRequired
string·min 16·max 200

Opaque client-generated key for safely retrying this operation.

Request Body

application/json
role
string

viewer reads the Workspace and its work and writes nothing. admin holds the same capabilities as owner; the only owner-reserved operation is archiving the Workspace, and a Workspace must always retain at least one active owner.

Values
owneradminmemberviewer
state
string
Values
activesuspended

Responses

Remove a member

DELETE/api/v1/workspaces/{workspace_id}/members/{member_id}

Ends the membership. The row is retained in a removed state and the member's Actor is retained, so past Task assignments, comments, and events stay attributable to a real identity.

The member's sessions in this Workspace are revoked in the same transaction, so access ends immediately rather than at next expiry. Removing the last active owner is refused 409 last_owner, and a caller may not remove themselves. Repeat removal answers 204.

Path Parameters

workspace_idRequired
string <uuid>
Example0198ac5e-f9b7-7000-8000-000000000001
member_idRequired
string <uuid>
Example0198ac5e-f9b7-7000-8000-000000000001

Header Parameters

X-CSRF-TokenRequired
string·min 43·max 43

Session-bound CSRF token. It must exactly match the __Host-assign_csrf cookie sent with the request.

Idempotency-KeyRequired
string·min 16·max 200

Opaque client-generated key for safely retrying this operation.

Responses

204The membership is removed.

List invitations

GET/api/v1/workspaces/{workspace_id}/invitations

Returns one newest-first page of invitations in every state — pending, accepted, expired, and revoked. Neither the token nor its hash is ever returned; the token exists in exactly one response, the one that created it.

Path Parameters

workspace_idRequired
string <uuid>
Example0198ac5e-f9b7-7000-8000-000000000001

Query Parameters

cursor
string·min 1·max 2048

Opaque continuation cursor returned by the preceding page.

limit
integer·min 1·max 100·default 50

Maximum number of resources to return.

Responses

Invite someone to the Workspace

POST/api/v1/workspaces/{workspace_id}/invitations

Creates an invitation and returns the plain token once. Only a hash is stored, so the token cannot be recovered later and a database disclosure is not replayable into Workspace access. Repeating the request with the same Idempotency-Key replays the original response, token included, which is how a client that lost the first response recovers it.

role may be admin, member, or viewer — not owner. Ownership carries the archive power and the last-owner invariant, and is conferred by a deliberate membership change on somebody already present rather than by whoever opens a link in a mailbox.

A second unexpired pending invitation for the same address is refused 409 invitation_pending rather than silently reissued, so the link the recipient already received stays the live one. An address that already belongs to an active member is refused 409 already_member, which discloses nothing an administrator cannot read from the member list. If the configured email provider cannot accept the invitation, the transaction rolls back and the endpoint returns retryable 503 delivery_unavailable.

Path Parameters

workspace_idRequired
string <uuid>
Example0198ac5e-f9b7-7000-8000-000000000001

Header Parameters

X-CSRF-TokenRequired
string·min 43·max 43

Session-bound CSRF token. It must exactly match the __Host-assign_csrf cookie sent with the request.

Idempotency-KeyRequired
string·min 16·max 200

Opaque client-generated key for safely retrying this operation.

Request Body

application/json
emailRequired
string <email>
roleRequired
string

owner is deliberately not invitable. Ownership carries the archive power and the last-owner invariant, and is conferred by a membership change on somebody already present.

Values
adminmemberviewer

Responses

Revoke an invitation

DELETE/api/v1/workspaces/{workspace_id}/invitations/{invitation_id}

Withdraws a pending invitation, so its link no longer opens the Workspace. Repeating it answers 204.

Revoking an accepted invitation is refused 409 invitation_not_pending: acceptance is not undone by revoking the link that produced it, and removing the resulting member is a separate, visible act.

Path Parameters

workspace_idRequired
string <uuid>
Example0198ac5e-f9b7-7000-8000-000000000001
invitation_idRequired
string <uuid>
Example0198ac5e-f9b7-7000-8000-000000000001

Header Parameters

X-CSRF-TokenRequired
string·min 43·max 43

Session-bound CSRF token. It must exactly match the __Host-assign_csrf cookie sent with the request.

Idempotency-KeyRequired
string·min 16·max 200

Opaque client-generated key for safely retrying this operation.

Responses

204The invitation is revoked.

Resend an invitation

POST/api/v1/workspaces/{workspace_id}/invitations/{invitation_id}/resend

Replaces an unaccepted invitation with a fresh seven-day invitation and sends the new link to the same normalized address with the same role. The previous link stops working only when delivery of the new message succeeds and the transaction commits. A delivery failure returns 503 delivery_unavailable and leaves the previous pending invitation usable.

Accepted, expired, and explicitly revoked invitations cannot be resent and return 409 invitation_not_pending. Repeating the request with the same Idempotency-Key replays the same successful response without sending another message.

Path Parameters

workspace_idRequired
string <uuid>
Example0198ac5e-f9b7-7000-8000-000000000001
invitation_idRequired
string <uuid>
Example0198ac5e-f9b7-7000-8000-000000000001

Header Parameters

X-CSRF-TokenRequired
string·min 43·max 43

Session-bound CSRF token. It must exactly match the __Host-assign_csrf cookie sent with the request.

Idempotency-KeyRequired
string·min 16·max 200

Opaque client-generated key for safely retrying this operation.

Responses

Accept an invitation

POST/api/v1/invitations/accept

Redeems an invitation token and joins the Workspace. Requires a signed-in session: the invitation's address must equal the caller's stored address exactly after normalization, so a forwarded message cannot transfer the grant. A mismatch answers 403 invitation_recipient_mismatch. A live invitation proves control of the matching mailbox: acceptance verifies that address atomically with membership creation, without another verification email.

Idempotency is account-scoped because the caller may have an authenticated account-only session and no target-Workspace membership before this operation succeeds.

An expired invitation answers 410 invitation_expired. A revoked or already-accepted one answers 409 invitation_not_pending. An unknown token answers 404 — the same answer a swept expired token gives, so the endpoint is not a token oracle.

Acceptance does not switch the calling session onto the joined Workspace; that is PUT /api/v1/auth/session/workspace.

Header Parameters

X-CSRF-TokenRequired
string·min 43·max 43

Session-bound CSRF token. It must exactly match the __Host-assign_csrf cookie sent with the request.

Idempotency-KeyRequired
string·min 16·max 200

Opaque client-generated key for safely retrying this operation.

Request Body

application/json
tokenRequired
string

Responses