Tenants And Organizations
Create and maintain tenants, organizations, commercial tiers, and organization metadata.
Tenants And Organizations
Use these routes with a PLATFORM_ADMIN token.
Tenant Lifecycle
| Action | Route |
|---|---|
| List tenants | GET /admin/api/v1/tenants |
| Create tenant | POST /admin/api/v1/tenants |
| Read tenant | GET /admin/api/v1/tenants/{tenant_id} |
| Update tenant | PATCH /admin/api/v1/tenants/{tenant_id} |
| Delete tenant | DELETE /admin/api/v1/tenants/{tenant_id} |
Create tenants with a stable slug, display name, optional
instance_fingerprint, and optional branding.
{
"name": "Example Tenant",
"slug": "example-tenant",
"instance_fingerprint": "sha256:example"
}
Tenant deletion is a backend soft delete. Treat it as an operationally sensitive action and keep the audit record attached to the change.
Organization Lifecycle
| Action | Route |
|---|---|
| List organizations in a tenant | GET /admin/api/v1/tenants/{tenant_id}/organizations |
| Create organization in a tenant | POST /admin/api/v1/tenants/{tenant_id}/organizations |
| Read organization | GET /admin/api/v1/tenants/{tenant_id}/organizations/{organization_id} |
| Update organization | PATCH /admin/api/v1/tenants/{tenant_id}/organizations/{organization_id} |
| Delete organization | DELETE /admin/api/v1/tenants/{tenant_id}/organizations/{organization_id} |
| Canonical create alias | POST /admin/api/v1/organizations |
The canonical create alias accepts tenant_id in the JSON body and is useful
for onboarding tools that do not use tenant-scoped URLs.
{
"tenant_id": "11111111-1111-4111-8111-111111111111",
"name": "Example Client",
"slug": "example-client",
"commercial_tier": "CLIENT",
"email_domains": ["example.com"]
}
Commercial Tree
The backend stores a variable-depth commercial tree. Use:
| Field | Purpose |
|---|---|
is_self | Marks the operator organization for the instance. |
parent_organization_id | Links a reseller/client to its direct provider. |
commercial_tier | Descriptive tier such as DISTRIBUTEUR, REVENDEUR, or CLIENT. |
The tier is billing metadata. It does not create a new application role.
Organization Provisioning
When the Keycloak Admin provisioner is configured, organization creation calls
Keycloak and returns a provisioning status. If Keycloak is unavailable, the
backend returns a structured SERVICE_UNAVAILABLE error instead of silently
creating a partial identity state.
Operational Checks
After creating an organization:
| Check | Expected result |
|---|---|
Organization appears in GET /admin/api/v1/tenants/{tenant_id}/organizations. | Present, not deleted. |
| Audit log contains the admin action where applicable. | Entry hash populated. |
| Keycloak organization metadata exists when the provisioner is enabled. | External ID stored or provisioner status returned. |
| Branding and IdP URLs pass the outbound URL policy. | No private, localhost, link-local, or credential-bearing URLs unless explicitly allowed. |