Corporate & Individuals
To onboard a business customer (KYB), you work with two entity types:
- A Corporate represents the legal entity you intend to onboard.
- An Individual represents a natural person connected to a Corporate - for example a legal representative, a shareholder, or the Business Contact.
An Individual is not a Person. A Person is a retail end-user onboarded through KYC. An Individual exists only in the context of a Corporate and is onboarded as part of the KYB process. Individuals have their own API resources (documents, questionnaires, responses).
This page covers how to create a Corporate, create its Individuals, and link them together with roles - the prerequisites for triggering KYB Onboarding.
Creating a Corporate
Endpoint: POST /corporates
Request Body
Send a JSON object with the following fields:
| Field | Type | Required | Notes |
|---|---|---|---|
external_id | String | Yes | Your reference ID in your own system (e.g., UUID). |
full_title | String | Yes | The corporate's official registered name. |
legal_form | String | Yes | Legal form (e.g., GmbH). |
register_code | String | Yes | Commercial register number (e.g., HRB 123456). |
register_court | String | Yes | Court holding the commercial register entry. |
incorporation_date | Date | Yes | Format: YYYY-MM-DD. |
lei | String | No | Legal Entity Identifier (LEI). Omit if not available. |
website | String | Yes | The corporate's website. |
street_name | String | Yes | Registered address street name. |
street_number | String | Yes | Registered address street number. |
zip_code | String | Yes | Postal code of the registered address. |
seat_location | String | Yes | City or location of the registered seat. |
country | String | Yes | ISO 3166-1 alpha-3 (e.g., DEU). |
tax_id | String | Yes | Tax identifier of the corporate. |
tax_country | String | Yes | ISO 3166-1 alpha-3. |
banking_country | String | Yes | ISO 3166-1 alpha-3. |
The request is rejected with 409 Conflict if:
- a Corporate with the same
external_idalready exists, or - a Corporate with the same combination of
full_title,legal_form, andregister_codealready exists (the comparison ignores case and surrounding whitespace).
Example Request
View cURL Request
curl -X POST https://<kyc_domain>/api/v1/corporates \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"external_id": "CORP-2041-XA",
"full_title": "Beispiel Markets GmbH",
"legal_form": "GmbH",
"register_code": "HRB 123456",
"register_court": "Amtsgericht Frankfurt am Main",
"incorporation_date": "2015-06-30",
"lei": "5493000IBP32UQZ0KL24",
"website": "https://www.example.com",
"street_name": "Bundesstraße",
"street_number": "32",
"zip_code": "60596",
"seat_location": "Frankfurt",
"country": "DEU",
"tax_id": "AB1234567890",
"tax_country": "DEU",
"banking_country": "DEU"
}'
Example Response
View JSON Response
{
"id": "8f6a2c1e-3b7d-4e29-9c41-5a0d8e7f1b23",
"external_id": "CORP-2041-XA",
"full_title": "Beispiel Markets GmbH",
"legal_form": "GmbH",
"register_code": "HRB 123456",
"register_court": "Amtsgericht Frankfurt am Main",
"incorporation_date": "2015-06-30",
"lei": "5493000IBP32UQZ0KL24",
"website": "https://www.example.com",
"street_name": "Bundesstraße",
"street_number": "32",
"zip_code": "60596",
"seat_location": "Frankfurt",
"country": "DEU",
"tax_id": "AB1234567890",
"tax_country": "DEU",
"banking_country": "DEU",
"created_at": "2026-08-01T09:12:44.120000Z",
"updated_at": null
}
Reading Corporates
| Method | Endpoint | Description |
|---|---|---|
GET | /corporates | Paginated list of all created corporates. |
GET | /corporates/{corporate_id} | Get a corporate by its ID. |
GET | /corporates/external/{external_id} | Get a corporate by your own reference ID. |
Creating Individuals
Create one Individual for every natural person that must be attached to the Corporate - the Business Contact, legal representatives, and beneficial owners.
Endpoint: POST /individuals
Request Body
| Field | Type | Required | Notes |
|---|---|---|---|
external_id | String | Yes | Your reference ID in your own system. |
first_name | String | Yes | |
middle_name | String | No | |
last_name | String | Yes | |
nationality | String | No | ISO 3166-1 alpha-3 (e.g., DEU). |
other_nationalities | List[String] | No | Array of ISO 3166-1 alpha-3 codes. |
gender | Integer | Yes | ISO/IEC 5218: 0 (unknown), 1 (male), 2 (female), 9 (not specified). |
birth_country | String | Yes | ISO 3166-1 alpha-3. |
birth_place | String | Yes | City/place of birth. |
birth_date | Date | Yes | Format: YYYY-MM-DD. The individual must be at least 18 years old. |
street_name | String | Yes | |
street_number | String | Yes | |
city | String | Yes | |
postal_code | String | Yes | |
region | String | No | Region or state. |
country | String | Yes | ISO 3166-1 alpha-3. |
phone | String | No | E.164 format (e.g., +49301234567). |
email | String | No | |
tax_identification_number | String | Yes | |
tax_country | String | Yes | ISO 3166-1 alpha-3. |
Compared to a Person, the contact and nationality fields (nationality, phone, email) are optional for an Individual. A request with a duplicate external_id is rejected with 409 Conflict; a birth_date younger than 18 years is rejected with a validation error.
Bulk creation
Endpoint: POST /individuals/bulk
Accepts a JSON array of Individual objects and processes them atomically - if any entry is invalid, none are created.
Reading Individuals
| Method | Endpoint | Description |
|---|---|---|
GET | /individuals | Paginated list. |
GET | /individuals/{individual_id} | Get an individual by ID. |
GET | /individuals/external/{external_id} | Get an individual by your own reference ID. |
GET | /individuals/{individual_id}/pending_requirements | Pending questionnaires for this individual (see Pending Requirements). |
Individuals also have their own document and questionnaire response endpoints under /individuals/{individual_id}/..., used during KYB onboarding.
Linking Individuals to a Corporate
Every Individual must be linked to the Corporate with one or more roles before onboarding can start.
Endpoint: POST /corporates/{corporate_id}/individual_links
Request Body
{
"individual_id": "1f77c9a4-0b3e-4d12-8a6f-2e9b5c4d7a10",
"roles": ["business_contact", "legal_representative"]
}
Returns 201 Created with the individual, its roles, and the link creation time. Fails with 409 Conflict if the individual is already linked to this corporate, and 404 if the corporate or individual does not exist.
Bulk linking
Endpoint: POST /corporates/{corporate_id}/individual_links/bulk
Accepts a JSON array of link objects (as above) and processes them atomically - an unknown individual or an already-linked individual fails the whole request.
Reading links
| Method | Endpoint | Description |
|---|---|---|
GET | /corporates/{corporate_id}/individual_links | Paginated list of linked individuals with their roles. |
GET | /corporates/{corporate_id}/individual_links/{individual_id} | One linked individual with the roles they hold. |
Available roles
| Role | Description |
|---|---|
business_contact | The Business Contact - the corporate's operational point of contact. Exactly one is required; this individual provides identity verification data during onboarding. |
legal_representative | A person legally authorized to represent the company (e.g., managing director). |
shareholder | A natural person holding shares/voting rights - treated as an Ultimate Beneficial Owner (UBO). |
beneficiary | A beneficiary (e.g., of a trust or foundation) - treated as a UBO. |
fictitious_ubo | A senior managing official recorded when no natural person qualifies as a UBO. |
trustee | Trustee of a trust. |
settlor | Settlor of a trust. |
appointor | Appointor of a trust. |
member | Member (e.g., of an association or governing body). |
sole_trader | The natural person behind a sole trader / sole proprietorship. |
general_partner | General partner in a partnership. |
limited_partner | Limited partner in a partnership. |
fund_administrator | Administrator of a fund. |
fund_manager | Manager of a fund. |
An individual can hold multiple roles. Individuals holding shareholder, beneficiary, or fictitious_ubo roles are treated as beneficial owners and undergo verification and compliance screening during onboarding.
The role structure is validated when KYB onboarding starts. Onboarding fails immediately unless all of the following hold across the corporate's linked individuals:
- There is exactly one
business_contact. - There is at least one
legal_representative. - There is at least one of
shareholder,beneficiary, orfictitious_ubo. fictitious_ubois mutually exclusive withshareholderandbeneficiary- a corporate cannot have both a real and a fictitious UBO.
A violation results in an entitlementFailed webhook whose details.reason describes the failed rule.
Triggering Entitlements
Creating a Corporate, its Individuals, and their links does not automatically start onboarding.
To begin the KYB process, trigger the onboarding entitlement for this Corporate ID.