Skip to main content
Version: 0.6.0 (Previous)

🏢 Organization Service

Testing Status

The Organization Service provides a complete REST API for managing organization entities with CRUD operations. It's built using the Nodeblocks functional composition approach and integrates seamlessly with MongoDB.


🚀 Quickstart​

import express from 'express';
import { middlewares, services, drivers } from '@nodeblocks/backend-sdk';

const { nodeBlocksErrorMiddleware } = middlewares;
const { organizationService } = services;
const { getMongoClient, createFileStorageDriver } = drivers;

const client = getMongoClient('mongodb://localhost:27017', 'dev');

// Optional but recommended for logo normalization and upload URLs:
// Ensure GOOGLE_APPLICATION_CREDENTIALS points to your GCP service account JSON.
const fileStorageDriver = createFileStorageDriver({
projectId: process.env.GCP_PROJECT_ID!,
bucketName: process.env.GCP_BUCKET_NAME!,
});

express()
.use(
organizationService(
{
organizations: client.collection('organizations'),
identities: client.collection('identities'),
},
{
authSecrets: {
authEncSecret: 'your-encryption-secret',
authSignSecret: 'your-signing-secret',
},
identity: {
typeIds: {
admin: '100',
guest: '000',
regular: '001',
},
},
organization: {
roles: {
admin: '100',
member: '001',
owner: '010',
},
},
},
{ fileStorageDriver }
)
)
.use(nodeBlocksErrorMiddleware())
.listen(8089, () => console.log('Server running'));

📋 Endpoint Summary​

Basic CRUD Operations​

MethodPathDescriptionAuthorization
POST/organizationsCreate a new organizationBearer token required (admin only)
GET/organizations/:organizationIdRetrieve an organization by IDBearer token required (admin/organization access)
GET/organizationsList/filter organizationsBearer token required (admin only)
PATCH/organizations/:organizationIdUpdate an organizationBearer token required (admin/owner access)
DELETE/organizations/:organizationIdDelete an organizationBearer token required (admin/owner access)

File Upload Operations​

MethodPathDescriptionAuthorization
GET/organizations/:organizationId/logo-upload-urlGet signed URL to upload organization logoBearer token required (admin/owner access)

Hierarchy Operations​

MethodPathDescriptionAuthorization
GET/organizations/:organizationId/descendantsList descendant organizations (optional depth)Bearer token required (admin/owner access)

User Management Operations​

MethodPathDescriptionAuthorization
GET/organizations/:organizationId/membersList members in an organizationBearer token required (admin/organization access)
PATCH/organizations/:organizationId/membersAdd/update members in an organizationBearer token required (admin/organization access)
DELETE/organizations/:organizationId/members/:identityIdRemove member from organizationBearer token required (admin/organization access)
GET/organizations/:organizationId/members/:identityId/roleGet member's role in organizationBearer token required (admin/organization access)
GET/organizations/members/:identityIdFind organizations for a memberBearer token required (admin/self access)

🗄️ Entity Schema​

The organization entity combines base fields (auto-generated) with organization-specific data:

{
"id": "string",
"createdAt": "string (datetime)",
"updatedAt": "string (datetime)",
"name": "string",
"description": "string",
"contact_email": "string",
"contact_phone": "string",
"address": "object",
"logo": "object or null",
"users": "array"
}

Field Details​

FieldTypeAuto-GeneratedRequiredDescription
idstring✅✅Unique identifier (UUID)
createdAtdatetime✅✅Creation timestamp
updatedAtdatetime✅✅Last modification timestamp
namestring❌✅Organization name (minimum 1 character)
descriptionstring❌✅Organization description
contact_emailstring❌✅Contact email address (email format)
contact_phonestring❌❌Contact phone number
addressobject❌❌Address object (free-form JSON)
logoobject or null❌❌Organization logo. Responses: { type, url }; Requests: { objectId, type }
usersarray❌❌Array of identities with roles ({id: string, role: string})

📝 Note: Auto-generated fields are set by the service and should not be included in create/update requests.


🔐 Authentication Headers​

For all endpoints, include the following headers:

Authorization: Bearer <access_token>
x-nb-fingerprint: <device_fingerprint>

⚠️ Important: The x-nb-fingerprint header is required for all authenticated requests if fingerprint was specified during authorization. Without it, requests will return 401 Unauthorized.


🔧 API Endpoints​

1. Create Organization​

Creates a new organization with the provided information.

Request:

  • Method: POST
  • Path: /organizations
  • Headers:
    • Content-Type: application/json
    • Authorization: Bearer <token>
    • x-nb-fingerprint: <device-fingerprint>
  • Authorization: Bearer token required (admin only)

Request Body (top-level):

FieldTypeRequiredDescription
organizationobject✅Organization payload object (see below)
ownerIdstring✅Identity ID of the organization owner
parentIdstring❌Optional parent organization ID

Organization object fields:

FieldTypeRequiredDescription
namestring✅Organization name (minimum 1 character)
descriptionstring✅Organization description
contact_emailstring✅Contact email address (email format)
contact_phonestring❌Contact phone number
addressobject❌Address object (free-form JSON)

Response Body:

FieldTypeDescription
idstringUnique organization identifier
namestringOrganization name
descriptionstringOrganization description
contact_emailstringContact email address
contact_phonestringContact phone number
addressobjectAddress object (free-form JSON)
usersarrayArray of objects containing user ID and role: {id: string, role: string}
createdAtstringCreation timestamp
updatedAtstringLast update timestamp

Validation:

  • Schema Validation: Enforced automatically (top-level organization and ownerId required; inside organization, name, description, and contact_email required; additionalProperties: false)
  • Route Validators:
    • Require authenticated request (bearer token)
    • Require admin role

Example Request:

curl -X POST {{host}}/organizations \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <access-token>" \
-d '{
"organization": {
"name": "ACME Corp",
"description": "Leading provider of rocket skates",
"contact_email": "info@acme.test",
"contact_phone": "+1-202-555-0199",
"address": {
"street": "1 Road Runner Way",
"city": "Desert",
"country": "US"
}
},
"ownerId": "identity-123",
"parentId": "org-parent-001"
}'

Success Response:

HTTP/1.1 200 OK
Content-Type: application/json

{
"id": "7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2",
"name": "ACME Corp",
"description": "Leading provider of rocket skates",
"contact_email": "info@acme.test",
"contact_phone": "+1-202-555-0199",
"address": {
"street": "1 Road Runner Way",
"city": "Desert",
"country": "US"
},
"users": [
{
"id": "owner-id",
"role": "owner"
}
],
"createdAt": "2024-05-28T09:41:22.552Z",
"updatedAt": "2024-05-28T09:41:22.552Z"
}

Error Responses:

When request body is missing required fields:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
"error": {
"message": "Validation Error",
"data": [
"request body must have required property 'name'",
"request body must have required property 'description'",
"request body must have required property 'contact_email'",
"request body must have required property 'ownerId'"
]
}
}

When no authorization token is provided:

HTTP/1.1 401 Unauthorized
Content-Type: application/json

{
"error": {
"message": "token could not be verified"
}
}

When database insert operation fails to return an inserted ID:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
"error": {
"message": "Failed to create organization"
}
}

When an unexpected error occurs (database connection issues, etc.):

HTTP/1.1 500 Internal Server Error
Content-Type: application/json

{
"error": {
"message": "Failed to create organization"
}
}

2. Get Organization by ID​

Retrieves a specific organization by their unique ID.

Request:

  • Method: GET
  • Path: /organizations/:organizationId
  • Headers: Authorization: Bearer <access-token>
  • Authorization: Bearer token required (admin/organization access)

URL Parameters:

ParameterTypeRequiredDescription
organizationIdstring✅Unique organization identifier

Response Body:

FieldTypeDescription
idstringUnique organization identifier
namestringOrganization name
descriptionstringOrganization description
contact_emailstringContact email address
contact_phonestringContact phone number
addressobjectAddress object (free-form JSON)
usersarrayArray of objects containing user ID and role: {id: string, role: string}
createdAtstringCreation timestamp
updatedAtstringLast update timestamp

Validation:

  • Schema Validation: None
  • Route Validators:
    • Require authenticated request (bearer token)
    • Require admin role or organization membership (owner/admin/member)

Example Request:

curl {{host}}/organizations/7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2

Success Response:

HTTP/1.1 200 OK
Content-Type: application/json

{
"id": "7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2",
"name": "ACME Corp",
"description": "Leading provider of rocket skates",
"contact_email": "info@acme.test",
"contact_phone": "+1-202-555-0199",
"address": {
"street": "1 Road Runner Way",
"city": "Desert",
"country": "US"
},
"users": [
{
"id": "owner-id",
"role": "owner"
}
],
"createdAt": "2024-05-28T09:41:22.552Z",
"updatedAt": "2024-05-28T09:41:22.552Z"
}

Error Responses:

When no organization exists with the provided ID:

HTTP/1.1 404 Not Found
Content-Type: application/json

{
"error": {
"message": "Organization not found"
}
}

When an unexpected error occurs (database connection issues, etc.):

HTTP/1.1 500 Internal Server Error
Content-Type: application/json

{
"error": {
"message": "Failed to get organization"
}
}

3. List Organizations​

Retrieves a list of organizations with optional filtering and pagination.

Request:

  • Method: GET
  • Path: /organizations
  • Authorization: Bearer token required (admin only)

Query Parameters:

ParameterTypeRequiredDescription
namestring❌Filter organizations by name (minimum 1 character)
descriptionstring❌Filter organizations by description
contact_emailstring❌Filter organizations by contact email (email format)
contact_phonestring❌Filter organizations by contact phone
pagenumber❌Page number
limitnumber❌Items per page

Response Body:

FieldTypeDescription
idstringUnique organization identifier
namestringOrganization name
descriptionstringOrganization description
contact_emailstringContact email address
contact_phonestringContact phone number
addressobjectAddress object (free-form JSON)
usersarrayArray of objects containing user ID and role: {id: string, role: string}
createdAtstringCreation timestamp
updatedAtstringLast update timestamp

Validation:

  • Schema Validation: Query parameter validation for name (min length 1), contact_email (email format), contact_phone (string), description (string), and pagination parameters (integers with min/max constraints)
  • Route Validators:
    • Require authenticated request (bearer token)
    • Require admin role

Example Requests:

List all organizations:

curl {{host}}/organizations

Filter by name:

curl "{{host}}/organizations?name=ACME Corp"

Filter by contact email:

curl "{{host}}/organizations?contact_email=info@acme.test"

Filter by description:

curl "{{host}}/organizations?description=rocket skates"

Filter by contact phone:

curl "{{host}}/organizations?contact_phone=+1-202-555-0199"

Combine filters:

curl "{{host}}/organizations?name=ACME&contact_email=info@acme.test&page=1&limit=20"

Success Response:

HTTP/1.1 200 OK
Content-Type: application/json

[
{
"id": "7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2",
"name": "ACME Corp",
"description": "Leading provider of rocket skates",
"contact_email": "info@acme.test",
"contact_phone": "+1-202-555-0199",
"address": {
"street": "1 Road Runner Way",
"city": "Desert",
"country": "US"
},
"users": [
{
"id": "owner-id",
"role": "owner"
}
],
"createdAt": "2024-05-28T09:41:22.552Z",
"updatedAt": "2024-05-28T09:41:22.552Z"
},
{
"id": "8fec096b-1bc7-5bfe-c827-3600e8fe2790",
"name": "Wayne Enterprises",
"description": "Gotham's premier technology company",
"contact_email": "contact@wayneenterprises.com",
"users": [
{
"id": "owner-id",
"role": "owner"
}
],
"createdAt": "2024-05-29T10:15:33.441Z",
"updatedAt": "2024-05-29T10:15:33.441Z"
}
]

Error Responses:

When an unexpected error occurs (database connection issues, invalid filter syntax, etc.):

HTTP/1.1 500 Internal Server Error
Content-Type: application/json

{
"error": {
"message": "Failed to find organizations"
}
}

4. Update Organization​

Updates an existing organization with partial data.

Request:

  • Method: PATCH
  • Path: /organizations/:organizationId
  • Headers: Content-Type: application/json
  • Authorization: Bearer token required (admin/owner access)

URL Parameters:

ParameterTypeRequiredDescription
organizationIdstring✅Unique organization identifier

Response Body:

FieldTypeDescription
idstringUnique organization identifier
namestringUpdated organization name
descriptionstringUpdated organization description
contact_emailstringUpdated contact email address
contact_phonestringUpdated contact phone number
addressobjectUpdated address object (free-form JSON)
createdAtstringCreation timestamp
updatedAtstringLast update timestamp

Validation:

  • Schema Validation: Enforced automatically (partial updates, all fields optional)
  • Route Validators:
    • Require authenticated request (bearer token)
    • Require admin role or organization owner role

Example Request:

curl -X PATCH {{host}}/organizations/7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2 \
-H "Content-Type: application/json" \
-d '{"description": "Updated description for ACME Corp"}'

Success Response:

HTTP/1.1 200 OK
Content-Type: application/json

{
"id": "7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2",
"name": "ACME Corp",
"description": "Updated description for ACME Corp",
"contact_email": "info@acme.test",
"contact_phone": "+1-202-555-0199",
"address": {
"street": "1 Road Runner Way",
"city": "Desert",
"country": "US"
},
"users": [
{
"id": "owner-id",
"role": "owner"
}
],
"createdAt": "2024-05-28T09:41:22.552Z",
"updatedAt": "2024-05-28T14:22:15.789Z"
}

Error Responses:

When request body is missing or empty:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
"error": {
"message": "Request body is required"
}
}

When no organization exists with the provided ID:

HTTP/1.1 404 Not Found
Content-Type: application/json

{
"error": {
"message": "Organization not found"
}
}

When the update operation doesn't modify any data (no changes detected):

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
"error": {
"message": "Failed to update organization"
}
}

When an unexpected error occurs (database connection issues, etc.):

HTTP/1.1 500 Internal Server Error
Content-Type: application/json

{
"error": {
"message": "Failed to update organization"
}
}

5. Delete Organization​

Permanently deletes an organization from the system.

Request:

  • Method: DELETE
  • Path: /organizations/:organizationId
  • Authorization: Bearer token required (admin/owner access)

URL Parameters:

ParameterTypeRequiredDescription
organizationIdstring✅Unique organization identifier

Response Body:

FieldTypeDescription
No response body-Delete endpoint returns no response body on success

Validation:

  • Schema Validation: None
  • Route Validators:
    • Require authenticated request (bearer token)
    • Require admin role or organization owner role

Example Request:

curl -X DELETE {{host}}/organizations/7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2

Success Response:

HTTP/1.1 204 No Content

Error Responses:

When no organization exists with the provided ID:

HTTP/1.1 404 Not Found
Content-Type: application/json

{
"error": {
"message": "Organization not found"
}
}

When an unexpected error occurs (database connection issues, etc.):

HTTP/1.1 500 Internal Server Error
Content-Type: application/json

{
"error": {
"message": "Failed to delete organization"
}
}

👥 User Management Endpoints​

6. List Organization Members​

Retrieves a list of users associated with an organization.

Request:

  • Method: GET
  • Path: /organizations/:organizationId/members
  • Headers: Authorization: Bearer <access-token>
  • Authorization: Bearer token required (admin/organization access)

URL Parameters:

ParameterTypeRequiredDescription
organizationIdstring✅Unique organization identifier

Validation:

  • Schema Validation: None (GET request)
  • Route Validators:
    • Require authenticated request (bearer token)
    • Require admin role or organization owner/admin role

Example Request:

curl {{host}}/organizations/7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2/members

Success Response:

HTTP/1.1 200 OK
Content-Type: application/json

{
"count": 2,
"total": 2,
"value": [
{
"id": "identity-123",
"role": "admin"
},
{
"id": "392157b1-dc7a-4935-a6f9-a2d333b910ea",
"role": "owner"
}
]
}

7. Add/Update Organization Members​

Adds new users to an organization or updates existing user roles. Uses upsert logic - if user exists, updates their role; if not, adds them.

Request:

  • Method: PATCH
  • Path: /organizations/:organizationId/members
  • Headers: Content-Type: application/json, Authorization: Bearer <access-token>
  • Authorization: Bearer token required (admin/organization access)

URL Parameters:

ParameterTypeRequiredDescription
organizationIdstring✅Unique organization identifier

Request Body: Array of member objects to add/update:

FieldTypeRequiredDescription
idstring✅Identity identifier
rolestring✅Member role in the organization

Validation:

  • Schema Validation: Enforced automatically (array with required id and role fields)
  • Route Validators:
    • Require authenticated request (bearer token)
    • Require admin role or organization owner/admin role

Example Request:

curl -X PATCH {{host}}/organizations/7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2/members \
-H "Content-Type: application/json" \
-d '[
{"id": "user123", "role": "admin"},
{"id": "user456", "role": "member"}
]'

Success Response:

HTTP/1.1 204 No Content

Error Responses:

When request body is missing or empty:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
"error": {
"message": "Request body non-empty array required"
}
}

When organization doesn't exist:

HTTP/1.1 404 Not Found
Content-Type: application/json

{
"error": {
"message": "Organization not found"
}
}

When database operation fails:

HTTP/1.1 500 Internal Server Error
Content-Type: application/json

{
"error": {
"message": "Failed to upsert organization users"
}
}

8. Remove Member from Organization​

Removes a specific user from an organization.

Request:

  • Method: DELETE
  • Path: /organizations/:organizationId/members/:identityId
  • Headers: Authorization: Bearer <access-token>
  • Authorization: Bearer token required (admin/organization access)

URL Parameters:

ParameterTypeRequiredDescription
organizationIdstring✅Unique organization identifier
identityIdstring✅Unique identity identifier

Validation:

  • Schema Validation: None (DELETE request)
  • Route Validators:
    • Require authenticated request (bearer token)
    • Require admin role or organization owner/admin role

Example Request:

curl -X DELETE {{host}}/organizations/7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2/members/identity-123

Success Response:

HTTP/1.1 204 No Content

Error Responses:

When organization doesn't exist:

HTTP/1.1 404 Not Found
Content-Type: application/json

{
"error": {
"message": "Organization not found"
}
}

When user is not in the organization:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
"error": {
"message": "Failed to remove user from organization"
}
}

When database operation fails:

HTTP/1.1 500 Internal Server Error
Content-Type: application/json

{
"error": {
"message": "Failed to delete organization user"
}
}

9. Get Member Role in Organization​

Retrieves the role of a specific user within an organization.

Request:

  • Method: GET
  • Path: /organizations/:organizationId/members/:identityId/role
  • Headers: Authorization: Bearer <access-token>
  • Authorization: Bearer token required (admin/organization access)

URL Parameters:

ParameterTypeRequiredDescription
organizationIdstring✅Unique organization identifier
identityIdstring✅Unique identity identifier

Validation:

  • Schema Validation: Path parameter validation (organizationId, identityId required)
  • Route Validators:
    • Require authenticated request (bearer token)
    • Require admin role or organization owner/admin role

Example Request:

curl {{host}}/organizations/7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2/members/identity-123/role

Success Response:

HTTP/1.1 200 OK
Content-Type: application/json

{
"inheritedFrom": "7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2" ,
"role": "owner"
}

Error Responses:

When organization or user doesn't exist:

HTTP/1.1 404 Not Found
Content-Type: application/json

{
"error": {
"message": "Organization not found"
}
}

When database operation fails:

HTTP/1.1 500 Internal Server Error
Content-Type: application/json

{
"error": {
"message": "Failed to get organization user role"
}
}

10. Check Member Existence in Organization​

Checks whether a specific user exists within an organization.

Request:

  • Method: GET
  • Path: /organizations/:organizationId/members/check-existence
  • Headers: Authorization: Bearer <access-token>
  • Authorization: Bearer token required (admin/organization access)

URL Parameters:

ParameterTypeRequiredDescription
organizationIdstring✅Unique organization identifier

Query Parameters:

ParameterTypeRequiredDescription
identityIdstring✅Unique identity identifier to check

Validation:

  • Schema Validation: None (GET request)
  • Route Validators:
    • Require authenticated request (bearer token)
    • Require admin role or organization owner/admin role

Example Request:

curl "{{host}}/organizations/7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2/members/check-existence?identityId=identity-123"

Success Response:

HTTP/1.1 200 OK
Content-Type: application/json

{
"isUserInOrganization": true
}

Error Responses:

When organization doesn't exist:

HTTP/1.1 404 Not Found
Content-Type: application/json

{
"error": {
"message": "Organization not found"
}
}

When database operation fails:

HTTP/1.1 500 Internal Server Error
Content-Type: application/json

{
"error": {
"message": "Failed to check organization user existence"
}
}

11. Find Organizations for Member​

Retrieves all organizations that a specific identity belongs to, including optional inherited roles when requested.

Request:

  • Method: GET
  • Path: /organizations/members/:identityId
  • Headers: Authorization: Bearer <access-token>
  • Authorization: Bearer token required (admin/self access)

URL Parameters:

ParameterTypeRequiredDescription
identityIdstring✅Unique identity identifier

Query Parameters:

ParameterTypeRequiredDescription
rolesstring❌Optional comma-separated roles filter (e.g., owner,admin)
includeInheritedboolean❌Include inherited roles from descendant organizations

Validation:

  • Schema Validation: Path parameter validation (identityId required) and optional query validation (roles as string; includeInherited as boolean)
  • Route Validators:
    • Require authenticated request (bearer token)
    • Require admin role or self

Example Request:

curl {{host}}/organizations/members/identity-123

Success Response:

[
{
"member": { "inheritedFrom": null, "role": "owner" },
"organization": {
"id": "org1",
"name": "ACME Corp",
"ancestors": [],
"members": [{ "identityId": "identity-123", "role": "owner" }]
}
},
{
"member": { "inheritedFrom": "org1", "role": "owner" },
"organization": {
"id": "org2",
"ancestors": ["org1"],
"members": [{ "identityId": "identity-123", "role": "member" }]
}
}
]

If User Does Not Exist:

HTTP/1.1 200 OK
Content-Type: application/json

{
"count": 0,
"total": 0,
"value": []
}

12. Get Organization Logo Upload URL​

Generates a pre-signed URL for securely uploading an organization logo image. Returns an object ID and a temporary signed URL.

Request:

  • Method: GET
  • Path: /organizations/:organizationId/logo-upload-url
  • Headers: Authorization: Bearer <token>
  • Authorization: Bearer token required (admin/owner access)

URL Parameters:

ParameterTypeRequiredDescription
organizationIdstring✅Target organization ID

Query Parameters:

ParameterTypeRequiredDescription
contentTypestring✅Image MIME type (e.g., image/png)
contentLengthnumber✅File size in bytes (max 10MB)

Response Body:

FieldTypeDescription
objectIdstringGenerated storage object ID for the logo
urlstringPre-signed URL for uploading the file

Validation:

  • Schema Validation: Uses image upload schema (content type and size constraints)
  • Route Validators:
    • Require authenticated request (bearer token)
    • Require admin role or organization owner role

Example Request:

curl "{{host}}/organizations/7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2/logo-upload-url?contentType=image/png&contentLength=1048576" \
-H "Authorization: Bearer <access-token>"

Success Response:

{
"objectId": "7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2",
"url": "https://storage.googleapis.com/bucket/logos/...&X-Goog-Expires=900&X-Goog-Signature=..."
}

13. List Descendant Organizations​

Retrieves all descendant organizations for a given organization, optionally limited by depth.

Request:

  • Method: GET
  • Path: /organizations/:organizationId/descendants
  • Headers: Authorization: Bearer <access-token>
  • Authorization: Bearer token required (admin/owner access)

URL Parameters:

ParameterTypeRequiredDescription
organizationIdstring✅Parent organization identifier

Query Parameters:

ParameterTypeRequiredDescription
depthnumber (>=1)❌Limit descendants by hierarchy depth

Validation:

  • Schema Validation: Path parameter validation (organizationId required); depth must be a positive number when provided
  • Route Validators:
    • Require authenticated request (bearer token)
    • Require admin role or organization owner/admin role

Example Request:

curl "{{host}}/organizations/7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2/descendants?depth=2" \
-H "Authorization: Bearer <access-token>"

Success Response:

[
{
"id": "9044d797-384e-4c60-a3b6-1d900ffd8be8",
"name": "ACME Corp",
"description": "Leading provider of rocket skates",
"contact_email": "info@acme.test",
"createdAt": "2025-08-25T07:42:18.643Z",
"updatedAt": "2025-08-25T07:42:18.643Z"
}
]

⚙️ Configuration Options​

Service Configuration​

interface OrganizationServiceConfiguration {
authSecrets: {
authEncSecret: string; // JWT encryption secret
authSignSecret: string; // JWT signing secret
};
identity?: {
typeIds?: {
admin: string; // Admin user type identifier
guest: string; // Guest user type identifier
regular: string; // Regular user type identifier
};
};
organization?: {
roles?: {
admin: string; // Admin role identifier
member: string; // Member role identifier
owner: string; // Owner role identifier
};
};
}

Configuration Details​

The organization service configuration is organized into logical groups for security, user type management, and organization role management.

🔐 Security Settings​

authSecrets - JWT token security secrets

  • Type: { authEncSecret: string; authSignSecret: string }
  • Description: Secret keys for JWT encryption and signing (used for token validation)
  • Required: Yes (for production)
  • Child Properties:
    • authEncSecret: Secret key for JWT payload encryption
    • authSignSecret: Secret key for JWT signature verification

👥 User Type Settings​

identity.typeIds - User type identifier configuration

  • Type: { admin?: string; guest?: string; regular?: string }
  • Description: Custom user type identifiers for role-based access control
  • Default: undefined (uses default type validation)
  • Child Properties:
    • admin: Admin user type identifier
      • Type: string
      • Description: Custom identifier for admin users
      • Use Case: Role-based access control for administrative operations
      • Example: "admin", "administrator", "superuser"
    • guest: Guest user type identifier
      • Type: string
      • Description: Custom identifier for guest users
      • Use Case: Limited access for unauthenticated or temporary users
      • Example: "guest", "visitor", "anonymous"
    • regular: Regular user type identifier
      • Type: string
      • Description: Custom identifier for regular users
      • Use Case: Standard user access permissions
      • Example: "user", "member", "customer"

🏢 Organization Role Settings​

organization.roles - Organization role identifier configuration

  • Type: { admin?: string; member?: string; owner?: string }
  • Description: Custom organization role identifiers for user management within organizations
  • Default: undefined (uses default role validation)
  • Child Properties:
    • admin: Admin role identifier
      • Type: string
      • Description: Custom identifier for organization admin role
      • Use Case: Administrative permissions within organizations
      • Example: "admin", "administrator", "manager"
    • member: Member role identifier
      • Type: string
      • Description: Custom identifier for organization member role
      • Use Case: Standard member permissions within organizations
      • Example: "member", "user", "employee"
    • owner: Owner role identifier
      • Type: string
      • Description: Custom identifier for organization owner role
      • Use Case: Full control permissions within organizations
      • Example: "owner", "founder", "creator"

Example Configuration​

const organizationConfig = {
authSecrets: {
authEncSecret: process.env.AUTH_ENC_SECRET || 'your-enc-secret',
authSignSecret: process.env.AUTH_SIGN_SECRET || 'your-sign-secret'
},
identity: {
typeIds: {
admin: '100',
guest: '000',
regular: '001'
}
},
organization: {
roles: {
admin: '100',
member: '001',
owner: '010'
}
}
};

🚨 Error Handling​

All organization service errors return JSON format with appropriate HTTP status codes:

Common Error Codes​

StatusError MessageDescription
400Validation ErrorInvalid request body format or missing required fields
400Request body is requiredMissing request body for PATCH operations
400Request body non-empty array requiredMissing or empty array for user management operations
400Failed to create organizationDatabase insert operation failed to return an inserted ID
400Failed to update organizationUpdate operation doesn't modify any data (no changes detected)
400Failed to remove user from organizationUser is not in the organization or removal failed
401token could not be verifiedMissing or invalid authorization token
403User is not authorized to access this resourceUser lacks required permissions (admin/organization access)
404Organization not foundOrganization doesn't exist for the requested operation
500Failed to create organizationDatabase connection issues or unexpected failures during creation
500Failed to get organizationDatabase connection issues or unexpected failures during retrieval
500Failed to find organizationsDatabase connection issues, invalid filter syntax, or unexpected failures during listing
500Failed to update organizationDatabase connection issues or unexpected failures during update
500Failed to delete organizationDatabase connection issues or unexpected failures during deletion
500Failed to upsert organization usersDatabase connection issues or unexpected failures during user management
500Failed to delete organization userDatabase connection issues or unexpected failures during user removal
500Failed to get organization user roleDatabase connection issues or unexpected failures during role retrieval
500Failed to check organization user existenceDatabase connection issues or unexpected failures during existence check
500Cannot read properties of undefined (reading 'organizations')Handler implementation bug in find organizations for user endpoint

Error Response Format​

{
"error": {
"message": "Error message description",
"data": ["Additional error details"]
}
}

Validation Errors include additional details:

{
"error": {
"message": "Validation Error",
"data": [
"request body must have required property 'name'",
"request body must have required property 'description'",
"request body must have required property 'contact_email'",
"request body must have required property 'ownerId'"
]
}
}