Migration Guide: The New Entity-Role Model
Overview
The TradeVest API has been restructured to improve clarity and separation of concerns. The monolithic customers.yaml
has been split into two specialized APIs:
entities.yaml: Manages entity data (natural persons, legal entities, joint persons, beneficial owners, legal representatives)
roles.yaml: Manages role assignments (customers, proxies)
Quick Reference: Endpoint Mapping
General
GET /partner-details
GET /v2/partner-details
✏️ Path change
Natural Persons
GET /natural-persons
GET /entities/natural-persons
✏️ Path change
POST /natural-persons
POST /entities/natural-persons
✏️ Path change
GET /natural-persons/{id}
GET /entities/natural-persons/{id}
✏️ Path change
PATCH /natural-persons/{id}
PATCH /entities/natural-persons/{id}
✏️ Path change
POST /natural-persons/{id}/identification
POST /entities/natural-persons/{id}/identification
✏️ Path change
Beneficial Owners
POST /customers/natural-persons/{customerId}/beneficial-owners
POST /entities/{legalEntityId}/beneficial-owners
GET /customers/natural-persons/{customerId}/beneficial-owners
GET /entities/{legalEntityId}/beneficial-owners
GET /customers/natural-persons/{customerId}/beneficial-owners/{id}
GET /entities/beneficial-owners/{id}
PATCH /customers/natural-persons/{customerId}/beneficial-owners/{id}
PATCH /entities/beneficial-owners/{id}
Important: Beneficial owners are now associated directly with legal entities, not with customer roles.
Legal Entities
POST /customers/legal-entities
🔀 Split → ➕ POST /entities/legal-entities
+ POST /roles/customers
🔄 Breaking change
GET /customers/legal-entities/{customerId}
GET /roles/customers/{customerId}
(role data) + GET /entities/legal-entities/{id}
(entity data)
🔄 Breaking change
PATCH /customers/legal-entities/{customerId}
PATCH /roles/customers/{customerId}
+ PATCH /entities/legal-entities/{id}
🔄 Breaking change
GET /customers/vendor/search/legal-entities
GET /entities/vendor/legal-entities
✏️ Path change
POST /customers/vendor/prepare/legal-entities
POST /entities/vendor/legal-entities
✏️ Path change
GET /customers/vendor/prepare/legal-entities/{searchId}
GET /entities/vendor/legal-entities/{searchId}
✏️ Path change
Important: Legal entities are now independent entities with their own UUID and status, no longer embedded as customer sub-objects. They have dedicated endpoints for full CRUD operations.
Legal Representatives
Inline in POST /customers/legal-entities
➕ POST /entities/{legalEntityId}/legal-representatives
🔄 Breaking change
Inline in GET /customers/legal-entities/{id}
➕ GET /entities/{legalEntityId}/legal-representatives
🔄 Breaking change
Inline in PATCH /customers/legal-entities/{id}
➕ GET /entities/legal-representatives/{id}
🔄 Breaking change
-
➕ PATCH /entities/legal-representatives/{id}
➕ New endpoint
-
➕ DELETE /entities/legal-representatives/{id}
➕ New endpoint
Important: Legal representatives are no longer embedded in legal entity payloads. They have dedicated endpoints for full CRUD operations.
Joint Persons
POST /customers/joint-persons
🔀 Split → ➕ POST /entities/joint-persons
+ POST /roles/customers
🔄 Breaking change
GET /customers/joint-persons/{customerId}
🔀 Split → ➕ GET /roles/customers/{customerId}
+ GET /entities/joint-persons/{id}
🔄 Breaking change
PATCH /customers/joint-persons/{customerId}
PATCH /roles/customers/{customerId}
+ PATCH /entities/joint-persons/{id}
🔄 Breaking change
-
GET /entities/joint-persons
➕ New endpoint
Important: Joint persons are now independent entities with their own UUID and status, no longer embedded as customer sub-objects. They require separate entity creation and customer role assignment.
Customers (Role Management)
GET /customers
GET /roles/customers
🔄 Breaking change
GET /customers/{customerId}
GET /roles/customers/{customerId}
✏️ Path change
POST /customers/natural-persons
🔀 Split → ➕ POST /entities/legal-entities
+ POST /roles/customers
🔄 Breaking change
POST /customers/joint-persons
🔀 Split → ➕ POST /entities/joint-persons
+ POST /roles/customers
🔄 Breaking change
PATCH /customers/natural-persons/{customerId}
PATCH /roles/customers/{customerId}
✏️ Path change
PATCH /customers/joint-persons/{customerId}
PATCH /roles/customers/{customerId}
✏️ Path change
Proxies
GET /proxies
GET /roles/proxies
✏️ Path change
GET /proxies/{proxyId}
GET /roles/proxies/{proxyId}
✏️ Path change
PATCH /proxies/{proxyId}
PATCH /roles/proxies/{proxyId}
✏️ Path change
Customer Labels
GET /customer-labels
GET /roles/customer-labels
✏️ Path change
PATCH /customer-labels/{labelName}
PATCH /roles/customer-labels/{labelName}
✏️ Path change
DELETE /customer-labels/{labelName}
DELETE /roles/customer-labels/{labelName}
✏️ Path change
PATCH /customer-labels/{labelName}/customers
PATCH /roles/customer-labels/{labelName}/customers
✏️ Path change
POST /customer-labels/{labelName}/customers
POST /roles/customer-labels/{labelName}/customers
✏️ Path change
Identification Verification
POST /identification-verifications
POST /entities/identification-verifications
✏️ Path change
GET /identification-verifications
GET /entities/identification-verifications
✏️ Path change
GET /identification-verifications/{id}
GET /entities/identification-verifications/{id}
✏️ Path change
Documents
GET /documents/{id}
GET /v2/documents/{id}
✏️ Path change
GET /documents/{id}/file
GET /v2/documents/{id}/file
✏️ Path change
POST /documents/sign
POST /v2/documents/sign
✏️ Path change
Important: Document model has changed - entityType
→ resourceType
with new enum values and improved resource categorization.
Onboarding & Offboarding (Centralized → Distributed)
POST /onboardings
POST /entities/onboardings
OR POST /roles/onboardings
OR POST /user-onboardings
GET /onboardings
GET /entities/onboardings
OR GET /roles/onboardings
OR GET /user-onboardings
GET /onboardings/{id}
GET /entities/onboardings/{id}
OR GET /roles/onboardings/{id}
OR GET /user-onboardings/{id}
GET /offboardings/{id}
GET /entities/offboardings/{id}
OR GET /roles/offboardings/{id}
DELETE /offboardings/{id}
DELETE /entities/offboardings/{id}
OR DELETE /roles/offboardings/{id}
Important: Onboarding is now dorelease-test-specific. Use entities.yaml
for entity onboarding (beneficial owners), roles.yaml
for role onboarding (customers, proxies) and users.yaml
for user onboarding..
Search NACE Sectors
GET /customers/natural-persons/search/nace-sectors
GET /entities/natural-persons/search/nace-sectors
✏️ Path change
GET /customers/legal-entities/search/nace-sectors
GET /entities/legal-entities/search/nace-sectors
✏️ Path change
Customer Statistics
GET /customers/status-counts
GET /roles/customers/statistics/status-counts
✏️ Path change
Natural Person Wizard (Completely Removed)
POST /customers/natural-persons/wizard
-
❌ Removed
GET /customers/natural-persons/wizard
-
❌ Removed
GET /customers/natural-persons/wizard/{wizardInstanceId}
-
❌ Removed
PATCH /customers/natural-persons/wizard/{wizardInstanceId}
-
❌ Removed
DELETE /customers/natural-persons/wizard/{wizardInstanceId}
-
❌ Removed
Important: Natural person wizard functionality has been completely removed. Use the comprehensive onboarding process available in entities.yaml
and roles.yaml
instead.
New Endpoints (Not Available in customers.yaml)
Entity Management
GET /entities
- Unified view of all entitiesGET /entities/legal-representatives/{id}
- Get specific legal representativePATCH /entities/legal-representatives/{id}
- Update legal representativeDELETE /entities/legal-representatives/{id}
- Delete legal representativePOST /entities/{legalEntityId}/legal-representatives
- Create legal representativeGET /entities/{legalEntityId}/legal-representatives
- List legal representatives
Onboarding & Offboarding
POST /entities/onboardings
- Start entity onboardingGET /entities/onboardings
- List entity onboardingsGET /entities/onboardings/{id}
- Get entity onboardingPOST /entities/offboardings
- Start entity offboardingGET /entities/offboardings
- List entity offboardingsGET /entities/offboardings/{id}
- Get entity offboardingDELETE /entities/offboardings/{id}
- Cancel entity offboarding
Role Onboarding & Offboarding
POST /roles/onboardings
- Start role onboardingGET /roles/onboardings
- List role onboardingsGET /roles/onboardings/{id}
- Get role onboardingPOST /roles/offboardings
- Start role offboardingGET /roles/offboardings
- List role offboardingsGET /roles/offboardings/{id}
- Get role offboardingDELETE /roles/offboardings/{id}
- Cancel role offboarding
User Onboarding
POST /user-onboardings
- Start user onboardingGET /user-onboardings
- List user onboardingsGET /user-onboardings/{id}
- Get user onboarding
Document Management (v2)
GET /v2/documents
- Get documents with new resource modelPOST /v2/documents
- Upload documents with new resource modelGET /v2/documents/{id}
- Get document with new modelGET /v2/documents/{id}/file
- Get document filePOST /v2/documents/sign
- Sign document with new model
Key Model Changes
Beneficial Owner Model
Old Model (customers.yaml):
{
"boType": "REAL_UBO_25",
"share": 30.0,
"uboRelationship": "DIRECTLY_HOLDING_25"
}
New Model (entities.yaml):
{
"share": 30.0,
"votingRights": 30.0,
"uboRelationship": "DIRECTLY_HOLDING_25"
}
Key Changes:
❌ Removed:
boType
field (all beneficial owners are nowREAL_UBO_25
)➕ Added:
votingRights
field (required)✅ Required:
uboRelationship
field is now mandatory
Proxy Model
Old Model (customers.yaml):
{
"customerId": "uuid",
"proxyType": "GENERAL_POWER_OF_ATTORNEY"
}
New Model (roles.yaml):
{
"entityId": "uuid",
"entityType": "NATURAL_PERSON",
"proxyType": "GENERAL_POWER_OF_ATTORNEY"
}
Key Changes:
🔄 Changed:
customerId
→entityId
➕ Added:
entityType
field
Legal Entity Model
Old Model (customers.yaml):
{
"legalName": "Example Corp",
"legalForm": "LIMITED_LIABILITY_COMPANY",
"labels": ["corporate"],
"refAccounts": [...],
"legalRepresentatives": [
{
"firstName": "John",
"lastName": "Doe",
"function": "MANAGING_DIRECTOR"
}
]
}
New Model (entities.yaml + roles.yaml):
// Legal Entity (entities.yaml)
{
"legalName": "Example Corp",
"legalForm": "LIMITED_LIABILITY_COMPANY",
"mainAddress": {...},
"contact": {...}
// NO legal representatives here!
}
// Customer Role (roles.yaml)
{
"entityId": "le-uuid",
"entityType": "LEGAL_ENTITY",
"labels": ["corporate"],
"refAccounts": [...]
}
// Legal Representatives (entities.yaml - separate endpoints)
// GET /entities/{legalEntityId}/legal-representatives
Key Changes:
❌ Removed:
legalRepresentatives
array from legal entity payload🔄 Separated: Customer role data moved to roles.yaml
➕ Added: Dedicated legal representative endpoints
Document Model
Old Model (documents.yaml):
{
"name": "example.pdf",
"entityType": "CUSTOMER",
"entityId": "customer-uuid",
"type": "ONBOARDING"
}
New Model (documents.yaml v2):
{
"name": "example.pdf",
"resourceType": "CUSTOMER",
"resourceId": "customer-uuid",
"type": "ONBOARDING"
}
Key Changes:
🔄 Renamed:
entityType
→resourceType
🔄 Renamed:
entityId
→resourceId
➕ Added: New resource types (LEGAL_ENTITY in addition to existing ones)
Onboarding Model
Old Model (onboardings.yaml - Centralized):
{
"entityType": "CUSTOMER",
"entityId": "customer-uuid"
}
New Model (entities.yaml + roles.yaml - Distributed):
// Entity Onboarding (entities.yaml)
{
"entityType": "BENEFICIAL_OWNER",
"entityId": "bo-uuid"
}
// Role Onboarding (roles.yaml)
{
"onboardingRoleType": "CUSTOMER",
"roleId": "customer-uuid"
}
// User Onboarding (users.yaml)
{
"userId": "user-uuid"
}
Key Changes:
🔄 Split: Centralized onboarding → dorelease-test-specific onboarding
🔄 Changed: Different parameters for entity vs role vs user onboarding
➕ Added:
onboardingRoleType
field for role onboarding
Practical Migration Examples
1. Creating a Beneficial Owner
Before (customers.yaml):
POST /customers/natural-persons/{customerId}/beneficial-owners
{
"firstName": "John",
"lastName": "Doe",
"boType": "REAL_UBO_25",
"share": 30.0,
"uboRelationship": "DIRECTLY_HOLDING_25"
}
After (entities.yaml):
POST /entities/{legalEntityId}/beneficial-owners
{
"firstName": "John",
"lastName": "Doe",
"share": 30.0,
"votingRights": 30.0,
"uboRelationship": "DIRECTLY_HOLDING_25"
}
2. Creating a Proxy
Before (customers.yaml):
POST /natural-persons/{naturalPersonId}/proxy
{
"customerId": "customer-uuid",
"proxyType": "GENERAL_POWER_OF_ATTORNEY",
"validityType": "UNLIMITED"
}
After (roles.yaml):
POST /roles/proxies
{
"entityId": "entity-uuid",
"entityType": "NATURAL_PERSON",
"proxyType": "GENERAL_POWER_OF_ATTORNEY",
"validityType": "UNLIMITED"
}
3. Creating a Natural Person Customer
Before (customers.yaml) - Two steps:
Step 1: Create Natural Person
POST /natural-persons
{
"firstName": "John",
"lastName": "Doe",
"birthDay": "1990-01-01",
"birthPlace": "Berlin",
"birthCountry": "DE",
"nationalities": ["DE"],
"contact": {
"phone": "+49123456789",
"email": "[email protected]"
},
"mainAddress": {
"street": "Main Street",
"streetNumber": "123",
"city": "Berlin",
"zip": "10115",
"country": "DE"
}
// ... other natural person data
}
Step 2: Create Natural Person Customer
POST /customers/natural-persons
{
"naturalPersonId": "{{naturalPersonId}}",
"labels": ["vip"],
"refAccounts": [...]
}
After (entities.yaml + roles.yaml) - Two steps:
Step 1: Create Natural Person Entity
POST /entities/natural-persons
{
"firstName": "John",
"lastName": "Doe",
"birthDay": "1990-01-01",
"birthPlace": "Berlin",
"birthCountry": "DE",
"nationalities": ["DE"],
"contact": {
"phone": "+49123456789",
"email": "[email protected]"
},
"mainAddress": {
"street": "Main Street",
"streetNumber": "123",
"city": "Berlin",
"zip": "10115",
"country": "DE"
}
// ... other natural person data
}
Step 2: Assign Customer Role
POST /roles/customers
{
"entityId": "{{naturalPersonId}}",
"entityType": "NATURAL_PERSON",
"labels": ["vip"],
"refAccounts": [...]
}
Key Change: Same two-step process, but different API domains:
Before:
/natural-persons
→/customers/natural-persons
After:
/entities/natural-persons
→/roles/customers
4. Creating a Legal Entity Customer
Before (customers.yaml) - Single step:
POST /customers/legal-entities
{
"legalName": "Example Corp",
"legalForm": "LIMITED_LIABILITY_COMPANY",
"labels": ["corporate"],
"refAccounts": [...],
"legalRepresentatives": [...],
// ... all entity + customer data in one payload
}
After (entities.yaml + roles.yaml) - Three steps:
Step 1: Create Legal Entity
POST /entities/legal-entities
{
"legalName": "Example Corp",
"legalForm": "LIMITED_LIABILITY_COMPANY",
"mainAddress": {...},
"contact": {...}
// ... entity data only (NO legal representatives here!)
}
// Response: { "legalEntityId": "le-uuid" }
Step 2: Create Legal Representatives
POST /entities/le-uuid/legal-representatives
{
"firstName": "John",
"lastName": "Doe",
"function": "MANAGING_DIRECTOR",
"soleSignatureAuthorized": true,
// ... legal representative data
}
// Response: { "legalRepresentativeId": "lr-uuid" }
Step 3: Create Customer Role
POST /roles/customers
{
"entityId": "le-uuid",
"entityType": "LEGAL_ENTITY",
"labels": ["corporate"],
"refAccounts": [...]
// ... customer role data only
}
5. Creating a Joint Person Customer
Before (customers.yaml) - Single step:
POST /customers/joint-persons
{
"firstNaturalPersonId": "np1-uuid",
"secondNaturalPersonId": "np2-uuid",
"labels": ["family"],
"refAccounts": [...],
// ... all entity + customer data in one payload
}
After (entities.yaml + roles.yaml) - Two steps:
Step 1: Create Joint Person
POST /entities/joint-persons
{
"firstNaturalPersonId": "np1-uuid",
"secondNaturalPersonId": "np2-uuid",
"contact": {...},
"mainAddress": {...}
// ... entity data only
}
// Response: { "jointPersonId": "jp-uuid" }
Step 2: Create Customer Role
POST /roles/customers
{
"entityId": "jp-uuid",
"entityType": "JOINT_PERSON",
"labels": ["family"],
"refAccounts": [...]
// ... customer role data only
}
6. Managing Legal Representatives
Before (customers.yaml) - Inline in legal entity:
# Legal representatives were included in legal entity payload
POST /customers/legal-entities
{
"legalName": "Example Corp",
"legalRepresentatives": [
{
"firstName": "John",
"lastName": "Doe",
"function": "MANAGING_DIRECTOR",
"soleSignatureAuthorized": true
}
]
}
# Updates also required full legal entity payload
PATCH /customers/legal-entities/{customerId}
{
"legalRepresentatives": [
{
"firstName": "John Updated",
"lastName": "Doe",
"function": "MANAGING_DIRECTOR"
}
]
}
After (entities.yaml) - Dedicated endpoints:
# Create legal representative separately
POST /entities/{legalEntityId}/legal-representatives
{
"firstName": "John",
"lastName": "Doe",
"function": "MANAGING_DIRECTOR",
"soleSignatureAuthorized": true,
"fatcaControllingPerson": false
}
# List legal representatives for entity
GET /entities/{legalEntityId}/legal-representatives
# Update specific legal representative
PATCH /entities/legal-representatives/{legalRepresentativeId}
{
"firstName": "John Updated"
}
# Delete legal representative (new capability!)
DELETE /entities/legal-representatives/{legalRepresentativeId}
7. Uploading Documents
Before (documents.yaml):
POST /documents
Content-Type: multipart/form-data
{
"document": {
"name": "contract.pdf",
"entityType": "CUSTOMER",
"entityId": "customer-uuid",
"type": "CONTRACTS"
},
"file": <binary-data>
}
After (documents.yaml v2):
POST /v2/documents
Content-Type: multipart/form-data
{
"document": {
"name": "contract.pdf",
"resourceType": "CUSTOMER",
"resourceId": "customer-uuid",
"type": "CONTRACTS"
},
"file": <binary-data>
}
8. Starting Onboarding Process
Before (onboardings.yaml - Centralized):
# Customer onboarding
POST /onboardings
{
"entityType": "CUSTOMER",
"entityId": "customer-uuid"
}
# Beneficial owner onboarding
POST /onboardings
{
"entityType": "BENEFICIAL_OWNER",
"entityId": "bo-uuid"
}
# Proxy onboarding
POST /onboardings
{
"entityType": "PROXY",
"entityId": "proxy-uuid"
}
# User onboarding
POST /onboardings
{
"entityType": "PARTNER_USER",
"entityId": "partner-user-uuid"
}
After (entities.yaml + roles.yaml + users.yaml- Distributed):
# Customer role onboarding
POST /roles/onboardings
{
"onboardingRoleType": "CUSTOMER",
"roleId": "customer-uuid"
}
# Beneficial owner entity onboarding
POST /entities/onboardings
{
"entityType": "BENEFICIAL_OWNER",
"entityId": "bo-uuid"
}
# Proxy role onboarding
POST /roles/onboardings
{
"onboardingRoleType": "PROXY",
"roleId": "proxy-uuid"
}
# User onboarding
POST /user-onboardings
{
"userId": "user-uuid"
}
9. Updating a Customer Role
Before (customers.yaml):
PATCH /customers/natural-persons/{customerId}
{
"labels": ["premium", "vip"],
"refAccounts": [
{
"bankName": "Deutsche Bank",
"iban": "DE89370400440532013000",
"bic": "DEUTDEFF",
"type": "PRIMARY"
}
]
}
After (roles.yaml):
PATCH /roles/customers/{customerId}
{
"labels": ["premium", "vip"],
"refAccounts": [
{
"bankName": "Deutsche Bank",
"iban": "DE89370400440532013000",
"bic": "DEUTDEFF",
"type": "PRIMARY"
}
]
}
Key Change: Customer role updates are now separate from entity updates. To update entity data (like address, contact), use the appropriate entity endpoint (/entities/natural-persons/{entityId}
or /entities/legal-entities/{entityId}
).
Migration Checklist
Phase 1: Update Base URLs
Phase 2: Path Updates
Phase 3: Model Updates
Phase 4: Breaking Changes
Legal Representatives: Remove from legal entity payloads, use dedicated endpoints
Creation: Extract from legal entity payload →
POST /entities/{legalEntityId}/legal-representatives
Reading: Get from legal entity response →
GET /entities/{legalEntityId}/legal-representatives
Updates: No longer inline →
PATCH /entities/legal-representatives/{id}
Deletion: New capability →
DELETE /entities/legal-representatives/{id}
Documents: Update to v2 API with new resource model
Upload: Use
/v2/documents
withresourceType
/resourceId
instead ofentityType
/entityId
Query: Update query parameters to use new resource-based filtering
Resource Types: Map old entity types to new resource types
Onboarding Process: Choose appropriate dorelease-test-specific endpoint
Entity Onboarding: Use
/entities/onboardings
for beneficial ownersRole Onboarding: Use
/roles/onboardings
for customers and proxiesUser Onboarding: Use
/user-onboardings
for usersParameters: Update payload structure with new field names
Customer Data Retrieval: Combine data from entity and role endpoints
Customer Updates: Update both entity data and role data separately
Phase 5: New Features
Unified Entity Search: Implement
GET /entities
endpoint for cross-entity searchingLegal Representative Management: Dedicated CRUD endpoints for legal representatives
Joint Person Management: Dedicated CRUD endpoints for joint persons
Legal Entity Management: Dedicated CRUD endpoints for legal entities
Validation Rules Changes
Beneficial Owners
uboRelationship is now required for all beneficial owners
votingRights is now required (0-100%, multiple of 0.01)
For
DIRECTLY_HOLDING_25
orINDIRECTLY_HOLDING_25
: either share OR voting rights must be ≥ 25%For
DOMINANT_INFLUENCE_OVER_SHARE_CAPITAL
: no minimum requirements
New Webhook Notifications
The entity-role architecture introduces several new webhook notifications to support the distributed model:
Entity-Related Webhooks (New)
/joint-person-notification
Joint Person lifecycle events
Joint Persons
/legal-entity-notification
Legal Entity lifecycle events
Legal Entities
/legal-representative-notification
Legal Representative lifecycle events
Legal Representatives
/legal-entity-search-notification
Legal Entity search process updates
Legal Entity Search
Process-Related Webhooks (New)
/offboarding-notification
Offboarding process updates
Entity and role offboarding events
Enhanced Existing Webhooks
/customer-notification
Role-focused
Now specifically for customer role events
/proxy-notification
Entity-aware
Now supports entity-based proxy relationships
/beneficial-owner-notification
Entity-focused
Now directly associated with legal entities
Notification Types
All new webhooks support standard notification types:
CREATED
- Entity/role was createdUPDATED
- Entity/role was updatedDELETED
- Entity/role was deletedVALIDATION_ERROR
- Validation failed
Migration Impact: Update your webhook handlers to support the new entity-focused notifications and ensure proper handling of the distributed event model.
Additional Resources
Check the detailed API reference in
entities.yaml
,roles.yaml
,documents.yaml
, andonboardings.yaml
Review the comprehensive architectural changes in the main README
Test your migration against the new endpoints in the test environment
Consult
webhooks.yaml
for notification updates
Legend:
✏️ Simple path change
🔄 Breaking change requiring code updates
➕ New endpoint/feature
❌ Removed field/endpoint
🔀 Split into multiple endpoints
✅ New requirement
Last updated