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:

  1. Employees (including at least one ADMIN_USER)
  2. Directors (minimum 1 required for activation)
  3. Shareholders (must total 100% ownership)

Dual Record Creation

When you add personnel, the system automatically creates two linked records:

Record TypePurposeStatus
Organization RecordLinks person to org with role/positionACTIVE
Individual CustomerCreates login credentialsACTIVE

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

person properties
firstName string body required

Given name

lastName string body required

Family name

email string body required

Email address

dateOfBirth string body required

ISO 8601 date (YYYY-MM-DD)

nationality string body required

ISO 3166-1 alpha-2 country code

gender integer body required

Gender code: 0 = Male, 1 = Female

placeOfBirth string body

Birth location

fullName string body

Complete name for display

role string body required

Director role type

Valid Values:

  • MANAGING_DIRECTOR
  • EXECUTIVE_DIRECTOR
  • NON_EXECUTIVE_DIRECTOR
  • BOARD_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

See TelephoneNumberDto

Code Example

cURL
bash
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
      }
    ]
  }'
JavaScript
javascript
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

Response example
200
json
{
  "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
bash
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
        }
      ]
    }
  ]'
JavaScript
javascript
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

Response example
200
json
{
  "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_APPROVER
  • COMPLIANCE_OFFICER
  • EMPLOYEE
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
bash
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

Response example
200
json
{
  "code": 200,
  "message": "Success",
  "data": {
    "employeeId": "emp_123456",
    "userId": "user_789012",
    "email": "compliance@acmecorp.com",
    "status": "ACTIVE"
  }
}
400
json
{
  "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

RoleMinimum CountPurpose
ADMIN_USER1+System administration and user management
COMPLIANCE_OFFICER1+ (recommended)KYC/AML compliance management
TRANSACTION_APPROVER1+ (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

  1. Register Organization → Creates basic structure
  2. Add Director(s) → Legal representatives
  3. Add Shareholder(s) → Ownership structure
  4. Add Employees → Must include ADMIN_USER
  5. Verify Organization → KYB process
  6. Accept Consents → Legal agreements
  7. Activate Organization → Enable operations

Common Validation Errors

Missing ADMIN_USER Role

Problem: Cannot complete setup without ADMIN_USER

Error:

json
{
  "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:

json
{
  "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

RolePermissionsRequired for Activation
ADMIN_USERFull organization access, can activate account✅ Yes (minimum 1)
COMPLIANCE_OFFICERCan approve verifications, activate organization✅ Recommended
TRANSACTION_APPROVERCan approve high-value transactionsNo
EMPLOYEEBasic access, transaction operationsNo

Director Types

TypeDescriptionAuthority Level
EXECUTIVEExecutive director with operational controlHigh
NON_EXECUTIVEAdvisory role, no day-to-day operationsMedium
INDEPENDENTIndependent oversightMedium

API Schema References

For complete OpenAPI schema specifications:



Changelog

VersionDateChanges
v2.12026-01-13Initial documentation

Type to search…

↑↓ navigate open esc close