API reference
Operator - Invitations
One tag: method, path, summary, auth, and scopes. Request and response fields ship in this page — expand a row to read the contract.
Endpoints
4
GET
/api/v1/operator/workspaces/:workspace_id/invitations
Web Session
List workspace invitations
/api/v1/operator/workspaces/:workspace_id/invitations
Web Session
List workspace invitations
Description
Returns unexpired pending invitations only (`accepted_at` is null and `expires_at` is in the future). Accepted and expired rows are omitted. JSON never includes the invite token — that secret is emailed and shown once on `/app/members`. `:workspace_id` must be the session workspace. Browser session + CSRF only; machine Bearer tokens are 401.
Auth
Web SessionParameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| workspace_id | path | string | Yes | Must be the session's current workspace UUID |
Responses
200
Pending unexpired invitations
Returns: InvitationList
Pending unexpired invitations
Returns: InvitationList
Response Body
| Field | Type | Required | Description |
|---|---|---|---|
| invitations | array<object> | Yes | Invitation records |
| invitations[].id | string | Yes | Invitation UUID |
| invitations[].email | string | Yes | Invitee email |
| invitations[].role | string (member, admin, auditor) | Yes | Assigned role |
| invitations[].inserted_at | datetime (ISO 8601) | Yes | Created at |
| invitations[].updated_at | datetime (ISO 8601) | Yes | Updated at |
| invitations[].expires_at | datetime (ISO 8601) | Yes | Expiry (default now+7 days; resend refreshes by 7 days) |
| invitations[].workspace | object | Yes | Workspace summary |
| invitations[].workspace.id | string | Yes | Workspace UUID |
| invitations[].workspace.name | string | Yes | Workspace name |
| invitations[].accepted_at | datetime (ISO 8601) | No | When the invite was accepted (null while pending) |
| invitations[].accepted_by | object | No | Accepting user (null while pending) |
| invitations[].accepted_by.id | string | Yes | User UUID |
| invitations[].accepted_by.email | string | Yes | User email |
| invitations[].invited_by | object | No | Inviting operator |
| invitations[].invited_by.id | string | Yes | User UUID |
| invitations[].invited_by.email | string | Yes | User email |
Example
{
"invitations": [
{
"accepted_at": null,
"accepted_by": null,
"email": "[email protected]",
"expires_at": "2026-04-03T10:00:00Z",
"id": "7b8c9d0e-1234-4abc-9def-0123456789ab",
"inserted_at": "2026-03-27T10:00:00Z",
"invited_by": {
"email": "[email protected]",
"id": "0f1cdac9-305d-4d11-a53d-3fca310c0635"
},
"role": "member",
"updated_at": "2026-03-27T10:00:00Z",
"workspace": {
"id": "4ce4d170-e6d5-4118-8f4d-fac69dc099ea",
"name": "Acme Corp"
}
}
]
}
401
No operator browser session
No operator browser session
404
workspace_id is not the session's current workspace
workspace_id is not the session's current workspace
POST
/api/v1/operator/workspaces/:workspace_id/invitations
Web Session
Create invitation
/api/v1/operator/workspaces/:workspace_id/invitations
Web Session
Create invitation
Description
Invites an email to the current workspace. `role` is optional and defaults to `member` (`admin` and `auditor` are also valid; `owner` is not). The row expires 7 days from creation. The one-time token is not in the JSON — the invitee joins at `/users/register?invite_token=…` (same URL the email and `/app/members` console copy). Owner/admin only. Marketplace-linked workspaces refuse invites (`400` `marketplace_managed_workspace`). Inviting an existing active member is `409` `already_member`.
Auth
Web SessionRequest Body
| Field | Type | Required | Description |
|---|---|---|---|
| invitation | object | Yes | Invitation attributes |
| invitation.email | string | Yes | Email address to invite |
| invitation.role | string (member, admin, auditor) | No | Role to assign. Defaults to member. owner is not assignable. |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| workspace_id | path | string | Yes | Must be the session's current workspace UUID |
Responses
201
Invitation created. Token is omitted; invitee uses /users/register?invite_token=…
Returns: Invitation
Invitation created. Token is omitted; invitee uses /users/register?invite_token=…
Returns: Invitation
Response Body
| Field | Type | Required | Description |
|---|---|---|---|
| id | string | Yes | Invitation UUID |
| string | Yes | Invitee email | |
| role | string (member, admin, auditor) | Yes | Assigned role |
| inserted_at | datetime (ISO 8601) | Yes | Created at |
| updated_at | datetime (ISO 8601) | Yes | Updated at |
| expires_at | datetime (ISO 8601) | Yes | Expiry (default now+7 days; resend refreshes by 7 days) |
| workspace | object | Yes | Workspace summary |
| workspace.id | string | Yes | Workspace UUID |
| workspace.name | string | Yes | Workspace name |
| accepted_at | datetime (ISO 8601) | No | When the invite was accepted (null while pending) |
| accepted_by | object | No | Accepting user (null while pending) |
| accepted_by.id | string | Yes | User UUID |
| accepted_by.email | string | Yes | User email |
| invited_by | object | No | Inviting operator |
| invited_by.id | string | Yes | User UUID |
| invited_by.email | string | Yes | User email |
Example
{
"accepted_at": null,
"accepted_by": null,
"email": "[email protected]",
"expires_at": "2026-04-03T10:00:00Z",
"id": "7b8c9d0e-1234-4abc-9def-0123456789ab",
"inserted_at": "2026-03-27T10:00:00Z",
"invited_by": {
"email": "[email protected]",
"id": "0f1cdac9-305d-4d11-a53d-3fca310c0635"
},
"role": "member",
"updated_at": "2026-03-27T10:00:00Z",
"workspace": {
"id": "4ce4d170-e6d5-4118-8f4d-fac69dc099ea",
"name": "Acme Corp"
}
}
400
Marketplace-managed workspace (`marketplace_managed_workspace`) or other atom error
Marketplace-managed workspace (`marketplace_managed_workspace`) or other atom error
401
No operator browser session
No operator browser session
403
Owner or admin membership required
Owner or admin membership required
404
workspace_id is not the session's current workspace
workspace_id is not the session's current workspace
409
That email is already an active workspace member
That email is already an active workspace member
422
Invalid email, invalid role, or a pending invite already exists
Invalid email, invalid role, or a pending invite already exists
PATCH
/api/v1/operator/workspaces/:workspace_id/invitations/:id/resend
Web Session
Resend invitation
/api/v1/operator/workspaces/:workspace_id/invitations/:id/resend
Web Session
Resend invitation
Description
Re-delivers the invitation email and refreshes `expires_at` by another 7 days from now. The token is unchanged and is still omitted from JSON. Refuses expired rows (`400` `expired`) and already-accepted rows (`400` `already_accepted`). Owner/admin only.
Auth
Web SessionParameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| workspace_id | path | string | Yes | Must be the session's current workspace UUID |
| id | path | string | Yes | Invitation UUID |
Responses
200
Invitation resent; expires_at refreshed by 7 days
Returns: Invitation
Invitation resent; expires_at refreshed by 7 days
Returns: Invitation
Response Body
| Field | Type | Required | Description |
|---|---|---|---|
| id | string | Yes | Invitation UUID |
| string | Yes | Invitee email | |
| role | string (member, admin, auditor) | Yes | Assigned role |
| inserted_at | datetime (ISO 8601) | Yes | Created at |
| updated_at | datetime (ISO 8601) | Yes | Updated at |
| expires_at | datetime (ISO 8601) | Yes | Expiry (default now+7 days; resend refreshes by 7 days) |
| workspace | object | Yes | Workspace summary |
| workspace.id | string | Yes | Workspace UUID |
| workspace.name | string | Yes | Workspace name |
| accepted_at | datetime (ISO 8601) | No | When the invite was accepted (null while pending) |
| accepted_by | object | No | Accepting user (null while pending) |
| accepted_by.id | string | Yes | User UUID |
| accepted_by.email | string | Yes | User email |
| invited_by | object | No | Inviting operator |
| invited_by.id | string | Yes | User UUID |
| invited_by.email | string | Yes | User email |
Example
{
"accepted_at": null,
"accepted_by": null,
"email": "[email protected]",
"expires_at": "2026-04-03T10:00:00Z",
"id": "7b8c9d0e-1234-4abc-9def-0123456789ab",
"inserted_at": "2026-03-27T10:00:00Z",
"invited_by": {
"email": "[email protected]",
"id": "0f1cdac9-305d-4d11-a53d-3fca310c0635"
},
"role": "member",
"updated_at": "2026-03-27T10:00:00Z",
"workspace": {
"id": "4ce4d170-e6d5-4118-8f4d-fac69dc099ea",
"name": "Acme Corp"
}
}
400
`expired` or `already_accepted`
`expired` or `already_accepted`
401
No operator browser session
No operator browser session
403
Owner or admin membership required
Owner or admin membership required
404
Invitation not found, or workspace_id is not the current workspace
Invitation not found, or workspace_id is not the current workspace
DELETE
/api/v1/operator/workspaces/:workspace_id/invitations/:id
Web Session
Cancel invitation
/api/v1/operator/workspaces/:workspace_id/invitations/:id
Web Session
Cancel invitation
Description
Deletes a pending invitation. Owner/admin only. `:workspace_id` must be the session workspace.
Auth
Web SessionParameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| workspace_id | path | string | Yes | Must be the session's current workspace UUID |
| id | path | string | Yes | Invitation UUID |
Responses
204
Invitation cancelled
Invitation cancelled
401
No operator browser session
No operator browser session
403
Owner or admin membership required
Owner or admin membership required
404
Invitation not found, or workspace_id is not the current workspace
Invitation not found, or workspace_id is not the current workspace