Skip to main content
Version: 🚧 Canary

🏢 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
idstringUnique identifier (UUID)
createdAtdatetimeCreation timestamp
updatedAtdatetimeLast modification timestamp
namestringOrganization name (minimum 1 character)
descriptionstringOrganization description
contact_emailstringContact email address (email format)
contact_phonestringContact phone number
addressobjectAddress object (free-form JSON)
logoobject or nullOrganization logo. Responses: { type, url }; Requests: { objectId, type }
usersarrayArray 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
organizationobjectOrganization payload object (see below)
ownerIdstringIdentity ID of the organization owner
parentIdstringOptional parent organization ID

Organization object fields:

FieldTypeRequiredDescription
namestringOrganization name (minimum 1 character)
descriptionstringOrganization description
contact_emailstringContact email address (email format)
contact_phonestringContact phone number
addressobjectAddress 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
organizationIdstringUnique 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
namestringFilter organizations by name (minimum 1 character)
descriptionstringFilter organizations by description
contact_emailstringFilter organizations by contact email (email format)
contact_phonestringFilter organizations by contact phone
pagenumberPage number
limitnumberItems 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
organizationIdstringUnique 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
organizationIdstringUnique 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
organizationIdstringUnique 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
organizationIdstringUnique organization identifier

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

FieldTypeRequiredDescription
idstringIdentity identifier
rolestringMember 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
organizationIdstringUnique organization identifier
identityIdstringUnique 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
organizationIdstringUnique organization identifier
identityIdstringUnique 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
organizationIdstringUnique organization identifier

Query Parameters:

ParameterTypeRequiredDescription
identityIdstringUnique 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
identityIdstringUnique identity identifier

Query Parameters:

ParameterTypeRequiredDescription
rolesstringOptional comma-separated roles filter (e.g., owner,admin)
includeInheritedbooleanInclude 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
organizationIdstringTarget organization ID

Query Parameters:

ParameterTypeRequiredDescription
contentTypestringImage MIME type (e.g., image/png)
contentLengthnumberFile 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
organizationIdstringParent 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'"
]
}
}