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:
boTypefield (all beneficial owners are nowREAL_UBO_25)➕ Added:
votingRightsfield (required)✅ Required:
uboRelationshipfield 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:
entityTypefield
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-representativesKey Changes:
❌ Removed:
legalRepresentativesarray 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:
onboardingRoleTypefield 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-personsAfter:
/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-representativesReading: Get from legal entity response →
GET /entities/{legalEntityId}/legal-representativesUpdates: 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/documentswithresourceType/resourceIdinstead ofentityType/entityIdQuery: 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/onboardingsfor beneficial ownersRole Onboarding: Use
/roles/onboardingsfor customers and proxiesUser Onboarding: Use
/user-onboardingsfor 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 /entitiesendpoint 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_25orINDIRECTLY_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.yamlReview the comprehensive architectural changes in the main README
Test your migration against the new endpoints in the test environment
Consult
webhooks.yamlfor 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

