Entities are typically businesses or users that have transactions on your platform.

The /entities endpoint can create, list, and update entities.

ENDPOINT

DESCRIPTION

GET /entities

Retrieves an existing entity.

POST /entities/list

Retrieves a list of all entities.

POST /entities/create

Creates an entity.

PUT /entities/<unit21_id>/update

Updates an existing entity.

PUT /entities/<unit21_id>/add-instruments

Adds instrument to an entity.

PUT /entities/<unit21_id>/link-media

Adds media objects to an entity.

Create Entity

We recommend that you create entities prior to running verification.

In the event you wish to run a verification on an entity immediately, Unit21 recommends that you wait at-least 2 minutes for your entity data to be securely stored.

You will receive a 423 error code if an entity is busy.

Batch Entity Requests

The /entities/create API accepts batch uploads:

  • each batch must contains no more than 250 entities,
  • and the total size of the POST body must be smaller than 100mb.
curl -X POST \
  https://<API_ENDPOINT>/v1/entities/create \
  -H 'Content-Type: application/json' \
  -H 'u21-key: <YOUR_API_KEY>' \
  -d '{
        "entities": [
          {
            "general_data": {
                "entity_id": "371c4d7b-0563-4685-aab1",
                "entity_type": "user",
                "entity_subtype": "payments",
                "status": "active",
                "registered_at": 1572673226
            },
            "user_data": {
                "first_name": "John",
                "middle_name": "Joseph",
                "last_name": "Smith",
                "day_of_birth": 14,
                "month_of_birth": 1,
                "year_of_birth": 1983,
                "gender": "male",
                "ssn": "733-99-5921"
            }
          },
          {
            "general_data": {
              "entity_id": "371c4d7b-0563-4685-aab2",
              "entity_type": "business",
              "entity_subtype": "payments",
              "status": "active",
              "registered_at": 1572673226
            },
            "business_data": {
              "business_name": "Global Liquids LLC",
              "corporate_tax_id": "434-455-3167",
              "account_holder_name": "John Smith",
              "registered_state": "CA",
              "registered_country": "US",
              "doing_business_as": "Global Liquids LLC"
            }
          }
        ],
        "options": {
          "identity_verifications": {
            "workflow_id": "sanctions_check_1",
            "run_verifications": true,
            "synchronous_response": false
          },
          "upsert_on_conflict": true,
          "resolve_geoip": true,
          "merge_custom_data": true,
          "list_merge_strategy": "union"
        }
      }'

When uploading a batch of entities, any entity-level options will be ignored; only the top-level options provided will be used.

If there are any data validation errors in the data that is passed (such as missing required fields) the entire batch request will fail with a 400 response code.

HTTP/1.1 400 BAD REQUEST
Content-Type: application/json
{
    "error_code": "invalid_input",
    "message": "Missing required field `general_data`"
}

The response contains a count of all the entities processed in the batch along with a list of objects containing three fields. The list allows you to map the entity_id passed to our API with our internal unit21_id. The response also indicates whether this entity previously existed or not.

HTTP/1.1 200 OK
Content-Type: application/json
{
  "count": 2,
  "entities": [
    {
      "entity_id": "371c4d7b-0563-4685-aab1",
      "unit21_id": "43247",
      "previously_existed": false
    },
    {
      "entity_id": "371c4d7b-0563-4685-aab2",
      "unit21_id": "43248",
      "previously_existed": true
    }
  ]
}

For entities that previously already existed in our system, previously_existed will be true. Unlike the /entities/update API, Unit21 will not update the entity with the newly provided fields, nor will it insert a new entity into our system.

Unit21 will execute the desired verification workflows on all entities in the provided batch, regardless of whether they previously existed in our system or not.

Placeholder Entities

When creating an entity using the /entities/create endpoint, you may include instrument objects as such:

curl -X POST \
  https://<API_ENDPOINT>/v1/entities/create \
  -H 'Content-Type: application/json' \
  -H 'u21-key: <YOUR_API_KEY>' \
  -d '{
    "general_data": {
      "entity_id": "371c4d7b-0563-4685-aab1",
      "entity_type": "user",
      "entity_subtype": "payments",
      "status": "active",
      "registered_at": 1572673226
    },
    "user_data": {
      "first_name": "John",
      "middle_name": "Joseph",
      "last_name": "Smith",
      "day_of_birth": 14,
      "month_of_birth": 1,
      "year_of_birth": 1983,
      "gender": "male",
      "ssn": "733-99-5921"
    },
    "instrument_ids": [
      "3234-sdghfdf-3332"
    ]
  }'

In this case, a placeholders for instrument with instrument_id=3234-sdghfdf-3332 will be created if its is not already in the Unit21 system.

Unit21's system creates placeholders for entities, instruments, or events that we expect to eventually be inserted in the system but don't yet exist.

When the details are later provided through the /entities/create, /instruments/create, or /events/create APIs, the placeholder objects are populated with the newly provided information.

if a placeholder entity is updated and there are any field value mismatches a 400 error code will be returned.

HTTP/1.1 400 BAD REQUEST
Content-Type: application/json
{
    "error_code": "invalid_input",
    "message": "Missing required field `business_data` for business type entity userA-38f8e0Rwdf6"
}

It does not matter whether you insert events and instruments before their corresponding entities or insert entities before their corresponding events and instruments. It is more important that the object be populated with relevant information at some point in time so that your fraud investigators can be more effective.

Upsert Entity

If the /entities/create API is called for an entity that already exists in the Unit21 system (i.e. has an existing entity_id), we treat it as an upsert and perform an update on the existing entity.

The response to the request will then contain the field previously_existed: true.

Note that we selectively ignore upserts if the request is identical to the last received update to that resource. The response to any upsert that is skipped will then contain the entry ignored: true:

HTTP/1.1 200 OK
Content-Type: application/json
{
    "entity_id": "userA-38f8e0Rwdf63nld71112345132UeUKFWE123",
    "ignored": true,
    "previously_existed": true,
    "unit21_id": "460500201"
}

If you wish for the API to perform strict validation and not perform an upsert on conflict, specifying options.upsert_on_conflict: false will result in the API responding with a 409 error code indicating that this entity cannot be overwritten.

curl -X POST \
  https://<API_ENDPOINT>/v1/entities/create \
  -H 'Content-Type: application/json' \
  -H 'u21-key: <YOUR_API_KEY>' \
  -d '{
    "general_data": {
        "entity_id": "userA-38f8e0Rwdf63nld71112345132UeUKFWE123",
        "entity_type": "user"
    },
    "user_data": {
        "first_name": "John",
        "middle_name": "Smith",
        "last_name": "Smith"
    },
    "options": {
        "upsert_on_conflict": false
    }
  }'
HTTP/1.1 409 BAD CONFLICT
Content-Type: application/json
{
    "error_code": "duplicate resource",
    "message": "Entity with id userA-38f8e0Rwdf63nld71112345132UeUKFWE123 already exists",
    "unit21_id": "460500201"
}

Modifying Entity Tags

Modifying an entity's tags can be achieved through the /entities/update endpoint (or via implicit upserts through /entities/create).

curl -X POST \
  https://<API_ENDPOINT>/v1/entities/create \
  -H 'Content-Type: application/json' \
  -H 'u21-key: <YOUR_API_KEY>' \
  -d '{
    "general_data": {
      "entity_id": "371c4d7b-0563-4685-aab1",
      "entity_type": "user",
      "tags": [
        "account_type:market2",
        "sector:europe"
      ]
    }
  }'

Entity-associated tags are considered as list-types on objects, so the standard list merge strategies apply. By default, newly specified tags in a request are unioned with the existing tags on the entity.

Tag deletion can either be achieved with the replace (full replace of the entire list) or difference (set-difference) list merge strategies.

Risk Scores

If provided, the risk_scores section can either be:

  • an Risk Score object of the fields "name" (required), "score" (required), "denominator" (optional)
  • an array consisting of multiple Risk Score objects
curl -X POST \
  https://<API_ENDPOINT>/v1/entities/create \
  -H 'Content-Type: application/json' \
  -H 'u21-key: <YOUR_API_KEY>' \
  -d '{
    "risk_scores": [
        {
          "name": "risk_score1",
          "score": 100
        },
        {
          "name": "risk_score2",
          "score": 5,
          "denominator": 100
        }
      ]
  }'

The denominator is not required but it is better to provide it in order to avoid ambiguity.

For example, if a denominator is not provided and a score of 50 is provided, a denominator of 100 is assumed. If a score of 150 is provided, a denominator of 1000 is assumed.

Note that it is possible for the "score" input to be negative. Upon submitting the entity risk score, two checks will be made:

  • Is the parameter "score" less than or equal to the "denominator" value?
  • Is the absolute value of (score / denominator) <= 1?

The above two checks must pass as part of the input validation.

These risk scores can be used in the custom Risk Score formula.

Whitelisted Entities

Whitelisted entities in the system are entities that can be exempted from models/rules.

Whitelisted entities cannot be updated through the /entities/create or the /entities/update endpoint.

If you attempt to update a whitelisted entity via the /entities/create endpoint (whether bulk or not), an additional field ignored: true will be returned in the response. The entity will not be updated.

Delete Entities

Deleting entities is not allowed.

Options for the Endpoint

curl -X POST \
  https://<API_ENDPOINT>/v1/entities/create \
  -H 'Content-Type: application/json' \
  -H 'u21-key: <YOUR_API_KEY>' \
  -d '{
    "options": {
      "identity_verifications": {
        "workflow_id": "sanctions_check_1",
        "run_verifications": true,
        "synchronous_response": false
      },
      "resolve_geoip": true,
      "upsert_on_conflict": true,
      "merge_custom_data": true,
      "list_merge_strategy": "union"
    }
  }'

The following fields are options for the endpoint:

Field

Type

Description

workflow_id

String

A unique identifier defined during workflow creation. Note that some workflows do not allow for synchronous responses.

run_verifications

Boolean

Whether or not to execute a verification workflow for the uploaded entity/entities.

synchronous_response

Boolean

Whether or not to immediately execute the workflow & receive a verification response as part of the API request response. If synchronous_response is true for a workflow that doesn't allow synchronous responses, this will throw an error.

include_full_response

String

Include the full, raw, verification results. This option can only be used if synchronous_response is set to true, or a 400 Bad Request will be returned. This is an optional field and will default to false.

resolve_geoip

Boolean

Whether or not to resolve the geographic location from the provided IP address (in the digital data section). Defaults to true if at least one value of an ip_address is provided in digital_data.ip_addresses. If resolve_geoip is set to true but no values are provided in digital_data.ip_addresses, an exception will be thrown. If resolve_geo_ip is set to true but the IP address provided is invalid or cannot be resolved, no exception will be thrown.

merge_custom_data

Boolean

Only relevant for updates/upserts, ignored otherwise. Default is false.

list_merge_strategy

String

Only relevant for updates/upserts, ignored otherwise. Possible values are union, replace, difference. Default is union.