Skip to main content

Organization Units

Organization units (OUs) let you organize users and groups to match your organization's structure. You can use OUs to model departments, teams, regions, or even separate tenants.

Root organization units are the top-level nodes that represent major segments of your organization. Child organization units are nested under root OUs. Together they form a tree-like structure that reflects your organizational hierarchy.

OUs can be nested to any depth. Common patterns include:

engineering/
frontend/
backend/
platform/
sales/
hr/

Organization Units and User Types

All users belong to an OU and each user also has a user type. A user type defines:

  • the attributes in the user's profile.

  • validation rules for those attributes.

  • whether users can self-register.

ThunderID ships with two default organization units, each with a predefined user type.

Organization UnitDefault User TypePurpose
DefaultPersonAdministrator-managed users
CustomersCustomerSelf-registering end users

Each user type belongs to a single OU and inherited by its child OUs. This means, a user of a certain type can only exist in that OU or its descendants. For example, the default Customers OU has a Customer user type. A user of Customer type can only exist in the Customers OU or its descendants.

Organization Handles

Every OU has a handle, a short, URL-safe identifier used to reference the OU in the hierarchy. Handles must be unique within the same parent.

ThunderID's two default OUs have fixed handles:

Organization UnitHandle
Defaultdefault
Customerscustomers

Handles compose into hierarchical paths by joining each OU's handle with a forward slash /. For example:

PathDescription
engineeringThe root OU with handle engineering
engineering/frontendThe frontend OU nested under engineering
engineering/frontend/uiThe ui OU nested under engineering/frontend

Hierarchical paths let you navigate directly to any OU in the tree without knowing its UUID, which is useful in API calls and CLI operations.

note

Handles must be unique within the same parent. Two sibling OUs cannot share the same handle. Handles at different levels of the hierarchy can be the same, only siblings conflict.

Create an Organization Unit

  1. Navigate to Organization Units in the ThunderID Console.
    • To create a root OU, click Add Root Organization Unit.
    • To create a child OU, expand the parent OU and click Add Child Organization Unit.
  2. Enter a Name - the human-readable display name for the OU.
  3. Enter a Handle - a short, URL-safe identifier. Use lowercase letters, numbers, and hyphens (for example, engineering or frontend-team).
  4. Optionally enter a Description.
  5. The Parent Organization Unit field shows where the OU will be created. For root OUs this displays Root Organization Unit; for child OUs it shows the selected parent.
  6. Click Create.

When creating an OU through the API, you can also provide the following optional branding and policy fields:

FieldDescription
themeIdIdentifier of the theme to apply to the OU.
layoutIdIdentifier of the layout to apply to the OU.
logoUrlURL of the logo to display for the OU.
tosUriURL of the Terms of Service page.
policyUriURL of the Privacy Policy page.
cookiePolicyUriURL of the Cookie Policy page.

Example: create an OU with branding:

curl -kL -X POST "https://localhost:8090/organization-units" \
-H 'Authorization: Bearer <access-token>' \
-H 'Content-Type: application/json' \
-d '{
"name": "Engineering",
"handle": "engineering",
"parent": null,
"logoUrl": "https://example.com/logo.png",
"tosUri": "https://example.com/tos"
}'

View an Organization Unit

Navigate to Organization Units in the ThunderID Console to see all OUs. Click the three-dot menu on any OU and select Edit to view its details:

  • Details - name, handle, description, and parent OU.
  • Child Organization Units - nested OUs directly under this OU.
  • Users - all users belonging to this OU.
  • Groups - all groups belonging to this OU.

When using the Organization Unit APIs, each OU response also includes system metadata:

  • isReadOnly - indicates whether the OU is immutable (for example, because it is defined declaratively and cannot be modified at runtime).
  • createdAt - UTC timestamp when the OU was created.
  • updatedAt - UTC timestamp when the OU was last updated.

To retrieve an OU by its ID:

curl -kL "https://localhost:8090/organization-units/{id}" \
-H 'Authorization: Bearer <access-token>'

To retrieve an OU by its hierarchical handle path:

curl -kL "https://localhost:8090/organization-units/tree/{path}" \
-H 'Authorization: Bearer <access-token>'

Update an Organization Unit

  1. Navigate to Organization Units in the ThunderID Console.
  2. Click the three-dot menu on the OU you want to update and select Edit.
  3. Update the Name, Handle, or Description as needed.
  4. Click Save.

To update an OU using the API by its ID:

curl -kL -X PUT "https://localhost:8090/organization-units/{id}" \
-H 'Authorization: Bearer <access-token>' \
-H 'Content-Type: application/json' \
-d '{"name": "Engineering Team", "handle": "engineering", "parent": null}'

To update by hierarchical path:

curl -kL -X PUT "https://localhost:8090/organization-units/tree/{path}" \
-H 'Authorization: Bearer <access-token>' \
-H 'Content-Type: application/json' \
-d '{"name": "Engineering Team", "handle": "engineering", "parent": null}'

The request body accepts the same fields as the create request, including the optional branding and policy fields.

List and Filter Organization Units

The Organization Unit API returns paginated results on all list endpoints. Append a filter query parameter to narrow results.

Supported Endpoints

Filtering applies to the following list endpoints:

EndpointDescription
GET /organization-unitsList all root-level organization units
GET /organization-units/{id}/ousList child organization units by parent ID
GET /organization-units/tree/{path}/ousList child organization units by hierarchical path

Filter Expression Syntax

A filter expression can contain one or more conditions joined by AND or OR:

attribute operator "value" [AND|OR attribute operator "value" ...]
  • attribute: the OU field to filter on.
  • operator: the comparison operator (eq, gt, or lt).
  • value: the value to compare against. Enclose string values in double quotes.
  • AND / OR: logical connectors between conditions. AND has higher precedence than OR, matching standard SQL behaviour.

Supported Operators

OperatorMeaning
eqEquals (case-insensitive for text attributes)
gtGreater than
ltLess than

Filterable Attributes

AttributeTypeNotes
nametextCase-insensitive equality
handletextCase-insensitive equality
descriptiontextCase-insensitive equality
createdAttimestampCompared lexicographically; use ISO 8601 format
updatedAttimestampCompared lexicographically; use ISO 8601 format

Filter Examples

Filter by exact name:

curl -kL "https://localhost:8090/organization-units?filter=name%20eq%20%22Engineering%22" \
-H 'Authorization: Bearer <access-token>'

Filter with AND, both conditions must match:

curl -kL "https://localhost:8090/organization-units?filter=name%20eq%20%22Engineering%22%20AND%20handle%20eq%20%22engineering%22" \
-H 'Authorization: Bearer <access-token>'

Filter with OR, either condition may match:

curl -kL "https://localhost:8090/organization-units?filter=name%20eq%20%22Engineering%22%20OR%20name%20eq%20%22Sales%22" \
-H 'Authorization: Bearer <access-token>'

Filter children by timestamp range:

curl -kL "https://localhost:8090/organization-units/<parent-id>/ous?filter=createdAt%20gt%20%222024-01-01T00:00:00Z%22" \
-H 'Authorization: Bearer <access-token>'

Combine filter with pagination:

curl -kL "https://localhost:8090/organization-units?filter=name%20eq%20%22Engineering%22&limit=10&offset=0" \
-H 'Authorization: Bearer <access-token>'

Filter Error Responses

Error CodeHTTP StatusCause
OU-1014400The filter expression is malformed, uses an unsupported connector, or references an unsupported attribute
OU-1013400The result count exceeds the limit supported in the current store configuration

List Users in an Organization Unit

Using Organization Unit ID

curl -kL "https://localhost:8090/organization-units/{id}/users" \
-H 'Authorization: Bearer <access-token>'

Using Hierarchical Path

curl -kL "https://localhost:8090/organization-units/tree/{path}/users" \
-H 'Authorization: Bearer <access-token>'

Append include=display to include a human-readable display name for each user:

curl -kL "https://localhost:8090/organization-units/{id}/users?include=display" \
-H 'Authorization: Bearer <access-token>'

The response includes pagination fields (totalResults, startIndex, count) and a users array. Each user entry contains an id and type, and optionally a display name when include=display is requested.

List Groups in an Organization Unit

Using Organization Unit ID

curl -kL "https://localhost:8090/organization-units/{id}/groups" \
-H 'Authorization: Bearer <access-token>'

Using Hierarchical Path

curl -kL "https://localhost:8090/organization-units/tree/{path}/groups" \
-H 'Authorization: Bearer <access-token>'

The response includes pagination fields and a groups array. Each group entry contains an id and name.

Delete an Organization Unit

  1. Open the OU from the Organization Units list.
  2. Click Delete and confirm.
warning

Deletion fails if the OU still contains users, groups, or child OUs. Delete or reassign all contained resources before deleting the OU.

To delete an OU using the API by its ID:

curl -kL -X DELETE "https://localhost:8090/organization-units/{id}" \
-H 'Authorization: Bearer <access-token>'

To delete by hierarchical path:

curl -kL -X DELETE "https://localhost:8090/organization-units/tree/{path}" \
-H 'Authorization: Bearer <access-token>'
  • User Types - User types are scoped to an organization unit
  • Users - Each user belongs to an organization unit
  • Groups - Each group belongs to an organization unit

Explore with AI

ThunderID LogoThunderID Logo

Product

DocsAPIsSDKs
© Copyright Linux Foundation Europe.For web site terms of use, trademark policy and other project policies please see https://linuxfoundation.eu/en/policies.