The Case Object

Dotfile provide a Case management system where you can organize your KYC/KYB processes. Open case, add new entities in a case, approve or reject the case.

Cases can be seen has folders where you would store all the entities and checks related to a same underlying customer or KYC/KYB process.

Case can be created:

  • via the Console, when a User creates a new Case
  • via the API, creating a case

Case lifecycle


Case lifecycle

  • Open: Entities in the case are under investigation, we collect document, process data, ask questions to them and review all information
  • Approved: Everything is approved, we have process and review all checks are approved. The case (customer) is verified and ready to access your service
  • Rejected: Some checks are rejected and the case (customer) is identify as not compliant and cannot access your service
  • Closed: Entities in the case are not under investigation anymore. Checks and entities will be kept in the event the case is reopened

Case review

To approve or reject a case via the API, you can create a case review:

  • status: "approved", "rejected" or "closed"
  • comment: Optional comment to explain and document the decision. This comment may be required depending on your workspace setting.
  • next_review_at: Optional date to override the date that would be set from your workspace setting and the case risk level at this time or null to not schedule a periodic review for this case.

The review information of the case is then available when retrieving a case and in all case webhook events.

Lean more about the Case approval flow in the product doc

Case Flags

A Case can have different flags that describe a specific state of the case.

  • contact_has_actions When an contact action is required

  • reviewer_has_actions When a reviewer action is required

  • flags: An array containing an ordered set of:

    • all_checks_approved When there is no actions left from any users and all checks are approved.
    • for_review Review is ready for the reviewer, no actions left from the contact.
    • for_first_collect When contact has actions for the first time and need to upload documents or verify it’s identity.
    • for_recollection Recollection is ready for the contact because all checks have been reviewed and there are some recollection needed (checks rejected or expired), no actions left from the reviewer.
    • first_collect_completed When an initial collection is done.

Case ID and External ID

For each case, we provide an auto-generated UUID (v4) but you can add your own external ID when creating a case.

You can find these IDs on the Case header in the console:


External ID must be unique.

Two cases cannot share the same External ID.
If you need to set custom data on a case, please refer to Custom data

Custom Properties

You can define Custom Properties on Case, Company or Individual entities in your Dotfile workspace settings.


Custom Properties will ensure you submit quality value with constraint depending on the type you chose:

  • Choices
  • Countries
  • Date
  • Email
  • Numeric
  • Phone number
  • Text
  • URL
  • Yes/No

You will be able to set custom property values on entities via create (POST) and update (PATCH) endpoints. In the payload, custom_properties is a key-value object where the key is the Custom Property key you can find on your workspace settings and the value must respect the constraint of the property type.

  "name": "Some example case",
  "status": "open",
  "custom_properties": {
    "ubo_us_citizen": true,
    "main_activity_country": ["FR"]

You can set null to reset the value.


A valid array of option key of the Custom Property.

Settings: Allow Multiple

  • true → can have more than one element
  • false → can have only one element
  "custom_properties": {
    "office_location": ["emea"]


A valid array of ISO 3166-1 alpha-2 country code (eg FR).

Settings: Allow Multiple

  • true → can have more than one element
  • false → can have only one element
  "custom_properties": {
    "main_activity_country": ["FR", "GB"]


Date in format ISO 8601 (yyyy-MM-dd eg 2023-01-31)

  "custom_properties": {
    "last_audit": "2022-02-03"


A valid email string with a maximum of 250 characters.

  "custom_properties": {
    "default_email": "[email protected]"


A numeric value that can be formatted as a number, percentage or currency with a currency code and with a maximum and minimum .

  "custom_properties": {
    "yearly_turnover": "20000",

Phone number

A valid (E164) phone number string

  "custom_properties": {
    "default_phone_number": "+33654489875"


A valid string with a maximum of 250-1500 characters.

Settings: isMultiLine

  • single line (isMultiLine=false ) maximum of 250 characters
  • multi line (isMultiLine=true ) maximum of 1500 characters
  "custom_properties": {
    "source_of_funds": "income"


A valid (RFC 3986) URL string

  "custom_properties": {
    "external_link": ""


A boolean (true/false).

  "custom_properties": {
    "ubo_us_citizen": true


You can set key-value data to a case in the metadata property when creating or updating the case. The main use-case is to stored some specific data that could be reuse in your system.

This data is stored as a key-value object where the value are only string:

  "metadata": {
    "custom_key": "true",
    "my_data": "this is important",
    "count": "42"

When updating a case, the metadata in input will override the whole existing metadata object (no merge between existing and new key or value). You can also pass metadata: null to remove all metadata.


Case metadata are always attach to the case object even on context of webhook payload.


Via API, you can push automatic risk on case using the API endpoint Creates an automatic Risk.

Via the Console, you can set manual risk on case.


If you set manual risk on a case, new automatic risk that are pushed on case will be saved but will not be set as the current risk. You need to “enable (back) the automatic risk” on the Console to set it as current.

Risk object

  • level: correspond to the risk level, can be not_defined low medium high prohibited.
  • score: is a number that is the total score calculated for this risk.
  • components: is an object of numbers that contains the details of the score. It helps to understand the risk score and level.
  • flags: is an object of boolean that contains the details of flags for this risk. It helps to understand the risk level.

Example of automatic risk: :

  "level": "medium",
  "score": 10067,
  "components": {
    "customer_score": 1400,
    "product_score": 3000,
    "delivery_channel_score": 2000,
    "transaction_score": 1667,
    "geography_score": 2000
  "flags": {
    "prohibited_country_ubo": true,
    "complex_company_alert": false


If you push the exact same risk than the latest automatic risk, it will not be saved and we will return the latest automatic risk instead (no error from the API).

Case relation

If you need to investigate complex company structure in a case, you can define relation between companies and individuals. This is display as a graph in the Console App.

Complex Company Structure - Dotfile

You can have two types of companies in a case:

  • Main company: this is the unique company at the core of the investigation, you are looking for the UBO of this company
  • Affiliated companies: intermediate companies that could be between the main company and beneficial owners

You can also have individuals that are the Beneficial Owners of the main company or others individuals interesting to investigate (such as Legal representatives or minor shareholders).

Relation object

Case relation object - Dotfile

The relations property on company or individual object is an array of relation like this:

  • to_company_id : describe a relation to the company id
  • from_individual_id or from_company_id : entity the relation comes from
  • ownership_percentage : number (0-100) of the ownership percentage
  • voting_rights_percentage : number (0-100) of the voting rights percentage
  • roles : array of roles (shareholder, legal_representative)
  • position: string of the position to company

Create relation

Via entity (individual, company) creation

For company POST /companies and individual POST /individuals, at the property relations, you can pass a relation object to link the new entity.


You could omit the to_company_id or the relations property and it will implicitly create a relation to the main company.

Example: Payload to create an individual related to an affiliated company

  "case_id": "{{case_id}}",
  "is_business_contact": true,
  "is_beneficial_owner": true,
  "first_name": "Tony",
  "last_name": "Stark",
  "maiden_name": null,
  "email": "[email protected]",
  "ownership_percentage": 33.33,
  "voting_rights_percentage": 33.33,
  "relations": [
      "to_company_id": "{{affiliated_company_id}}",
      "roles": [
      "position": "CEO",
      "ownership_percentage": 33.33,
      "voting_rights_percentage": 33.33

Create/Update/delete relations for existing entities

You could also manage relation via the dedicated CUD endpoints:

You need to specify the to_company_id (if omitted it links to the main company) and the from_individual_id or from_company_id to create the relation.

If you want to change the to_company_id or from_individual_id or from_company_id, you need to create the new relation and delete the old one. The graph cannot have orphan entities so be sure to create relation first.

Total and Direct percentage

Total and Direct percentage - Dotfile

There are two percentage properties:

  • ownership_percentage
  • voting_rights_percentage

You can find them at two levels:

  • On the individual object, there are the Total interest in the main company
  • On relation object, there are the Direct interest in the to_company_id referenced in the relation

We also compute total percentage according to all direct percentage define on relations.