Organization Management API
Manage directors, shareholders, and employees for organizations
Organization Management API
Manage organization structure by adding directors, shareholders, and employees after initial registration.
Personnel Management Overview
After registering an organization, you must add personnel in the correct order:
Recommended Order:
- Employees (including at least one ADMIN_USER)
- Directors (minimum 1 required for activation)
- Shareholders (must total 100% ownership)
Dual Record Creation
When you add personnel, the system automatically creates two linked records:
| Record Type | Purpose | Status |
|---|---|---|
| Organization Record | Links person to org with role/position | ACTIVE |
| Individual Customer | Creates login credentials | ACTIVE |
Important: Each person gets auto-generated username and password returned in the response.
Add Director
Add a director to an organization.
Endpoint
POST /api/v2.1/customer/organization/{organizationId}/director
Path Parameters
organizationId string path required Organization UUID identifier
Example: 2f6ddd86-9ef1-45b6-a16d-058b3ccf29e4
Headers
X-Tenant-ID string header required Tenant identifier
Authorization string header required Bearer token for authentication
Content-Type string header required Must be application/json
Request Body
person object body required Director’s personal information
See PersonDto for complete structure
role string body required Director role type
Valid Values:
MANAGING_DIRECTOREXECUTIVE_DIRECTORNON_EXECUTIVE_DIRECTORBOARD_MEMBER
ownershipPercentage number body Percentage ownership (0-100)
Default: 0 if not specified
isPrimaryContact boolean body Whether this director is the primary contact
Default: false
addresses array body required Array of address objects
See AddressDto
telephoneNumbers array body required Array of telephone numbers
Code Example
curl -X POST "https://sandbox.finhub.cloud/api/v2.1/customer/organization/2f6ddd86-9ef1-45b6-a16d-058b3ccf29e4/director" \
-H "Accept: application/json, text/plain, */*" \
-H "Content-Type: application/json" \
-H "X-Tenant-ID: 97e7ff29-15f3-49ef-9681-3bbfcce4f6cd" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "X-Forwarded-From: e2e-test" \
-H "platform: web" \
-H "deviceId: 356938035643809" \
-d '{
"person": {
"firstName": "John",
"lastName": "Director",
"email": "director@acmecorp.com",
"dateOfBirth": "1980-01-15",
"nationality": "LT",
"gender": 0,
"placeOfBirth": "Vilnius",
"fullName": "John Director"
},
"role": "MANAGING_DIRECTOR",
"ownershipPercentage": 0,
"isPrimaryContact": false,
"addresses": [
{
"type": "HOME",
"street": "123 Director Street",
"city": "Vilnius",
"postalCode": "12345",
"country": "LT",
"isPrimary": true
}
],
"telephoneNumbers": [
{
"number": "+37060012345",
"country": "LT",
"phoneType": 1,
"operator": "Telia",
"purpose": "personal",
"isPrimary": true
}
]
}'const addDirector = async (organizationId) => {
const response = await fetch(
`https://sandbox.finhub.cloud/api/v2.1/customer/organization/${organizationId}/director`,
{
method: 'POST',
headers: {
'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json',
'X-Tenant-ID': '97e7ff29-15f3-49ef-9681-3bbfcce4f6cd',
'Authorization': `Bearer ${token}`,
'X-Forwarded-From': 'e2e-test',
'platform': 'web',
'deviceId': '356938035643809'
},
body: JSON.stringify({
person: {
firstName: 'John',
lastName: 'Director',
email: 'director@acmecorp.com',
dateOfBirth: '1980-01-15',
nationality: 'LT',
gender: 0,
placeOfBirth: 'Vilnius',
fullName: 'John Director'
},
role: 'MANAGING_DIRECTOR',
ownershipPercentage: 0,
isPrimaryContact: false,
addresses: [{
type: 'HOME',
street: '123 Director Street',
city: 'Vilnius',
postalCode: '12345',
country: 'LT',
isPrimary: true
}],
telephoneNumbers: [{
number: '+37060012345',
country: 'LT',
phoneType: 1,
operator: 'Telia',
purpose: 'personal',
isPrimary: true
}]
})
}
);
return response.json();
};Response
{
"code": 200,
"message": "Success",
"data": {
"individual": {
"password": "temporaryPassword123!",
"customerId": "9620561e-a47c-419b-b0f7-ca204f827ef6",
"tenantId": "d1e2f3a4-b5c6-47d8-9e0f-1a2b3c4d5e6f",
"userId": "bb9b9fee-205e-474d-8669-fd53e2189403",
"email": "director@acmecorp.com",
"username": "director@acmecorp.com"
},
"organization": {
"individual": false,
"organization": true,
"adminEmployees": [],
"organizationId": "ef4a8be6-602b-4b26-b81d-afa7d6d835fd",
"tenantId": "d1e2f3a4-b5c6-47d8-9e0f-1a2b3c4d5e6f",
"shareholders": [],
"employees": [],
"directors": []
}
}
}Add Shareholders
Add one or more shareholders to an organization.
Endpoint
POST /api/v2.1/customer/organization/{organizationId}/shareholders
Path Parameters
organizationId string path required Organization UUID identifier
Request Body
The request body is an array of shareholder objects.
[n].person object body required Shareholder’s personal information (see PersonDto)
[n].sharePercentage number body required Ownership percentage (0-100)
[n].isPrimaryContact boolean body required Whether this shareholder is the primary contact
[n].addresses array body required Array of address objects
[n].telephoneNumbers array body required Array of telephone numbers
Code Example
curl -X POST "https://sandbox.finhub.cloud/api/v2.1/customer/organization/2f6ddd86-9ef1-45b6-a16d-058b3ccf29e4/shareholders" \
-H "Accept: application/json, text/plain, */*" \
-H "Content-Type: application/json" \
-H "X-Tenant-ID: 97e7ff29-15f3-49ef-9681-3bbfcce4f6cd" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "X-Forwarded-From: e2e-test" \
-H "platform: web" \
-H "deviceId: 356938035643809" \
-d '[
{
"person": {
"firstName": "Alice",
"lastName": "Shareholder",
"email": "shareholder1@acmecorp.com",
"dateOfBirth": "1975-05-20",
"nationality": "LT",
"gender": 1,
"placeOfBirth": "Kaunas",
"fullName": "Alice Shareholder"
},
"sharePercentage": 60,
"isPrimaryContact": true,
"addresses": [
{
"type": "HOME",
"street": "456 Shareholder Ave",
"city": "Kaunas",
"postalCode": "54321",
"country": "LT",
"isPrimary": true
}
],
"telephoneNumbers": [
{
"number": "+37060054321",
"country": "LT",
"phoneType": 1,
"operator": "Tele2",
"purpose": "personal",
"isPrimary": true
}
]
},
{
"person": {
"firstName": "Bob",
"lastName": "Shareholder",
"email": "shareholder2@acmecorp.com",
"dateOfBirth": "1978-08-10",
"nationality": "LT",
"gender": 0,
"placeOfBirth": "Klaipeda",
"fullName": "Bob Shareholder"
},
"sharePercentage": 40,
"isPrimaryContact": false,
"addresses": [
{
"type": "HOME",
"street": "789 Owner Street",
"city": "Klaipeda",
"postalCode": "98765",
"country": "LT",
"isPrimary": true
}
],
"telephoneNumbers": [
{
"number": "+37060098765",
"country": "LT",
"phoneType": 1,
"operator": "Bite",
"purpose": "personal",
"isPrimary": true
}
]
}
]'const addShareholders = async (organizationId, shareholders) => {
const response = await fetch(
`https://sandbox.finhub.cloud/api/v2.1/customer/organization/${organizationId}/shareholders`,
{
method: 'POST',
headers: {
'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json',
'X-Tenant-ID': '97e7ff29-15f3-49ef-9681-3bbfcce4f6cd',
'Authorization': `Bearer ${token}`,
'X-Forwarded-From': 'e2e-test',
'platform': 'web',
'deviceId': '356938035643809'
},
body: JSON.stringify(shareholders)
}
);
return response.json();
};Response
{
"code": 200,
"message": "Success",
"data": {
"count": 2
}
}Add Employee
Add an employee to an organization.
Endpoint
POST /api/v2.1/customer/organization/{organizationId}/employee
Path Parameters
organizationId string path required Organization UUID identifier
Request Body
person object body required Employee’s personal information (see PersonDto)
role string body required Primary role identifier
Valid Roles:
ADMIN_USER(Required for at least one employee)TRANSACTION_APPROVERCOMPLIANCE_OFFICEREMPLOYEE
roles string[] body required Array of role identifiers (can include multiple roles)
Example: ["COMPLIANCE_OFFICER", "TRANSACTION_APPROVER", "EMPLOYEE"]
department string body Department name
Examples: "Finance", "Compliance", "Management"
addresses array body required Array of address objects
telephoneNumbers array body required Array of telephone numbers
Code Example
curl -X POST "https://sandbox.finhub.cloud/api/v2.1/customer/organization/2f6ddd86-9ef1-45b6-a16d-058b3ccf29e4/employee" \
-H "Accept: application/json, text/plain, */*" \
-H "Content-Type: application/json" \
-H "X-Tenant-ID: 97e7ff29-15f3-49ef-9681-3bbfcce4f6cd" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "X-Forwarded-From: e2e-test" \
-H "platform: web" \
-H "deviceId: 356938035643809" \
-d '{
"person": {
"firstName": "Jane",
"lastName": "Compliance",
"email": "compliance@acmecorp.com",
"dateOfBirth": "1990-03-25",
"nationality": "LT",
"gender": 1,
"placeOfBirth": "Vilnius",
"fullName": "Jane Compliance"
},
"role": "ADMIN_USER",
"roles": ["ADMIN_USER", "COMPLIANCE_OFFICER", "EMPLOYEE"],
"department": "Compliance",
"addresses": [
{
"type": "HOME",
"street": "321 Employee Road",
"city": "Vilnius",
"postalCode": "11111",
"country": "LT",
"isPrimary": true
}
],
"telephoneNumbers": [
{
"number": "+37060011111",
"country": "LT",
"phoneType": 1,
"operator": "Telia",
"purpose": "personal",
"isPrimary": true
}
]
}'Response
{
"code": 200,
"message": "Success",
"data": {
"employeeId": "emp_123456",
"userId": "user_789012",
"email": "compliance@acmecorp.com",
"status": "ACTIVE"
}
}{
"code": 400,
"message": "Missing required role 'ADMIN_USER' for BUSINESS_TYPE_CLIENT_TO_TENANT organization. At least one employee must have this role."
}Organization Structure Best Practices
Required Roles
| Role | Minimum Count | Purpose |
|---|---|---|
ADMIN_USER | 1+ | System administration and user management |
COMPLIANCE_OFFICER | 1+ (recommended) | KYC/AML compliance management |
TRANSACTION_APPROVER | 1+ (recommended) | Financial transaction approvals |
Typical Organization Structure
Organization
├── Directors (1-5)
│ └── MANAGING_DIRECTOR (primary)
├── Shareholders (1-10)
│ └── Share percentages sum to 100%
└── Employees (1-50)
├── ADMIN_USER (required, 1+)
├── COMPLIANCE_OFFICER (recommended)
├── TRANSACTION_APPROVER (recommended)
└── EMPLOYEE (general staff)
Setup Workflow
- Register Organization → Creates basic structure
- Add Director(s) → Legal representatives
- Add Shareholder(s) → Ownership structure
- Add Employees → Must include ADMIN_USER
- Verify Organization → KYB process
- Accept Consents → Legal agreements
- Activate Organization → Enable operations
Common Validation Errors
Missing ADMIN_USER Role
Problem: Cannot complete setup without ADMIN_USER
Error:
{
"code": 400,
"message": "Missing required role 'ADMIN_USER' for BUSINESS_TYPE_CLIENT_TO_TENANT organization"
}Solution: Ensure at least one employee has ADMIN_USER in their roles array:
{
"role": "ADMIN_USER",
"roles": ["ADMIN_USER", "EMPLOYEE"]
}Duplicate Email
Problem: Email already exists in system
Solution: Each person (director, shareholder, employee) must have a unique email address within the tenant.
Invalid Share Percentage
Problem: Shareholder percentages don’t sum to 100
Recommendation: While not strictly enforced, share percentages should typically sum to 100% for accurate ownership representation.
Role Hierarchy and Permissions
Employee Roles
| Role | Permissions | Required for Activation |
|---|---|---|
| ADMIN_USER | Full organization access, can activate account | ✅ Yes (minimum 1) |
| COMPLIANCE_OFFICER | Can approve verifications, activate organization | ✅ Recommended |
| TRANSACTION_APPROVER | Can approve high-value transactions | No |
| EMPLOYEE | Basic access, transaction operations | No |
Director Types
| Type | Description | Authority Level |
|---|---|---|
| EXECUTIVE | Executive director with operational control | High |
| NON_EXECUTIVE | Advisory role, no day-to-day operations | Medium |
| INDEPENDENT | Independent oversight | Medium |
API Schema References
For complete OpenAPI schema specifications:
Related Endpoints
Complete HTTP headers reference
Initial organization registration
Employee management operations
Director management operations
Shareholder management operations
Activate organization after setup
Changelog
| Version | Date | Changes |
|---|---|---|
| v2.1 | 2026-01-13 | Initial documentation |