Skip to content
Last updated

👤 Create A New Customer

We support both natural and legal persons (business).

To create a user, follow the steps described below:

1) Collect the user’s basic data

First, collect the basic information on the customer via your website or platform. The following basic data must be collected at a minimum and forwarded to us:

  • First name
  • Last name
  • Type (natural vs legal entity)
  • Street
  • Street number
  • Postal code
  • City
  • Country (ISO)
  • Email address

About the Custodian

Before the beginning of the onboarding phase, we will ask your organization to choose which crypto custodian you will use for your customers' blockchain wallets. These wallets will be the ones holding the tokenized securities. This will determine which datapoints you will send us in key API calls (Create Customer, Save KYC Data, etc.) The custodian options are two-fold:

  • Tangany, our MiCAR-licensed crypto custodian partner.
  • Non-custodial wallets: you can choose to bring us non-custodial wallets (e.g. Web3Auth), or wallets provided by a custodian you already have an integration with.

ℹ️ Important information about our custodian partner Tangany: If you select Tangany as the custodian ( "custodyProvider": 1 ), please note that they only accept residents of the European Union, Iceland, Norway, Switzerland, the United Kingdom, Ukraine and Japan.

We accept investors with non-custodial wallets from across the world, except countries on international sanctioned lists.

ℹ️ Note when Tangany applies: This step relates to the creation POST /customers (basic info + company{}), tanganyLegalPerson and related[] fields are not needed at this creation stage but are passed when needed on each call thereafter.

2) Submit the user's basic data

Send the user's personal information with the following request:

POST customer /api/external/v1/customers

You must specify whether the investor is a natural or a legal person in the type field. For legal persons, you must provide the relevant corporate details. The required legal person data points may vary depending on your configured custody provider.

ℹ️ The optional string fields under tanganyLegalPerson (leiCode, vatId, isinCode) must be omitted entirely when not applicable, not sent as empty strings. Sending empty values "" triggers TanganyCustomerCreationFailed.

Request Example:

# UAT BASE_URL: https://uat.api.nyala.de
# Production BASE_URL: https://api.nyala.de

curl -X POST {{BASE_URL}}/api/external/v1/customers \
-H "Content-Type: application/json" \
-H "Authorization: HMAC YOUR_API_KEY:GENERATED_SIGNATURE" \
-H "Content-Length: CALCULATED_CONTENT_LENGTH" \
-d '{
  "firstname": "John",
  "lastname": "Doe",
  "email": "john.doe@example.com",
  "type": "Person",
  "salutation": "Mr",
  "phoneNumber": "+493012345678",
  "birthDate": "1985-03-20T00:00:00Z",
  "street": "Uhlandstrasse",
  "streetNo": "32",
  "postalCode": "10719",
  "town": "Berlin",
  "countryIso": "DE",
  "nationalityIso": "DE",
  "custodyProvider": 1
}'

The table below describes some of the parameters for a natural person investor.

ParameterDescriptionExpected Values
firstNameFirst name of the investor. When sending values with accents (e.g. É, ç, ñ), send the values in UTF-8 charset."John"
typeWhether the investor is a natural person or a legal entity. Always send "Person" for natural persons."Person"
streetThe street name where the investor resides. When sending values with accents (e.g. É, ç, ñ), send the values in UTF-8 charset."Uhlandstrasse"
townThe town in which the investor resides. When sending values with accents (e.g. É, ç, ñ), send the values in UTF-8 charset."Berlin"
countryIsoThe country ISO code in which the investor resides. Use ISO 3166-1 alpha-2 country codes."DE"
nationalityIsoThe nationality of the investor. Use ISO 3166-1 alpha-2 country codes."DE"
emailThe email which the investor used to register. This must be unique and cannot be reused by other investors."john.doe@example.com"
custodyProviderSet whether the customer's private keys will be held by our custodian partner Tangany. Choosing Tangany requires sending more data fields in the KYC endpoint. You can either send a number or the name of the custodian as a string. Set '1' for Tangany or '0' for external (non-custodial) wallets only.1

The table below describes some of the parameters regarding the basic information for a legal entity representative.

ParameterDescriptionExpected Values
firstNameFirst name of the company representative. Legal requirement: collect at least the beneficial owner's first name and surname."John"
lastNameLast name of representative."Doe"
birthDateBirth date of representative."1985-03-20"
phoneNumberPhone number of representative."+49 30 12345678"
typeAlways send "LegalEntity" for legal persons."LegalEntity"
streetRefers to the address of the representative."Uhlandstrasse"
postalCodeRefers to the address of the representative."10719"
townRefers to the address of the representative."Berlin"
countryIsoRefers to the address of the representative. Expects ISO country code."DE"
nationalityIsoRefers to the nationality of the representative."DE"
genderThe gender of the representative."Male", "Female", "Other", "NotSet"

The table below contains basic company information parameters. These are required for all legal entity investors, regardless of custody choice.

ParameterDescriptionExpected Values
company.nameName of the company."ACME Corporation GmbH"
company.registerNumberRegister number of the company."HRB 12345"
company.fullAddressFull address of the company as a string."Hauptstrasse 10, 10115 Berlin, Germany"
company.emailThe email of the company's representative performing the onboarding. You may re-use the same input as for the representative email."john.doe@company.com"

The parameters in the following tables are relevant only if Tangany is selected as the custodian.

The table below describes some parameters regarding Tangany legal entity (nested under tanganyLegalPerson).

ParameterDescriptionExpected Values
tanganyLegalPerson.idA UUID for the company.UUID value
tanganyLegalPerson.nameThe name of the company. You can re-use the value from company.name."ACME Corporation GmbH"
tanganyLegalPerson.legalFormLegal form of company. E.g. "AG", "GmbH"."GmbH", "AG"
tanganyLegalPerson.commercialRegisterYou may leave it blank. Legally speaking, only the register number is required."Amtsgericht Berlin"
tanganyLegalPerson.leiCodeLEI code of the company."549300ABCDEFGHIJK123"
tanganyLegalPerson.taxIdTax ID of the company."12/345/67890"
tanganyLegalPerson.vatIdVat ID of the company."DE123456789"
tanganyLegalPerson.isincodeISIN code of the company."DE0005140008"
tanganyLegalPerson.legalJurisdictionISO country code (e.g. "DE") where the legal entity is registered. Not mandatory, as this data is captured within the legalAddress object."DE"

The table below describes some parameters regarding Tangany legal entity (nested under 'tanganyLegalPerson.legalAddress).

ParameterDescriptionExpected Values
legalAddress.countryISO country code (e.g. "DE") where the company is registered."DE"
legalAddress.cityCity where company is registered."Berlin"
legalAddress.postcodePost code where company is registered."10115"
legalAddress.streetNameStreet name where company is registered."Hauptstrasse"
legalAddress.streetNumberStreet number where company is registered."10"

The table below describes some parameters regarding Tangany legal entity (nested under 'tanganyLegalPerson.postalAddress).

ParameterDescriptionExpected Values
postalAddress.countryYou may re-use the same data as for the legal address."DE"
postalAddress.cityYou may re-use the same data as for the legal address."Berlin"
postalAddress.postcodeYou may re-use the same data as for the legal address."10115"
postalAddress.streetNameYou may re-use the same data as for the legal address."Hauptstrasse"
postalAddress.streetNumberYou may re-use the same data as for the legal address."10"

The table below describes some parameters regarding Tangany legal entity (nested under 'tanganyLegalPerson.kyc).

ParameterDescriptionExpected Values
kyc.businessDescriptionYou can always send the following value: "Investor"."Investor"
kyc.isCreAvailableYou can always set this field to "false".false

The table below describes some parameters regarding Tangany legal entity (nested under 'tanganyLegalPerson.related).

ParameterDescriptionExpected Values
related.entityIdThe legal requirement is to create one per beneficial owner of the company (even if they do not have to go through the KYC process). Do not supply an entityId when creating new beneficial owners.UUID of beneficial owner
related.positionPosition of the beneficial owner in the company. Takes any string needed."CEO", "Director"
related.isFictitiousBeneficialOwnerIndicates if this is a fictitious beneficial owner.false
related.isUltimateBeneficialOwnerIndicates if this is the ultimate beneficial owner.true
related.sharePercentageShare percentage of ownership. Passed as a string "str""25.5", "100"

Response Example: In response to the successful user creation, you will receive a user ID, which you will need to proceed with the saving of the KYC data, the wallet creation request, and more.

{
    "errorMessageCodes": null,
    "errors": null,
    "data": "42557ea2-8a55-4599-85b2-2a91f343a08b"
}

You can query the customer data via endpoints:

GET customer /api/external/v1/customers/{customerId}

Request Example:

# UAT BASE_URL: https://uat.api.nyala.de
# Production BASE_URL: https://api.nyala.de

# The {customerId} is 42557ea2-8a55-4599-85b2-2a91f343a08b

curl -X GET {{BASE_URL}}/api/external/v1/customers/42557ea2-8a55-4599-85b2-2a91f343a08b \
-H "Authorization: HMAC YOUR_API_KEY:GENERATED_SIGNATURE" \
-H "Content-Length: 0"

Response Example:

{
  "errorMessageCodes": null,
  "errors": null,
  "data":
    {
      "id": "42557ea2-8a55-4599-85b2-2a91f343a08b",
      "firstname": "John",
      "lastname": "Doe",
      "institutionId": "290e614f-4e79-4ba8-8ba3-60a0f7608256",
      "institutionName": "My Institution",
      "salutation": "Mr",
      "type": "Person",
      "birthDate": "1985-03-20T00:00:00Z",
      "title": "",
      "email": "john.doe@example.com",
      "phoneNumber": "+493012345678",
      "walletAccess": "Full",
      "address": {
        "id": "5e062896-9054-470e-b640-5b75380dc49c",
        "street": "Uhlandstrasse",
        "streetNo": "32",
        "postalCode": "10719",
        "town": "Berlin",
        "country": {
          "id": "38913c1d-dd38-494a-80d1-13922dd61d0e",
          "iso": "DE",
          "isoCode3": "DEU",
          "name": "Deutschland"
        }
      },
      "nationalityId": "38913c1d-dd38-494a-80d1-13922dd61d0e",
      "nationalityIso": "DE",
      "gender": "Male",
      "kycData": {
        "title": "",
        "salutation": "Mr",
        "firstname": "John",
        "lastname": "Doe",
        "placeOfBirth": "Germany",
        "dateOfBirth": "1985-03-20T00:00:00Z",
        "email": "john.doe@example.com",
        "phoneNumber": "+493012345678",
        "nonPepPerson": true,
        "highCorruptionIndex": false,
        "nonSanctionedCountry": true,
        "nonUsTaxPerson": true,
        "identVerified": true,
        "identVerifiedType": "Normal",
        "tanganyIdentVerifiedType": "Qes_bankident",
        "eulaAgreed": true,
        "address": {
          "street": "Uhlandstrasse",
          "streetNo": "32",
          "postalCode": "10719",
          "town": "Berlin",
          "countryCodeIso2": "DE"
        },
        "company": null,
        "nationalityIso": "DE",
        "gender": "Male",
        "bic": "",
        "tanganyLegalPerson": null
      },
      "company": null,
      "approvedForMonerium": false,
      "moneriumIban": null,
      "tanganyCustomerId": "12ac5cc7-71b6-46ee-84a7-be70a5afe915",
      "tanganyAuthorizedId": "42557ea2-8a55-4599-85b2-2a91f343a08b",
      "tanganyOwnerId": "42557ea2-8a55-4599-85b2-2a91f343a08b",
    }
}

GET customer /api/external/v1/search

Request Example:

# UAT BASE_URL: https://uat.api.nyala.de
# Production BASE_URL: https://api.nyala.de

# Example with: 
# searchText = "John"
# take = 50
# skip = 0

curl -X GET "{{BASE_URL}}/api/external/v1/customers?searchText=John&take=50&skip=0" \
-H "Authorization: HMAC YOUR_API_KEY:GENERATED_SIGNATURE" \
-H "Content-Length: 0"

Response Example:

{
  "errorMessageCodes": null,
  "errors": null,
  "data": [
    {
      "id": "42557ea2-8a55-4599-85b2-2a91f343a08b",
      "firstname": "John",
      "lastname": "Doe",
      "institutionId": "290e614f-4e79-4ba8-8ba3-60a0f7608256",
      "institutionName": "My Institution",
      "salutation": "Mr",
      "type": "Person",
      "birthDate": "1985-03-20T00:00:00Z",
      "title": "",
      "email": "john.doe@example.com",
      "phoneNumber": "+493012345678",
      "walletAccess": "Full",
      "address": {
        "id": "5e062896-9054-470e-b640-5b75380dc49c",
        "street": "Uhlandstrasse",
        "streetNo": "32",
        "postalCode": "10719",
        "town": "Berlin",
        "country": {
          "id": "38913c1d-dd38-494a-80d1-13922dd61d0e",
          "iso": "DE",
          "isoCode3": "DEU",
          "name": "Deutschland"
        }
      },
      "nationalityId": "38913c1d-dd38-494a-80d1-13922dd61d0e",
      "nationalityIso": "DE",
      "gender": "Male",
      "kycData": {
        "title": "",
        "salutation": "Mr",
        "firstname": "John",
        "lastname": "Doe",
        "placeOfBirth": "Germany",
        "dateOfBirth": "1985-03-20T00:00:00Z",
        "email": "john.doe@example.com",
        "phoneNumber": "+493012345678",
        "nonPepPerson": true,
        "highCorruptionIndex": false,
        "nonSanctionedCountry": true,
        "nonUsTaxPerson": true,
        "identVerified": true,
        "identVerifiedType": "Normal",
        "tanganyIdentVerifiedType": "Qes_bankident",
        "eulaAgreed": true,
        "address": {
          "street": "Uhlandstrasse",
          "streetNo": "32",
          "postalCode": "10719",
          "town": "Berlin",
          "countryCodeIso2": "DE"
        },
        "company": null,
        "nationalityIso": "DE",
        "gender": "Male",
        "bic": "",
        "tanganyLegalPerson": null
      },
      "company": null,
      "approvedForMonerium": false,
      "moneriumIban": null,
      "tanganyCustomerId": "12ac5cc7-71b6-46ee-84a7-be70a5afe915",
      "tanganyAuthorizedId": "42557ea2-8a55-4599-85b2-2a91f343a08b",
      "tanganyOwnerId": "42557ea2-8a55-4599-85b2-2a91f343a08b",
    }
  ]
}

Errors

CaseError codeResponse
Customer already exists (email or guid)400{"errorMessageCodes": ["DuplicateEntity"],"errors": null,"data": "00000000-0000-0000-0000-000000000000"}
Wrong country code either in country iso or natonalityIso400 "errors": "CountryIso": ["The field CountryIso must be a string with a minimum length of 2 and a maximum length of 2."]
User with type = 1 (natural person) has company details included in the API call500"errorMessageCodes": ["AccountTypePersonCannotHaveCompanyDetails"], "errors": null,"data": "00000000-0000-0000-0000-000000000000"
Nationality field contains more than 2 letters404 "errorMessageCodes": ["TanganyCustomerCreationFailed"]
Internal server error retuned when Monerium API is not reachable (very uncommon. Retry later)500"title": "An error occurred while processing your request.", "status": 500