Instruments represent any physical, digital, or logical intermediary between an entity and a transaction event.

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

ENDPOINT

DESCRIPTION

POST /instruments/create

Creates an instrument.

PUT /instruments/<unit21_id>/update

Updates an existing instrument.

GET /instruments/<unit21_id>

Retrieves an existing instruments.

POST /instruments/list

Retrieves a list of all instruments.

Batch Instrument Requests

The /instruments/create API accepts batch uploads:

  • each batch must contains no more than 250 instruments,
  • and the total size of the POST body must be smaller than 100mb.
curl -X POST \
  https://<API_ENDPOINT>/v1/instruments/create \
  -H 'Content-Type: application/json' \
  -H 'u21-key: <YOUR_API_KEY>' \
  -d '{
        "instruments": [
          {
            "instrument_id": "3234-sdghfdf-3332",
            "instrument_type": "account",
            "source": "internal",
            "status": "active",
            "registered_at": 1572672326,
            "parent_instrument_id": "3234-sdghfdf-3331",
            "custom_data": {
              "activated_at": 1572679326
            }
          },
          {
            "instrument_id": "3234-dfsasfr-3334",
            "instrument_type": "account",
            "source": "internal",
            "status": "dormant",
            "registered_at": 1572672326,
            "parent_instrument_id": "3234-sdghfdf-3331",
            "custom_data": {
              "activated_at": 1572679326
            }
          }
        ]
      }'

When uploading a batch of instruments, any instrument-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": "Unexpected field `instrument_idd`"
}

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

HTTP/1.1 200 OK
Content-Type: application/json
{
  "count": 2,
  "instruments": [
    {
      "instrument_id": "3234-sdghfdf-3332",
      "unit21_id": "49073",
      "previously_existed": false
    },
    {
      "instrument_id": "3234-dfsasfr-3334",
      "unit21_id": "49074",
      "previously_existed": true
    }
  ]
}

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

Placeholder Instruments

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 instrument 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": "Unexpected field `instrument_idd`"
}

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 Instrument

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

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
{
    "ignored": true,
    "instrument_id": "instrumentA-38f8e0Rwdf63nld71112345132UeUKFWE123",
    "previously_existed": true,
    "unit21_id": "687022319"
}

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 instrument cannot be overwritten.

curl -X POST \
  https://<API_ENDPOINT>/v1/instruments/create \
  -H 'Content-Type: application/json' \
  -H 'u21-key: <YOUR_API_KEY>' \
  -d '{
    "instrument_id": "instrumentA-38f8e0Rwdf63nld71112345132UeUKFWE123",
    "instrument_type": "account",
    "source": "internal",
    "status": "activated_nitro",
    "registered_at": 1572672326,
    "location_data": {
        "building_number": "222333",
        "street_name": "Peachtree Place",
        "city": "Atlanta",
        "state": "GA",
        "postal_code": "30318",
        "country": "US"
    },
    "options": {
        "upsert_on_conflict": false
    }
  }'
HTTP/1.1 409 BAD CONFLICT
Content-Type: application/json
{
    "error_code": "duplicate resource",
    "message": "Instrument with id instrumentA-38f8e0Rwdf63nld71112345132UeUKFWE123 already exists",
    "unit21_id": "687022319"
}

Delete Instruments

Deleting instruments is not allowed.

Options for the Endpoint

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

The following fields are options for the endpoint:

Field

Type

Description

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.

list_merge_strategy

String

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

upsert_on_conflict

Boolean

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 instrument cannot be overwritten.

merge_custom_data

Boolean

Only relevant for updates/upserts, ignored otherwise.