API reference
Tenant: users, groups, roles and policies
Administer an organization's members, invites, groups, roles, sign-in clients, sign-in logs and sign-in policy.
Reads need tenant:read, changes tenant:write (owners and admins, or a custom role with them). Changes that touch owners, and the sign-in policy, need an owner; nobody assigns a role with scopes they don't hold. Every change is recorded in the audit log. See Tenant for what each part does.
GET /v1/orgs/:orgId/tenant/groups
Groups with their size, owners and the roles they grant.
Auth: user access token or platform agent key · Scope: tenant:read
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
Response 200
{
groups: {
customRoleIds: string[]
members: number
owners: string[]
createdAt?: number
role?: "admin" | "developer" | "viewer"
description?: string
teamId: string
slug: string
name: string
}[]
}POST /v1/orgs/:orgId/tenant/groups
Creates a group; owners default to the person creating it. role is a built-in role members get (not owner).
Auth: user access token or platform agent key · Scope: tenant:write
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
name | string | Yes | 1–64 characters; trimmed |
slug | string | No | up to 39 characters; trimmed |
description | string | No | up to 500 characters; trimmed |
role | "admin" | "developer" | "viewer" | No | |
customRoleIds | string[] | No | up to 20 items; each up to 40 characters |
ownerIds | string[] | No | up to 20 items; each up to 64 characters |
Response 201
{
group: {
customRoleIds: string[]
members: number
owners: string[]
createdAt?: number
role?: "admin" | "developer" | "viewer"
description?: string
teamId: string
slug: string
name: string
}
members: {
userId: string
email?: string
name?: string
role: "owner" | "member"
addedAt?: number
}[]
grants: {
level: "write"
type: "project"
id: string
name: string
} | {
level: "write"
type: "repository"
id: string
name: string
}[]
apps: string[]
}Errors
| Status | Message |
|---|---|
400 | Slugs are lowercase letters, digits and single hyphens. |
400 | Unknown role. |
404 | Organization not found |
404 | Not a member of this organization |
404 | Group not found |
409 | A group with this slug exists. |
GET /v1/orgs/:orgId/tenant/groups/:teamId
Members, owners, granted roles, Serverless App Service and repository access, and app assignments.
Auth: user access token or platform agent key · Scope: tenant:read
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:teamId | Group id (team_…). |
Response 200
{
group: {
customRoleIds: string[]
members: number
owners: string[]
createdAt?: number
role?: "admin" | "developer" | "viewer"
description?: string
teamId: string
slug: string
name: string
}
members: {
userId: string
email?: string
name?: string
role: "owner" | "member"
addedAt?: number
}[]
grants: {
level: "write"
type: "project"
id: string
name: string
} | {
level: "write"
type: "repository"
id: string
name: string
}[]
apps: string[]
}Errors
| Status | Message |
|---|---|
404 | Group not found |
PATCH /v1/orgs/:orgId/tenant/groups/:teamId
Name, description, the built-in role members get (null removes it) and custom roles.
Auth: user access token or platform agent key · Scope: tenant:write
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:teamId | Group id (team_…). |
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
name | string | No | 1–64 characters; trimmed |
description | string | No | up to 500 characters; trimmed; can be null |
role | "admin" | "developer" | "viewer" | No | can be null |
customRoleIds | string[] | No | up to 20 items; each up to 40 characters |
Response 200
{
group: {
customRoleIds: string[]
members: number
owners: string[]
createdAt?: number
role?: "admin" | "developer" | "viewer"
description?: string
teamId: string
slug: string
name: string
}
members: {
userId: string
email?: string
name?: string
role: "owner" | "member"
addedAt?: number
}[]
grants: {
level: "write"
type: "project"
id: string
name: string
} | {
level: "write"
type: "repository"
id: string
name: string
}[]
apps: string[]
}Errors
| Status | Message |
|---|---|
400 | Unknown role. |
404 | Organization not found |
404 | Group not found |
DELETE /v1/orgs/:orgId/tenant/groups/:teamId
Deletes the group with its memberships, access and assignments (members keep their own roles).
Auth: user access token or platform agent key · Scope: tenant:write
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:teamId | Group id (team_…). |
Response 204 with no body.
Errors
| Status | Message |
|---|---|
404 | Organization not found |
404 | Group not found |
PUT /v1/orgs/:orgId/tenant/groups/:teamId/members/:userId
Adds a member or changes their group role (owner manages the group's members, member).
Auth: user access token or platform agent key · Scope: tenant:write
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:teamId | Group id (team_…). |
:userId | A member's user id (usr_…). |
Request body
| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
role | "owner" | "member" | No | "member" |
Response 200
{
group: {
customRoleIds: string[]
members: number
owners: string[]
createdAt?: number
role?: "admin" | "developer" | "viewer"
description?: string
teamId: string
slug: string
name: string
}
members: {
userId: string
email?: string
name?: string
role: "owner" | "member"
addedAt?: number
}[]
grants: {
level: "write"
type: "project"
id: string
name: string
} | {
level: "write"
type: "repository"
id: string
name: string
}[]
apps: string[]
}Errors
| Status | Message |
|---|---|
404 | Organization not found |
404 | Group not found |
404 | Not a member of this organization |
DELETE /v1/orgs/:orgId/tenant/groups/:teamId/members/:userId
Takes a member out of the group.
Auth: user access token or platform agent key · Scope: tenant:write
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:teamId | Group id (team_…). |
:userId | A member's user id (usr_…). |
Response 200
{
group: {
customRoleIds: string[]
members: number
owners: string[]
createdAt?: number
role?: "admin" | "developer" | "viewer"
description?: string
teamId: string
slug: string
name: string
}
members: {
userId: string
email?: string
name?: string
role: "owner" | "member"
addedAt?: number
}[]
grants: {
level: "write"
type: "project"
id: string
name: string
} | {
level: "write"
type: "repository"
id: string
name: string
}[]
apps: string[]
}Errors
| Status | Message |
|---|---|
404 | Organization not found |
404 | Group not found |
404 | Not a member of this organization |
PUT /v1/orgs/:orgId/tenant/groups/:teamId/grants/:resourceType/:resourceId
Gives the group write access to one Serverless App Service or repository.
Auth: user access token or platform agent key · Scope: tenant:write
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:teamId | Group id (team_…). |
:resourceType | What the protocol is attached to: org, project, space, calendar, mailbox or agent; for a group's access, project or repository. |
:resourceId | Resource id (res_…); for a group's access, the Serverless App Service id (prj_…) or the repository's resource id. |
Response 200
{
group: {
customRoleIds: string[]
members: number
owners: string[]
createdAt?: number
role?: "admin" | "developer" | "viewer"
description?: string
teamId: string
slug: string
name: string
}
members: {
userId: string
email?: string
name?: string
role: "owner" | "member"
addedAt?: number
}[]
grants: {
level: "write"
type: "project"
id: string
name: string
} | {
level: "write"
type: "repository"
id: string
name: string
}[]
apps: string[]
}Errors
| Status | Message |
|---|---|
400 | Unknown resource type or principal. |
400 | Unknown resource. |
404 | Group not found |
404 | That Serverless App Service or repository isn't in this organization. |
DELETE /v1/orgs/:orgId/tenant/groups/:teamId/grants/:resourceType/:resourceId
Removes the group's write access to the Serverless App Service or repository.
Auth: user access token or platform agent key · Scope: tenant:write
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:teamId | Group id (team_…). |
:resourceType | What the protocol is attached to: org, project, space, calendar, mailbox or agent; for a group's access, project or repository. |
:resourceId | Resource id (res_…); for a group's access, the Serverless App Service id (prj_…) or the repository's resource id. |
Response 200
{
group: {
customRoleIds: string[]
members: number
owners: string[]
createdAt?: number
role?: "admin" | "developer" | "viewer"
description?: string
teamId: string
slug: string
name: string
}
members: {
userId: string
email?: string
name?: string
role: "owner" | "member"
addedAt?: number
}[]
grants: {
level: "write"
type: "project"
id: string
name: string
} | {
level: "write"
type: "repository"
id: string
name: string
}[]
apps: string[]
}Errors
| Status | Message |
|---|---|
400 | Unknown resource type or principal. |
400 | Unknown resource. |
404 | Group not found |
404 | That Serverless App Service or repository isn't in this organization. |
GET /v1/orgs/:orgId/tenant/roles
Built-in roles with their scopes, custom roles, and who holds each.
Auth: user access token or platform agent key · Scope: tenant:read
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
Response 200
{
builtIn: {
users: string[]
groups: string[]
scopes: ("platform:admin" | "platform:infra" | "platform:analytics" | "platform:coverage" | "org:read" | "org:write" | "audit:read" | "tenant:read" | "tenant:write" | "members:read" | "members:write" | "projects:read" | "projects:write" | "deployments:read" | "deployments:write" | "env:read" | "env:write" | "keys:read" | "keys:use" | "keys:write" | "domains:read" | "domains:write" | "resources:read" | "resources:write" | "git:read" | "git:write" | "git:admin" | "logs:read" | "analytics:read" | "knowledge:read" | "knowledge:write" | "connectors:read" | "connectors:write" | "chat:use" | "mcp:connect" | "agents:read" | "agents:write" | "agents:run" | "mail:read" | "mail:send" | "mail:admin" | "calendar:read" | "calendar:write" | "contacts:read" | "contacts:write" | "issues:read" | "issues:write" | "issues:admin" | "maps:read" | "maps:write" | "drive:read" | "drive:write" | "crm:read" | "crm:write" | "crm:admin" | "marketing:read" | "marketing:write" | "marketing:send" | "marketing:admin" | "health:read" | "health:write" | "weather:read" | "weather:write" | "food:read" | "food:write")[]
groupAssignable: boolean
id: "owner" | "admin" | "developer" | "viewer"
name: string
description: string
}[]
custom: {
users: string[]
groups: string[]
scopes: string[]
createdAt?: number
updatedAt?: number
description?: string
roleId: string
name: string
}[]
assignableScopes: ("platform:admin" | "platform:infra" | "platform:analytics" | "platform:coverage" | "org:read" | "org:write" | "audit:read" | "tenant:read" | "tenant:write" | "members:read" | "members:write" | "projects:read" | "projects:write" | "deployments:read" | "deployments:write" | "env:read" | "env:write" | "keys:read" | "keys:use" | "keys:write" | "domains:read" | "domains:write" | "resources:read" | "resources:write" | "git:read" | "git:write" | "git:admin" | "logs:read" | "analytics:read" | "knowledge:read" | "knowledge:write" | "connectors:read" | "connectors:write" | "chat:use" | "mcp:connect" | "agents:read" | "agents:write" | "agents:run" | "mail:read" | "mail:send" | "mail:admin" | "calendar:read" | "calendar:write" | "contacts:read" | "contacts:write" | "issues:read" | "issues:write" | "issues:admin" | "maps:read" | "maps:write" | "drive:read" | "drive:write" | "crm:read" | "crm:write" | "crm:admin" | "marketing:read" | "marketing:write" | "marketing:send" | "marketing:admin" | "health:read" | "health:write" | "weather:read" | "weather:write" | "food:read" | "food:write")[]
}Errors
| Status | Message |
|---|---|
404 | Organization not found |
POST /v1/orgs/:orgId/tenant/roles
Creates a custom role: a named set of scopes added on top of a member's role.
Auth: user access token or platform agent key · Scope: tenant:write
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
name | string | Yes | 1–64 characters; trimmed |
description | string | No | up to 500 characters; trimmed |
scopes | [] | Yes | 1–100 items |
Response 201
{
role: {
name: string
createdAt?: number
updatedAt?: number
orgId: string
createdBy: string
scopes: string[]
description?: string
roleId: string
}
}Errors
| Status | Message |
|---|---|
400 | Unknown or platform scopes: … |
400 | Choose at least one scope. |
400 | An organization can have up to 50 custom roles. |
409 | A role with this name exists. |
PATCH /v1/orgs/:orgId/tenant/roles/:roleId
Renames a custom role or changes its scopes (you need every scope it grants, before and after).
Auth: user access token or platform agent key · Scope: tenant:write
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:roleId | A built-in role (owner, admin, developer, viewer) or a custom role id (rol_…); in Mirage, a server role (mrl_…, or the server's id for @everyone). |
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
name | string | No | 1–64 characters; trimmed |
description | string | No | up to 500 characters; trimmed; can be null |
scopes | [] | No | 1–100 items |
Response 200
{
role: {
name: string
createdAt?: number
updatedAt?: number
orgId: string
createdBy: string
scopes: string[]
description?: string
roleId: string
}
}Errors
| Status | Message |
|---|---|
400 | Unknown or platform scopes: … |
400 | Choose at least one scope. |
404 | Role not found |
409 | A role with this name exists. |
DELETE /v1/orgs/:orgId/tenant/roles/:roleId
Deletes a custom role; members and groups holding it lose its scopes.
Auth: user access token or platform agent key · Scope: tenant:write
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:roleId | A built-in role (owner, admin, developer, viewer) or a custom role id (rol_…); in Mirage, a server role (mrl_…, or the server's id for @everyone). |
Response 204 with no body.
Errors
| Status | Message |
|---|---|
404 | Role not found |
POST /v1/orgs/:orgId/tenant/roles/:roleId/assignments
Assigns a role (a built-in role id such as admin, or a custom rol_…) to a member or group. A built-in role replaces a member's role; a group grants one built-in role at most.
Auth: user access token or platform agent key · Scope: tenant:write
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:roleId | A built-in role (owner, admin, developer, viewer) or a custom role id (rol_…); in Mirage, a server role (mrl_…, or the server's id for @everyone). |
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
principalType | "user" | "group" | Yes | |
principalId | string | Yes | 1–64 characters |
Response 200
{
builtIn: {
users: string[]
groups: string[]
scopes: ("platform:admin" | "platform:infra" | "platform:analytics" | "platform:coverage" | "org:read" | "org:write" | "audit:read" | "tenant:read" | "tenant:write" | "members:read" | "members:write" | "projects:read" | "projects:write" | "deployments:read" | "deployments:write" | "env:read" | "env:write" | "keys:read" | "keys:use" | "keys:write" | "domains:read" | "domains:write" | "resources:read" | "resources:write" | "git:read" | "git:write" | "git:admin" | "logs:read" | "analytics:read" | "knowledge:read" | "knowledge:write" | "connectors:read" | "connectors:write" | "chat:use" | "mcp:connect" | "agents:read" | "agents:write" | "agents:run" | "mail:read" | "mail:send" | "mail:admin" | "calendar:read" | "calendar:write" | "contacts:read" | "contacts:write" | "issues:read" | "issues:write" | "issues:admin" | "maps:read" | "maps:write" | "drive:read" | "drive:write" | "crm:read" | "crm:write" | "crm:admin" | "marketing:read" | "marketing:write" | "marketing:send" | "marketing:admin" | "health:read" | "health:write" | "weather:read" | "weather:write" | "food:read" | "food:write")[]
groupAssignable: boolean
id: "owner" | "admin" | "developer" | "viewer"
name: string
description: string
}[]
custom: {
users: string[]
groups: string[]
scopes: string[]
createdAt?: number
updatedAt?: number
description?: string
roleId: string
name: string
}[]
assignableScopes: ("platform:admin" | "platform:infra" | "platform:analytics" | "platform:coverage" | "org:read" | "org:write" | "audit:read" | "tenant:read" | "tenant:write" | "members:read" | "members:write" | "projects:read" | "projects:write" | "deployments:read" | "deployments:write" | "env:read" | "env:write" | "keys:read" | "keys:use" | "keys:write" | "domains:read" | "domains:write" | "resources:read" | "resources:write" | "git:read" | "git:write" | "git:admin" | "logs:read" | "analytics:read" | "knowledge:read" | "knowledge:write" | "connectors:read" | "connectors:write" | "chat:use" | "mcp:connect" | "agents:read" | "agents:write" | "agents:run" | "mail:read" | "mail:send" | "mail:admin" | "calendar:read" | "calendar:write" | "contacts:read" | "contacts:write" | "issues:read" | "issues:write" | "issues:admin" | "maps:read" | "maps:write" | "drive:read" | "drive:write" | "crm:read" | "crm:write" | "crm:admin" | "marketing:read" | "marketing:write" | "marketing:send" | "marketing:admin" | "health:read" | "health:write" | "weather:read" | "weather:write" | "food:read" | "food:write")[]
}Errors
| Status | Message |
|---|---|
400 | Guests can be developers or viewers. |
400 | Only guests have an access end date. |
400 | Groups can't grant the owner role. |
400 | Unknown role. |
404 | Organization not found |
404 | Not a member of this organization |
404 | Group not found |
404 | Role not found |
409 | An organization needs at least one other active owner first. |
DELETE /v1/orgs/:orgId/tenant/roles/:roleId/assignments/:principalType/:principalId
Takes a custom role from a member or group, or the built-in role a group grants.
Auth: user access token or platform agent key · Scope: tenant:write
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:roleId | A built-in role (owner, admin, developer, viewer) or a custom role id (rol_…); in Mirage, a server role (mrl_…, or the server's id for @everyone). |
:principalType | user or group. |
:principalId | A person (usr_…) or a group or team (team_…): the member or group a Tenant assignment or a Drive share is for. |
Response 200
{
builtIn: {
users: string[]
groups: string[]
scopes: ("platform:admin" | "platform:infra" | "platform:analytics" | "platform:coverage" | "org:read" | "org:write" | "audit:read" | "tenant:read" | "tenant:write" | "members:read" | "members:write" | "projects:read" | "projects:write" | "deployments:read" | "deployments:write" | "env:read" | "env:write" | "keys:read" | "keys:use" | "keys:write" | "domains:read" | "domains:write" | "resources:read" | "resources:write" | "git:read" | "git:write" | "git:admin" | "logs:read" | "analytics:read" | "knowledge:read" | "knowledge:write" | "connectors:read" | "connectors:write" | "chat:use" | "mcp:connect" | "agents:read" | "agents:write" | "agents:run" | "mail:read" | "mail:send" | "mail:admin" | "calendar:read" | "calendar:write" | "contacts:read" | "contacts:write" | "issues:read" | "issues:write" | "issues:admin" | "maps:read" | "maps:write" | "drive:read" | "drive:write" | "crm:read" | "crm:write" | "crm:admin" | "marketing:read" | "marketing:write" | "marketing:send" | "marketing:admin" | "health:read" | "health:write" | "weather:read" | "weather:write" | "food:read" | "food:write")[]
groupAssignable: boolean
id: "owner" | "admin" | "developer" | "viewer"
name: string
description: string
}[]
custom: {
users: string[]
groups: string[]
scopes: string[]
createdAt?: number
updatedAt?: number
description?: string
roleId: string
name: string
}[]
assignableScopes: ("platform:admin" | "platform:infra" | "platform:analytics" | "platform:coverage" | "org:read" | "org:write" | "audit:read" | "tenant:read" | "tenant:write" | "members:read" | "members:write" | "projects:read" | "projects:write" | "deployments:read" | "deployments:write" | "env:read" | "env:write" | "keys:read" | "keys:use" | "keys:write" | "domains:read" | "domains:write" | "resources:read" | "resources:write" | "git:read" | "git:write" | "git:admin" | "logs:read" | "analytics:read" | "knowledge:read" | "knowledge:write" | "connectors:read" | "connectors:write" | "chat:use" | "mcp:connect" | "agents:read" | "agents:write" | "agents:run" | "mail:read" | "mail:send" | "mail:admin" | "calendar:read" | "calendar:write" | "contacts:read" | "contacts:write" | "issues:read" | "issues:write" | "issues:admin" | "maps:read" | "maps:write" | "drive:read" | "drive:write" | "crm:read" | "crm:write" | "crm:admin" | "marketing:read" | "marketing:write" | "marketing:send" | "marketing:admin" | "health:read" | "health:write" | "weather:read" | "weather:write" | "food:read" | "food:write")[]
}Errors
| Status | Message |
|---|---|
400 | Unknown resource type or principal. |
400 | Every member has a built-in role: assign another one instead. |
400 | Unknown role. |
404 | Group not found |
404 | Organization not found |
404 | Role not found |
404 | Not a member of this organization |
GET /v1/orgs/:orgId/tenant/apps
The org's sign-in clients (per Serverless App Service) with assignment and secret expiry, MCP clients members connected here, and its keys.
Auth: user access token or platform agent key · Scope: tenant:read
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
Response 200
{
signIn: {
createdAt?: number
lastUsedAt?: number
secretCreatedAt?: number
secretExpiresAt?: number
assignmentRequired: boolean
assignments: number
clientUri?: string
logoUri?: string
clientId: string
name: string
projectId?: string
project?: string
redirectUris: string[]
subjectType: "public" | "pairwise"
}[]
mcp: {
clientId: string
name: string
users: {
userId: string
scopes: string[]
lastUsedAt?: number
connectedAt?: number
}[]
}[]
keys: {
keyId: string
name: string
kind: "api" | "mcp" | "agent"
scopes: string[]
createdBy: string
lastUsedAt?: number
expiresAt?: number
createdAt?: number
machine: boolean
}[]
}GET /v1/orgs/:orgId/tenant/apps/:clientId
One sign-in client: redirect URIs, secret expiry and who is assigned.
Auth: user access token or platform agent key · Scope: tenant:read
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:clientId | Sign-in client id (cli_…). |
Response 200
{
app: {
createdAt?: number
lastUsedAt?: number
secretCreatedAt?: number
secretExpiresAt?: number
assignmentRequired: boolean
assignments: number
clientUri?: string
logoUri?: string
clientId: string
name: string
projectId?: string
project?: string
redirectUris: string[]
subjectType: "public" | "pairwise"
}
assignments: {
principalType: "user" | "group"
principalId: string
label: string
assignedAt?: number
}[]
}Errors
| Status | Message |
|---|---|
404 | App not found |
PATCH /v1/orgs/:orgId/tenant/apps/:clientId
assignmentRequired: only assigned people and groups can sign in (checked at sign-in and every refresh).
Auth: user access token or platform agent key · Scope: tenant:write
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:clientId | Sign-in client id (cli_…). |
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
assignmentRequired | boolean | Yes |
Response 200
{
app: {
createdAt?: number
lastUsedAt?: number
secretCreatedAt?: number
secretExpiresAt?: number
assignmentRequired: boolean
assignments: number
clientUri?: string
logoUri?: string
clientId: string
name: string
projectId?: string
project?: string
redirectUris: string[]
subjectType: "public" | "pairwise"
}
assignments: {
principalType: "user" | "group"
principalId: string
label: string
assignedAt?: number
}[]
}Errors
| Status | Message |
|---|---|
404 | App not found |
POST /v1/orgs/:orgId/tenant/apps/:clientId/secret
Replaces the secret (the old one stops at once) with one valid for expiresInDays (0: no expiry); shown once.
Auth: user access token or platform agent key · Scope: tenant:write
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:clientId | Sign-in client id (cli_…). |
Request body
| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
expiresInDays | integer | No | 180 |
Response 200
{
secretExpiresAt?: number
clientSecret: string
app: {
createdAt?: number
lastUsedAt?: number
secretCreatedAt?: number
secretExpiresAt?: number
assignmentRequired: boolean
assignments: number
clientUri?: string
logoUri?: string
clientId: string
name: string
projectId?: string
project?: string
redirectUris: string[]
subjectType: "public" | "pairwise"
}
assignments: {
principalType: "user" | "group"
principalId: string
label: string
assignedAt?: number
}[]
}Errors
| Status | Message |
|---|---|
400 | Choose a lifetime from the list. |
404 | App not found |
POST /v1/orgs/:orgId/tenant/apps/:clientId/assignments
Lets a member or group sign in to an app that requires assignment.
Auth: user access token or platform agent key · Scope: tenant:write
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:clientId | Sign-in client id (cli_…). |
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
principalType | "user" | "group" | Yes | |
principalId | string | Yes | 1–64 characters |
Response 200
{
app: {
createdAt?: number
lastUsedAt?: number
secretCreatedAt?: number
secretExpiresAt?: number
assignmentRequired: boolean
assignments: number
clientUri?: string
logoUri?: string
clientId: string
name: string
projectId?: string
project?: string
redirectUris: string[]
subjectType: "public" | "pairwise"
}
assignments: {
principalType: "user" | "group"
principalId: string
label: string
assignedAt?: number
}[]
}Errors
| Status | Message |
|---|---|
404 | App not found |
404 | Not a member of this organization |
404 | Group not found |
DELETE /v1/orgs/:orgId/tenant/apps/:clientId/assignments/:principalType/:principalId
Takes a member's or group's assignment away; their next refresh is refused.
Auth: user access token or platform agent key · Scope: tenant:write
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:clientId | Sign-in client id (cli_…). |
:principalType | user or group. |
:principalId | A person (usr_…) or a group or team (team_…): the member or group a Tenant assignment or a Drive share is for. |
Response 200
{
app: {
createdAt?: number
lastUsedAt?: number
secretCreatedAt?: number
secretExpiresAt?: number
assignmentRequired: boolean
assignments: number
clientUri?: string
logoUri?: string
clientId: string
name: string
projectId?: string
project?: string
redirectUris: string[]
subjectType: "public" | "pairwise"
}
assignments: {
principalType: "user" | "group"
principalId: string
label: string
assignedAt?: number
}[]
}Errors
| Status | Message |
|---|---|
400 | Unknown resource type or principal. |
404 | App not found |
DELETE /v1/orgs/:orgId/tenant/apps/:clientId/connections
Disconnects an MCP client from this org for every member.
Auth: user access token or platform agent key · Scope: tenant:write
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:clientId | Sign-in client id (cli_…). |
Response 204 with no body.
Errors
| Status | Message |
|---|---|
404 | App not found |
GET /v1/orgs/:orgId/tenant/sign-ins
Members' sign-ins and failed sign-ins, newest first: method, address, approximate place, device.
Auth: user access token or platform agent key · Scope: tenant:read
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
| Query parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
cursor | string | No | up to 4,096 characters | |
limit | integer | No | 50 | 1–100; coerced from a string |
user | string | No | up to 64 characters | |
result | "success" | "failure" | No |
Response 200
{
signIns: {
eventId: string
at: number
userId: string
user?: string
result: "success" | "failure"
method?: string
locked?: boolean
client?: string
ip?: string
country?: string
region?: string
city?: string
browser?: string
os?: string
model?: string
}[]
cursor: null | string
}Errors
| Status | Message |
|---|---|
400 | Invalid cursor |
GET /v1/orgs/:orgId/tenant/policies
The sign-in policy and the members it would leave without access.
Auth: user access token or platform agent key · Scope: tenant:read
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
Response 200
{
signIn: {
strength: "any" | "mfa" | "passkey"
methods: ("passkey" | "password")[]
graceUntil?: number
sessionHours?: number
}
coverage: {
members: number
affected: {
userId: string
email?: string
name?: string
passkeys: number
textCode: boolean
authenticator: boolean
}[]
}
}Errors
| Status | Message |
|---|---|
404 | Organization not found |
PUT /v1/orgs/:orgId/tenant/policies/sign-in
Sets the sign-in policy (owners): required strength (any, mfa: a passkey or text codes, passkey), allowed methods, a grace period in days and the longest a sign-in lasts in hours.
Auth: user access token or platform agent key · Scope: tenant:write
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
Request body
| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
strength | "any" | "mfa" | "passkey" | Yes | ||
methods | ("password" | "passkey")[] | Yes | 1–2 items | |
graceDays | integer | No | 0 | 0–90 |
sessionHours | integer | No | 1–720; can be null |
Response 200
{
signIn: {
strength: "any" | "mfa" | "passkey"
methods: ("passkey" | "password")[]
graceUntil?: number
sessionHours?: number
}
coverage: {
members: number
affected: {
userId: string
email?: string
name?: string
passkeys: number
textCode: boolean
authenticator: boolean
}[]
}
}Errors
| Status | Message |
|---|---|
400 | Allow at least one sign-in method. |
400 | Requiring a passkey needs passkeys allowed. |
400 | A grace period is 0 to 90 days. |
400 | Sign-ins can last 1 hour to 30 days. |
404 | Organization not found |
409 | You don't meet this policy yet. Add a passkey first, or give a grace period. |
GET /v1/orgs/:orgId/tenant/keys
Every key of the organization with its creator, scopes, expiry, status and last use (when, address, country, client). Never secrets.
Auth: user access token or platform agent key · Scope: tenant:read
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
Response 200
{
keys: {
keyId: string
name: string
kind: string
scopes: string[]
git: boolean
machine?: string
createdBy: null | {
userId: string
name?: string
email?: string
}
createdAt?: number
expiresAt?: number
lastUsedAt?: number
lastUsedIp?: string
lastUsedCountry?: string
lastUsedAgent?: string
status: "active" | "expired" | "creator_stopped"
}[]
}DELETE /v1/orgs/:orgId/tenant/keys/:keyId
Revokes a key of the organization at once; audited as key.revoke.
Auth: user access token or platform agent key · Scope: tenant:write
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:keyId | Key id (key_…). |
Response 204 with no body.
Errors
| Status | Message |
|---|---|
404 | Key not found |
GET /v1/orgs/:orgId/tenant/users
Members with sign-in health; pending invites and removed members (restorable for 30 days).
Auth: user access token or platform agent key · Scope: tenant:read
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
| Query parameter | Type | Required | Notes |
|---|---|---|---|
q | string | No | up to 200 characters |
role | "owner" | "admin" | "developer" | "viewer" | No | |
status | "active" | "blocked" | "guest" | "member" | No | |
signIn | "never" | "30d" | "90d" | No | |
mfa | "yes" | "no" | No |
Response 200
{
users: {
userId: string
email?: string
name?: string
role: "owner" | "admin" | "developer" | "viewer"
effectiveRole: "owner" | "admin" | "developer" | "viewer"
title?: string
department?: string
status: "active" | "blocked"
blockedAt?: number
guest: boolean
guestExpiresAt?: number
joinedAt?: number
lastSignInAt?: number
lastSignInMethod?: string
passkeys: number
textCode: boolean
authenticator: boolean
mfa: boolean
groups: {
teamId: string
name: string
role: "owner" | "member"
}[]
customRoleIds: string[]
tokensValidAfter?: number
disabledAccount: boolean
}[]
total: number
invites: {
teamIds: string[]
department?: string
title?: string
guestDays?: number
inviteId: string
email: string
role: "owner" | "admin" | "developer" | "viewer"
expiresAt: number
createdAt?: number
invitedBy: string
guest: boolean
}[]
removed: {
userId: string
email?: string
name?: string
role: string
removedAt: number
removedBy: string
restoreUntil: number
}[]
}GET /v1/orgs/:orgId/tenant/users/export
Every member as CSV (email, name, role, attributes, status, groups, sign-in health).
Auth: user access token or platform agent key · Scope: tenant:read
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
Response 200 with no body.
GET /v1/orgs/:orgId/tenant/users/:userId
One member: groups, browser sessions, keys they created, app assignments and recent sign-ins.
Auth: user access token or platform agent key · Scope: tenant:read
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:userId | A member's user id (usr_…). |
Response 200
{
user: {
userId: string
email?: string
name?: string
role: "owner" | "admin" | "developer" | "viewer"
effectiveRole: "owner" | "admin" | "developer" | "viewer"
title?: string
department?: string
status: "active" | "blocked"
blockedAt?: number
guest: boolean
guestExpiresAt?: number
joinedAt?: number
lastSignInAt?: number
lastSignInMethod?: string
passkeys: number
textCode: boolean
authenticator: boolean
mfa: boolean
groups: {
teamId: string
name: string
role: "owner" | "member"
}[]
customRoleIds: string[]
tokensValidAfter?: number
disabledAccount: boolean
}
sessions: {
sessionId: string
method?: string
browser?: string
os?: string
deviceKind?: string
ip?: string
country?: string
region?: string
city?: string
createdAt?: number
lastSeenAt?: number
reachesOrg: boolean
}[]
keys: {
keyId: string
name: string
kind: "api" | "mcp" | "agent"
scopes: string[]
lastUsedAt?: number
expiresAt?: number
createdAt?: number
machine: boolean
}[]
apps: string[]
signIns: {
eventId: string
orgId: string
action: string
actor: {
type: "user" | "key" | "device" | "system"
id: string
label?: string
}
target: {
type: string
id: string
label?: string
}
metadata?: {
[key: string]: unknown
}
ip?: string
userAgent?: string
createdAt: number
}[]
}Errors
| Status | Message |
|---|---|
404 | Not a member of this organization |
PATCH /v1/orgs/:orgId/tenant/users/:userId
Role, title, department, and a guest's access end (epoch seconds, or null).
Auth: user access token or platform agent key · Scope: tenant:write
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:userId | A member's user id (usr_…). |
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
role | "owner" | "admin" | "developer" | "viewer" | No | |
title | any JSON | No | can be null |
department | any JSON | No | can be null |
guestExpiresAt | integer | No | > 0; can be null |
Response 200
{
user: {
userId: string
email?: string
name?: string
role: "owner" | "admin" | "developer" | "viewer"
effectiveRole: "owner" | "admin" | "developer" | "viewer"
title?: string
department?: string
status: "active" | "blocked"
blockedAt?: number
guest: boolean
guestExpiresAt?: number
joinedAt?: number
lastSignInAt?: number
lastSignInMethod?: string
passkeys: number
textCode: boolean
authenticator: boolean
mfa: boolean
groups: {
teamId: string
name: string
role: "owner" | "member"
}[]
customRoleIds: string[]
tokensValidAfter?: number
disabledAccount: boolean
}
sessions: {
sessionId: string
method?: string
browser?: string
os?: string
deviceKind?: string
ip?: string
country?: string
region?: string
city?: string
createdAt?: number
lastSeenAt?: number
reachesOrg: boolean
}[]
keys: {
keyId: string
name: string
kind: "api" | "mcp" | "agent"
scopes: string[]
lastUsedAt?: number
expiresAt?: number
createdAt?: number
machine: boolean
}[]
apps: string[]
signIns: {
eventId: string
orgId: string
action: string
actor: {
type: "user" | "key" | "device" | "system"
id: string
label?: string
}
target: {
type: string
id: string
label?: string
}
metadata?: {
[key: string]: unknown
}
ip?: string
userAgent?: string
createdAt: number
}[]
}Errors
| Status | Message |
|---|---|
400 | Guests can be developers or viewers. |
400 | Only guests have an access end date. |
404 | Organization not found |
404 | Not a member of this organization |
409 | An organization needs at least one other active owner first. |
POST /v1/orgs/:orgId/tenant/users/:userId/block
Blocks sign-in to this org: no new tokens; current ones stop at the API and MCP within 30 seconds.
Auth: user access token or platform agent key · Scope: tenant:write
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:userId | A member's user id (usr_…). |
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
reason | string | No | up to 200 characters; trimmed |
Response 200
{
user: {
userId: string
email?: string
name?: string
role: "owner" | "admin" | "developer" | "viewer"
effectiveRole: "owner" | "admin" | "developer" | "viewer"
title?: string
department?: string
status: "active" | "blocked"
blockedAt?: number
guest: boolean
guestExpiresAt?: number
joinedAt?: number
lastSignInAt?: number
lastSignInMethod?: string
passkeys: number
textCode: boolean
authenticator: boolean
mfa: boolean
groups: {
teamId: string
name: string
role: "owner" | "member"
}[]
customRoleIds: string[]
tokensValidAfter?: number
disabledAccount: boolean
}
sessions: {
sessionId: string
method?: string
browser?: string
os?: string
deviceKind?: string
ip?: string
country?: string
region?: string
city?: string
createdAt?: number
lastSeenAt?: number
reachesOrg: boolean
}[]
keys: {
keyId: string
name: string
kind: "api" | "mcp" | "agent"
scopes: string[]
lastUsedAt?: number
expiresAt?: number
createdAt?: number
machine: boolean
}[]
apps: string[]
signIns: {
eventId: string
orgId: string
action: string
actor: {
type: "user" | "key" | "device" | "system"
id: string
label?: string
}
target: {
type: string
id: string
label?: string
}
metadata?: {
[key: string]: unknown
}
ip?: string
userAgent?: string
createdAt: number
}[]
}Errors
| Status | Message |
|---|---|
400 | You can't do that to yourself. |
404 | Not a member of this organization |
409 | An organization needs at least one other active owner first. |
POST /v1/orgs/:orgId/tenant/users/:userId/unblock
Unblocks sign-in; the person signs in again to reach the org.
Auth: user access token or platform agent key · Scope: tenant:write
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:userId | A member's user id (usr_…). |
Response 200
{
user: {
userId: string
email?: string
name?: string
role: "owner" | "admin" | "developer" | "viewer"
effectiveRole: "owner" | "admin" | "developer" | "viewer"
title?: string
department?: string
status: "active" | "blocked"
blockedAt?: number
guest: boolean
guestExpiresAt?: number
joinedAt?: number
lastSignInAt?: number
lastSignInMethod?: string
passkeys: number
textCode: boolean
authenticator: boolean
mfa: boolean
groups: {
teamId: string
name: string
role: "owner" | "member"
}[]
customRoleIds: string[]
tokensValidAfter?: number
disabledAccount: boolean
}
sessions: {
sessionId: string
method?: string
browser?: string
os?: string
deviceKind?: string
ip?: string
country?: string
region?: string
city?: string
createdAt?: number
lastSeenAt?: number
reachesOrg: boolean
}[]
keys: {
keyId: string
name: string
kind: "api" | "mcp" | "agent"
scopes: string[]
lastUsedAt?: number
expiresAt?: number
createdAt?: number
machine: boolean
}[]
apps: string[]
signIns: {
eventId: string
orgId: string
action: string
actor: {
type: "user" | "key" | "device" | "system"
id: string
label?: string
}
target: {
type: string
id: string
label?: string
}
metadata?: {
[key: string]: unknown
}
ip?: string
userAgent?: string
createdAt: number
}[]
}Errors
| Status | Message |
|---|---|
400 | You can't do that to yourself. |
404 | Not a member of this organization |
POST /v1/orgs/:orgId/tenant/users/:userId/revoke-sessions
Ends the person's sessions for this org (they sign in again) and disconnects their MCP clients here; keys also revokes keys they created here.
Auth: user access token or platform agent key · Scope: tenant:write
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:userId | A member's user id (usr_…). |
Request body
| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
keys | boolean | No | false |
Response 200
{
revoked: {
clients: number
keys: number
}
}Errors
| Status | Message |
|---|---|
400 | You can't do that to yourself. |
404 | Not a member of this organization |
DELETE /v1/orgs/:orgId/tenant/users/:userId
Removes the member; restorable with their role, attributes, groups and app assignments for 30 days.
Auth: user access token or platform agent key · Scope: tenant:write
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:userId | A member's user id (usr_…). |
Response 204 with no body.
Errors
| Status | Message |
|---|---|
400 | You can't do that to yourself. |
404 | Not a member of this organization |
409 | An organization needs at least one other active owner first. |
POST /v1/orgs/:orgId/tenant/removed/:userId/restore
Restores a removed member.
Auth: user access token or platform agent key · Scope: tenant:write
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:userId | A member's user id (usr_…). |
Response 200
{
user: {
userId: string
email?: string
name?: string
role: "owner" | "admin" | "developer" | "viewer"
effectiveRole: "owner" | "admin" | "developer" | "viewer"
title?: string
department?: string
status: "active" | "blocked"
blockedAt?: number
guest: boolean
guestExpiresAt?: number
joinedAt?: number
lastSignInAt?: number
lastSignInMethod?: string
passkeys: number
textCode: boolean
authenticator: boolean
mfa: boolean
groups: {
teamId: string
name: string
role: "owner" | "member"
}[]
customRoleIds: string[]
tokensValidAfter?: number
disabledAccount: boolean
}
sessions: {
sessionId: string
method?: string
browser?: string
os?: string
deviceKind?: string
ip?: string
country?: string
region?: string
city?: string
createdAt?: number
lastSeenAt?: number
reachesOrg: boolean
}[]
keys: {
keyId: string
name: string
kind: "api" | "mcp" | "agent"
scopes: string[]
lastUsedAt?: number
expiresAt?: number
createdAt?: number
machine: boolean
}[]
apps: string[]
signIns: {
eventId: string
orgId: string
action: string
actor: {
type: "user" | "key" | "device" | "system"
id: string
label?: string
}
target: {
type: string
id: string
label?: string
}
metadata?: {
[key: string]: unknown
}
ip?: string
userAgent?: string
createdAt: number
}[]
}Errors
| Status | Message |
|---|---|
404 | Nothing to restore |
404 | Organization not found |
404 | The account no longer exists. |
404 | Not a member of this organization |
409 | They're a member again already. |
DELETE /v1/orgs/:orgId/tenant/removed/:userId
Forgets a removed member now instead of after 30 days.
Auth: user access token or platform agent key · Scope: tenant:write
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:userId | A member's user id (usr_…). |
Response 204 with no body.
Errors
| Status | Message |
|---|---|
404 | Nothing to restore |
POST /v1/orgs/:orgId/tenant/invites
Invites one person by email (replacing a pending invite to the same address); the link is mailed and returned.
Auth: user access token or platform agent key · Scope: tenant:write
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
Request body
| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
email | string | Yes | up to 254 characters; email address | |
role | "owner" | "admin" | "developer" | "viewer" | No | "developer" | |
title | any JSON | No | ||
department | any JSON | No | ||
guest | boolean | No | ||
guestDays | integer | No | ||
teamIds | string[] | No | up to 20 items; each up to 64 characters | |
days | integer | No | 1–30 |
Response 201
{
invite: {
inviteId: string
email: string
role: "owner" | "admin" | "developer" | "viewer"
expiresAt: number
link: string
delivered: boolean
}
}Errors
| Status | Message |
|---|---|
400 | Unknown role. |
400 | Guests can be developers or viewers. |
400 | Unknown group. |
404 | Organization not found |
409 | … is already a member. |
POST /v1/orgs/:orgId/tenant/invites/bulk
Invites up to 200 people: csv (email[,role[,title[,department]]], header optional) or rows; defaults apply to each. Rows that fail are reported and the rest are sent.
Auth: user access token or platform agent key · Scope: tenant:write
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
Request body
| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
csv | string | No | up to 200,000 characters | |
rows | object[] | No | up to 200 items | |
rows[].email | string | Yes | up to 254 characters; email address | |
rows[].role | "owner" | "admin" | "developer" | "viewer" | No | "developer" | |
rows[].title | any JSON | No | ||
rows[].department | any JSON | No | ||
rows[].guest | boolean | No | ||
rows[].guestDays | integer | No | ||
rows[].teamIds | string[] | No | up to 20 items; each up to 64 characters | |
rows[].days | integer | No | 1–30 | |
defaults | object | No | ||
defaults.role | "owner" | "admin" | "developer" | "viewer" | No | "developer" | |
defaults.title | any JSON | No | ||
defaults.department | any JSON | No | ||
defaults.guest | boolean | No | ||
defaults.guestDays | integer | No | ||
defaults.teamIds | string[] | No | up to 20 items; each up to 64 characters | |
defaults.days | integer | No | 1–30 |
Also checked: Send csv or rows.
Response 200
{
results: {
email: string
ok: true
inviteId: string
delivered: boolean
link: string
} | {
email: string
ok: false
error: string
}[]
errors: {
line: number
message: string
}[]
}Errors
| Status | Message |
|---|---|
400 | Up to 200 invites at once. |
400 | Unknown role. |
400 | Guests can be developers or viewers. |
400 | Unknown group. |
404 | Organization not found |
409 | … is already a member. |
POST /v1/orgs/:orgId/tenant/invites/:inviteId/resend
A new link for a pending invite (the old one stops working), mailed again.
Auth: user access token or platform agent key · Scope: tenant:write
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:inviteId | Invite id (inv_…). |
Response 200
{
invite: {
inviteId: string
email: string
role: "owner" | "admin" | "developer" | "viewer"
expiresAt: number
link: string
delivered: boolean
}
}Errors
| Status | Message |
|---|---|
400 | Unknown role. |
400 | Guests can be developers or viewers. |
400 | Unknown group. |
404 | Invite not found |
404 | Organization not found |
409 | … is already a member. |
DELETE /v1/orgs/:orgId/tenant/invites/:inviteId
Revokes a pending invite (the link stops working).
Auth: user access token or platform agent key · Scope: tenant:write
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:inviteId | Invite id (inv_…). |
Response 204 with no body.
Errors
| Status | Message |
|---|---|
404 | Invite not found |
GET /v1/orgs/:orgId/tenant
Properties, counts, the sign-in policy and recommendations computed from the org's data.
Auth: user access token or platform agent key · Scope: tenant:read
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
Response 200
{
org: {
plan?: {
planId: string
name: string
}
createdAt?: number
contactEmail?: string
logoUri?: string
orgId: string
slug: string
name: string
kind: "platform" | "customer"
}
counts: {
members: number
active: number
guests: number
blocked: number
admins: number
mfa: number
passkeys: number
groups: number
customRoles: number
apps: number
mcpClients: number
keys: number
invites: number
removed: number
}
policy: {
strength: "any" | "mfa" | "passkey"
methods: ("passkey" | "password")[]
graceUntil?: number
sessionHours?: number
}
recommendations: {
id: string
severity: "medium" | "low" | "high"
title: string
detail: string
count?: number
href: string
}[]
}Errors
| Status | Message |
|---|---|
404 | Organization not found |
PATCH /v1/orgs/:orgId/tenant
Name, logo (https) and contact address.
Auth: user access token or platform agent key · Scope: tenant:write
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
name | string | No | 1–64 characters; trimmed |
logoUri | string | "" | No | up to 512 characters; trimmed; can be null |
contactEmail | string | "" | No | up to 254 characters; email address; can be null |
Response 200
{
org: {
plan?: {
planId: string
name: string
}
createdAt?: number
contactEmail?: string
logoUri?: string
orgId: string
slug: string
name: string
kind: "platform" | "customer"
}
counts: {
members: number
active: number
guests: number
blocked: number
admins: number
mfa: number
passkeys: number
groups: number
customRoles: number
apps: number
mcpClients: number
keys: number
invites: number
removed: number
}
policy: {
strength: "any" | "mfa" | "passkey"
methods: ("passkey" | "password")[]
graceUntil?: number
sessionHours?: number
}
recommendations: {
id: string
severity: "medium" | "low" | "high"
title: string
detail: string
count?: number
href: string
}[]
}Errors
| Status | Message |
|---|---|
404 | Organization not found |
GET /v1/orgs/:orgId/tenant/grantables
Serverless App Services and repositories a group can be given write access to.
Auth: user access token or platform agent key · Scope: tenant:read
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
Response 200
{
grantables: {
type: "project"
id: string
name: string
} | {
type: "repository"
id: string
name: string
}[]
}