Skip to main content

Tenant endpoints

Endpoints for tenant lifecycle and tenant-admin membership.

EndpointAuthStatus
POST /api/v1/tenantssuperadminv0
GET /api/v1/tenantsauthenticated principalv0
GET /api/v1/tenants/{tenant}tenant member or higherv0
PUT /api/v1/tenants/{tenant}/admins/{user_id}tenant admindeferred
DELETE /api/v1/tenants/{tenant}/admins/{user_id}tenant admindeferred

See conventions for the auth header, error envelope, pagination, and rate limits — every endpoint here inherits them.


POST /api/v1/tenants

Create a new tenant. An exd installation can contain multiple tenants. Each tenant maps to either a configured SSO provider or a verified email domain.

Auth required: superadmin. See access-controltenant.create.

Request body (SSO tenant)

{
"slug": "acme",
"display_name": "Acme Corp",
"login_mode": "sso",
"sso_provider": "acme-oidc",
"initial_admin_user_ids": ["usr_01HV5Z9R4Y0XJ7A2W8WJ9R7S3A"]
}

Request body (email-domain tenant)

{
"slug": "acme",
"display_name": "Acme Corp",
"login_mode": "email_domain",
"email_domain": "acme.example"
}

Fields

FieldTypeRequiredDescription
slugstringyesTenant slug. Pattern [a-z][a-z0-9-]*, max 63 chars. Globally unique across the installation. Immutable.
display_namestringnoHuman-readable name. Defaults to the slug.
login_modestringyessso or email_domain.
sso_providerstringwhen login_mode = "sso"Identifier for a configured OIDC or SAML provider.
email_domainstringwhen login_mode = "email_domain"Verified domain used to admit email-login users.
initial_admin_user_idsarraynoInitial tenant admins for SSO tenants. Ignored for email-domain tenants (every admitted user is a tenant admin).

Response: 201 Created

{
"tenant": {
"slug": "acme",
"display_name": "Acme Corp",
"login_mode": "sso",
"sso_provider": "acme-oidc",
"email_domain": null,
"created_at": "2026-04-25T09:00:00Z",
"namespace_count": 0
},
"request_id": "01HV5XK1EFQT8N3JRDCP7MW04A"
}

GET /api/v1/tenants

List tenants visible to the authenticated principal.

Auth required: authenticated user, tenant-admin, or superadmin. List endpoints filter to the principal's visible scope.

Query parameters

Supports limit + after (pagination).

Response: 200 OK

{
"tenants": [
{
"slug": "acme",
"display_name": "Acme Corp",
"login_mode": "sso",
"sso_provider": "acme-oidc",
"email_domain": null,
"created_at": "2026-04-25T09:00:00Z",
"namespace_count": 2,
"current_user_roles": ["tenant_admin"]
}
],
"next_cursor": null,
"request_id": "01HV5XK2EFQT8N3JRDCP7MW04B"
}

GET /api/v1/tenants/{tenant}

Retrieve metadata for a single tenant.

Auth required: tenant member, tenant-admin bound to this tenant, or superadmin. Permission: tenant.read.

Response: 200 OK

Same tenant object as the create response, plus the requester's roles.


PUT /api/v1/tenants/{tenant}/admins/{user_id}

Deferred. Not implemented in v0.

Grant tenant-admin access to a user. Valid for SSO tenants. Email-domain tenants do NOT need explicit tenant-admin grants — every verified user in the tenant is a tenant admin.

Auth required: tenant_admin for this tenant or superadmin. Permission: tenant.admin.manage.


DELETE /api/v1/tenants/{tenant}/admins/{user_id}

Deferred. Not implemented in v0.

Revoke explicit tenant-admin access from a user in an SSO tenant.

Auth required: tenant_admin for this tenant or superadmin. Permission: tenant.admin.manage.


See also