Skip to main content

Org structure

About 8 min

Org Structure

Working with the org structure via the REST API: org units, positions, employees, and the relationships between them. General rules (authentication, limits) are covered in the REST API overview.

Working with the org structure

The org structure consists of several key entities:

Core Entities

OrgItem - an element of the org structure. It can be of two types:

  • Position - for example, "Chief Executive Officer"
  • Group - for example, "Financial Control Department"

Relationship with Roles

Roles are an internal abstraction in Stormbpmn. OrgItems can be assigned to roles. In this case, they cannot be deleted via the API; you must perform reassignment through the UI.

OrgItemEdge - a link between org structure elements, representing subordination.

  • For example: "Financial Control Department" is subordinate to "Chief Executive Officer"
  • Each OrgItem can have only one parent link (dual subordination is not allowed)

Person - an organization employee

OrgItemPersonEdge - assignment of an employee to an org structure element

  • For example: "Kotov D.G." is assigned to the "Chief Executive Officer" position
  • A Person can be assigned to multiple OrgItems
  • A Person can be assigned ONLY to OrgItems of the "Position" type

Important

Operations on entities are separated into individual methods. Integrity from a business logic perspective is maintained by the calling system. Integrity from a validation and inter-entity relationship perspective is ensured by the system.


Entity Attribute Composition

OrgItem

AttributeTypeDescription
idUUIDInternal identifier
externalIdstringIdentifier in the external system (unique)
typeENUMPOSITION (position) or OU (group)
namestringName
descriptionstringDescription in HTML format
colorstringColor in HEX format

OrgItemEdge

AttributeTypeDescription
idUUIDInternal identifier
sourceIdUUIDParent element identifier
targetIdUUIDChild element identifier
externalSourceIdstringExternal parent identifier
externalTargetIdstringExternal child element identifier

Person

AttributeTypeDescription
idUUIDInternal identifier
externalIdstringIdentifier in the external system (unique)
emailstringEmail address
phonestringPhone number
firstNamestringFirst name
lastNamestringLast name
patronymicstringPatronymic
photoUrlstringLink to a photo (via the file upload API)

OrgItemPersonEdge

AttributeTypeDescription
idUUIDInternal identifier
sourceIdUUIDOrgItem identifier
personIdUUIDPerson identifier
externalSourceIdstringExternal OrgItem identifier
externalPersonIdstringExternal Person identifier

API Methods

Creating an OrgItem

Path: POST /public-api/v1/org-items

Request structure:

[
    {
        "externalId": "CEO_POSITION_001",
        "type": "POSITION",
        "name": "Генеральный директор",
        "description": "<p>Руководитель организации</p>",
        "color": "#FF6B6B"
    }
]

Request parameters:

FieldTypeRequiredDescription
externalIdstring✅Unique identifier in the external system
typeenum✅POSITION (position) or OU (group)
namestring✅Element name
descriptionstring📄Description in HTML format
colorstring📄Color in HEX format

Response structure:

{
    "created": [
        {
            "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
            "externalId": "CEO_POSITION_001",
            "type": "POSITION",
            "name": "Генеральный директор",
            "description": "<p>Руководитель организации</p>",
            "color": "#FF6B6B"
        }
    ],
    "errors": []
}

Reading an OrgItem

Path: GET /public-api/v1/org-items

Query parameters:

ParameterTypeRequiredDescription
pagenumber📄Page number (default 0)
sizenumber📄Page size (default 20)

Retrieval by ID:

Path: GET /public-api/v1/org-items/{id}

Path parameters:

ParameterTypeDescription
idUUIDInternal identifier

Retrieval by external ID:

Path: GET /public-api/v1/org-items/by-external-id/{externalId}

Path parameters:

ParameterTypeDescription
externalIdstringExternal identifier of the element

Response structure:

{
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "externalId": "CEO_POSITION_001",
    "type": "POSITION",
    "name": "Генеральный директор",
    "description": "<p>Руководитель организации</p>",
    "color": "#FF6B6B",
    "parentItems": {},
    "childItems": [
        {
            "id": "b2c3d4e5-f6g7-8901-bcde-f23456789012",
            "externalId": "b2c3d4e5-f6g7-8901-bcde-f23456789012",
            "name": "Заместитель генерального директора"
        }
    ],
    "assignedPersons": [
        {
            "externalId": "CEO_POSITION_001",
            "id": "c3d4e5f6-g7h8-9012-cdef-345678901234",
            "firstName": "Дмитрий",
            "lastName": "Котов",
            "email": "kotov@company.com"
        }
    ]
}

Updating an OrgItem

Path: PUT /public-api/v1/org-items/{id}

Path parameters:

ParameterTypeDescription
idUUIDInternal identifier

Update by external ID:

Path: PUT /public-api/v1/org-items/by-external-id/{externalId}

Request structure:

{
    "name": "Генеральный директор (обновлено)",
    "description": "<p>Главное лицо организации</p>",
    "color": "#4ECDC4"
}

Request parameters:

FieldTypeRequiredDescription
namestring📄New name
descriptionstring📄New description in HTML
colorstring📄New color in HEX

Important

The element type (type) cannot be changed after creation. To change the type, you must delete and create a new element.

Deleting an OrgItem

Path: DELETE /public-api/v1/org-items/{id}

Path parameters:

ParameterTypeDescription
idUUIDInternal identifier

Deletion by external ID:

**Path:Path: DELETE /public-api/v1/org-items/by-external-id/{externalId}

Response structure:

{
    "deleted": true,
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "message": "OrgItem успешно удален"
}

Deletion conditions:

  • ✅ An element without connections can be deleted immediately
  • ⚠️ An element with child connections can only be deleted after all connections are removed
  • ⚠️ An element with assigned employees can only be deleted after all assignments are revoked

Cascading deletion

Cascading deletion is not supported.

Creating a Person

Path: POST /public-api/v1/persons

Request structure:

[
    {
        "externalId": "KOTOV_DG_001",
        "email": "kotov@company.com",
        "phone": "+7 (495) 123-45-67",
        "firstName": "Дмитрий",
        "lastName": "Котов",
        "patronymic": "Георгиевич",
        "photoUrl": "/userFiles/1.png"
    }
]

Request parameters:

FieldTypeRequiredDescription
externalIdstring📄Unique identifier in the external system
emailstring📄Employee's email address
phonestring📄Employee's phone number
firstNamestring✅Employee's first name
lastNamestring📄Employee's last name
patronymicstring📄Employee's patronymic
photoUrlstring📄Link to the photo (via the file upload API)

Response structure:

{
    "created": [
        {
            "id": "c3d4e5f6-g7h8-9012-cdef-345678901234",
            "externalId": "KOTOV_DG_001",
            "email": "kotov@company.com",
            "phone": "+7 (495) 123-45-67",
            "firstName": "Дмитрий",
            "lastName": "Котов",
            "patronymic": "Георгиевич",
            "photoUrl": "https://company.com/photos/kotov.jpg"
        }
    ],
    "errors": []
}

Reading a Person

Path: GET /public-api/v1/persons

Query parameters:

ParameterTypeRequiredDescription
pagenumber📄Page number (default 0)
sizenumber📄Page size (default 20)
emailstring📄Filter by email address

Retrieval by ID:

Path: GET /public-api/v1/persons/{id}

Path parameters:

ParameterTypeDescription
idUUIDInternal identifier

Retrieval by external ID:

Path: GET /public-api/v1/persons/by-external-id/{externalId}

Path parameters:

ParameterTypeDescription
externalIdstringExternal identifier of the element

Response structure:

{
    "id": "c3d4e5f6-g7h8-9012-cdef-345678901234",
    "externalId": "KOTOV_DG_001",
    "email": "kotov@company.com",
    "phone": "+7 (495) 123-45-67",
    "firstName": "Дмитрий",
    "lastName": "Котов",
    "patronymic": "Георгиевич",
    "photoUrl": "https://company.com/photos/kotov.jpg",
    "assignedPositions": [
        {
            "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
            "externalId": "CEO_POSITION_001",
            "name": "Генеральный директор",
            "type": "POSITION"
        }
    ]
}

Updating a Person

Path: PUT /public-api/v1/persons/{id}

Path parameters:

ParameterTypeDescription
idUUIDInternal identifier

Update by external ID:

Path: PUT /public-api/v1/persons/by-external-id/{externalId}

Request structure:

{
    "email": "d.kotov@company.com",
    "phone": "+7 (495) 987-65-43",
    "firstName": "Дмитрий",
    "lastName": "Котов",
    "patronymic": "Георгиевич",
    "photoUrl": "/photos/kotov_new.jpg"
}

Request parameters:

FieldTypeRequiredDescription
emailstring📄New email address
phonestring📄New phone number
firstNamestring📄New first name
lastNamestring📄New last name
patronymicstring📄New patronymic
photoUrlstring📄New link to the photo

Deleting a Person

Path: DELETE /public-api/v1/persons/{id}

PPath parameters:**

ParameterTypeDescription
idUUIDInternal identifier

Deletion by external ID:

Path: DELETE /public-api/v1/persons/by-external-id/{externalId}

Response structure:

{
    "deleted": true,
    "id": "c3d4e5f6-g7h8-9012-cdef-345678901234",
    "message": "Person успешно удален"
}

Deletion conditions:

  • ✅ An employee without assignments can be deleted immediately
  • ⚠️ An employee with active assignments can only be deleted after all assignments are revoked

Important

When deleting an employee, related OrgItemPersonEdge are not automatically deleted. You must first delete all assignments.

Creating an OrgItemEdge

Path: POST /public-api/v1/org-item-edges

Request structure:

[
    {
        "sourceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
        "targetId": "b2c3d4e5-f6g7-8901-bcde-f23456789012",
        "externalSourceId": "CEO_POSITION_001",
        "externalTargetId": "DEPUTY_CEO_001"
    }
]

Request parameters:

FieldTypeRequiredDescription
sourceIdUUID📎Internal ID of the parent element
targetIdUUID📎Internal ID of the child element
externalSourceIdstring📎External ID of the parent element
externalTargetIdstring📎External ID of the child element

Creation logic

You can use either internal IDs (sourceId, targetId) or external IDs (externalSourceId, externalTargetId). If both internal and external IDs are specified, internal IDs take precedence.

Response structure:

{
    "created": [
        {
            "id": "d4e5f6g7-h8i9-0123-defg-456789012345",
            "sourceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
            "targetId": "b2c3d4e5-f6g7-8901-bcde-f23456789012",
            "externalSourceId": "CEO_POSITION_001",
            "externalTargetId": "DEPUTY_CEO_001",
            "sourceItem": {
                "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                "name": "Генеральный директор"
            },
            "targetItem": {
                "id": "b2c3d4e5-f6g7-8901-bcde-f23456789012",
                "name": "Заместитель генерального директора"
            }
        }
    ],
    "errors": []
}

Reading an OrgItemEdge

Path: GET /public-api/v1/org-item-edges

Query parameters:

ParameterTypeRequiredDescription
pagenumber📄Page number (default 0)
sizenumber📄Page size (default 20)
sourceIdUUID📄Filter by parent element
targetIdUUID📄Filter by child element
externalSourceIdstring📄Filter by parent external ID

Retrieval by ID:

Path: GET /public-api/v1/org-item-edges/{id}

Path parameters:

ParameterTypeDescription
idUUIDInternal identifier

Response structure:

{
    "id": "d4e5f6g7-h8i9-0123-defg-456789012345",
    "sourceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "targetId": "b2c3d4e5-f6g7-8901-bcde-f23456789012",
    "externalSourceId": "CEO_POSITION_001",
    "externalTargetId": "DEPUTY_CEO_001",
    "sourceItem": {
        "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
        "externalId": "CEO_POSITION_001",
        "name": "Генеральный директор",
        "type": "POSITION"
    },
    "targetItem": {
        "id": "b2c3d4e5-f6g7-8901-bcde-f23456789012",
        "externalId": "DEPUTY_CEO_001",
        "name": "Заместитель генерального директора",
        "type": "POSITION"
    }
}

Updating an OrgItemEdge

Path: PUT /public-api/v1/org-item-edges/{id}

Path parameters:

ParameterTypeDescription
idUUIDInternal identifier

Request structure:

{
    "sourceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "targetId": "c3d4e5f6-g7h8-9012-cdef-345678901234",
    "externalSourceId": "CEO_POSITION_001",
    "externalTargetId": "HR_MANAGER_001"
}

Request parameters:

FieldTypeRequiredDescription
sourceIdUUID📎New ID of the parent element
targetIdUUID📎New ID of the child element
externalSourceIdstring📎New external ID of the parent
externalTargetIdstring📎New external ID of the child

Deleting an OrgItemEdge

Path: DELETE /public-api/v1/org-item-edges/{id}

Path parameters:

ParameterTypeDescription
idUUIDInternal identifier

Deletion by relationship:

Path: DELETE /public-api/v1/org-item-edges/by-relation

Query parameters:

ParameterTypeRequiredDescription
sourceIdUUID📎ID of the parent element
targetIdUUID📎ID of the child element
externalSourceIdstring📎External ID of the parent
externalTargetIdstring📎External ID of the child

Response structure:

{
    "deleted": true,
    "id": "d4e5f6g7-h8i9-0123-defg-456789012345",
    "message": "OrgItemEdge успешно удален"
}

Deletion conditions:

  • ✅ A relationship can be deleted at any time
  • ⚠️ When a relationship is deleted, the child element becomes a root element (without a parent)

Important

Deleting a relationship does not delete the OrgItem elements themselves. Only the subordination relationship between them is removed.

Creating an OrgItemPersonEdge

Path: POST /public-api/v1/org-item-person-edges

Request structure:

[
    {
        "sourceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
        "personId": "c3d4e5f6-g7h8-9012-cdef-345678901234",
        "externalSourceId": "CEO_POSITION_001",
        "externalPersonId": "KOTOV_DG_001"
    }
]

Request parameters:

FieldTypeRequiredDescription
sourceIdUUID📎Internal ID of the org structure element
personIdUUID📎Internal ID of the employee
externalSourceIdstring📎External ID of the org structure element
externalPersonIdstring📎External ID of the employee

Creation logic

You can use either internal IDs (sourceId, personId) or external IDs (externalSourceId, externalPersonId). If both internal and external IDs are specified, internal IDs take precedence.

Constraints

An employee can be assigned ONLY to an element of type POSITION (position). Assignment to groups (OU) is not supported.

Response structure:

{
    "created": [
        {
            "id": "e5f6g7h8-i9j0-1234-efgh-567890123456",
            "sourceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
            "personId": "c3d4e5f6-g7h8-9012-cdef-345678901234",
            "externalSourceId": "CEO_POSITION_001",
            "externalPersonId": "KOTOV_DG_001",
            "orgItem": {
                "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                "name": "Генеральный директор",
                "type": "POSITION"
            },
            "person": {
                "id": "c3d4e5f6-g7h8-9012-cdef-345678901234",
                "firstName": "Дмитрий",
                "lastName": "Котов",
                "email": "kotov@company.com"
            }
        }
    ],
    "errors": []
}

Reading an OrgItemPersonEdge

Path: GET /public-api/v1/org-item-person-edges

Query parameters:

ParameterTypeRequiredDescription
pagenumber📄Page number (default 0)
sizenumber📄Page size (default 20)
sourceIdUUID📄Filter by org structure element
personIdUUID📄Filter by employee
externalSourceIdstring📄Filter by position external ID
emailstring📄Filter by employee email

Retrieval by ID:

Path: GET /public-api/v1/org-item-person-edges/{id}

Path parameters:

ParameterTypeDescription
idUUIDInternal identifier

Response structure:

{
    "id": "e5f6g7h8-i9j0-1234-efgh-567890123456",
    "sourceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "personId": "c3d4e5f6-g7h8-9012-cdef-345678901234",
    "externalSourceId": "CEO_POSITION_001",
    "externalPersonId": "KOTOV_DG_001",
    "orgItem": {
        "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
        "externalId": "CEO_POSITION_001",
        "name": "Генеральный директор",
        "type": "POSITION",
        "description": "<p>Руководитель организации</p>",
        "color": "#FF6B6B"
    },
    "person": {
        "id": "c3d4e5f6-g7h8-9012-cdef-345678901234",
        "externalId": "KOTOV_DG_001",
        "firstName": "Дмитрий",
        "lastName": "Котов",
        "patronymic": "Георгиевич",
        "email": "kotov@company.com",
        "phone": "+7 (495) 123-45-67"
    }
}

Updating OrgItemPersonEdge

Path: PUT /public-api/v1/org-item-person-edges/{id}

Path parameters:

ParameterTypeDescription
idUUIDInternal identifier

Request structure:

{
    "sourceId": "b2c3d4e5-f6g7-8901-bcde-f23456789012",
    "personId": "c3d4e5f6-g7h8-9012-cdef-345678901234",
    "externalSourceId": "DEPUTY_CEO_001",
    "externalPersonId": "KOTOV_DG_001"
}

Request parameters:

FieldTypeRequiredDescription
sourceIdUUID📎New org structure element ID
personIdUUID📎New employee ID
externalSourceIdstring📎New external position ID
externalPersonIdstring📎New external employee ID

Deleting OrgItemPersonEdge

Path: DELETE /public-api/v1/org-item-person-edges/{id}

Path parameters:

ParameterTypeDescription
idUUIDInternal identifier

Deletion by assignment:

Path: DELETE /public-api/v1/org-item-person-edges/by-assignment

Query parameters:

ParameterTypeRequiredDescription
sourceIdUUID📎Org structure element ID
personIdUUID📎Employee ID
externalSourceIdstring📎External position ID
externalPersonIdstring📎External employee ID

Deletion of all employee assignments:

Path: DELETE /public-api/v1/org-item-person-edges/by-person

Query parameters:

ParameterTypeRequiredDescription
personIdUUID📎Employee ID
externalPersonIdstring📎External employee ID

Response structure:

{
    "deleted": true,
    "id": "e5f6g7h8-i9j0-1234-efgh-567890123456",
    "message": "OrgItemPersonEdge успешно удален"
}

Deletion conditions:

  • ✅ An assignment can be revoked at any time
  • ✅ When all of an employee's assignments are deleted, the employee becomes unassigned
  • ✅ When an assignment is deleted, the position remains vacant

Important

Deleting an assignment does not delete the employee or the position. Only the link between them is removed.


Recommended Work Scenarios

Initial Creation of the Org Structure

  1. Create OrgItems (positions and groups)
  2. Create OrgItemEdges (subordination links)
  3. Create Person (employees)
  4. Create OrgItemPersonEdge (assignments to positions)

Updating Attributes (Without Changing Links)

  • OrgItem/Person: update via the corresponding method with externalId

Updating Links (OrgItemEdges, OrgItemPersonEdge)

  1. Ensure that the required sourceId, targetId, personId are created and up to date
  2. Update the corresponding links

Deleting Structure Elements (OrgItem, Person)

  1. Delete all associated bindings
  2. Delete OrgItem/Person

Deleting Links (OrgItemEdges, OrgItemPersonEdge)

  1. Delete/modify all dependent bindings via sourceId, targetId, personId
  2. Delete OrgItemEdges/OrgItemPersonEdge