Verification Webhooks

Verification request bodies

Default fields for all webhooks:

Field NameValue TypeDetails
unit21_idNumberA Unit21 internally-assigned unique identifier for the entity within our system
entity_idStringThe ID of the matching entity within your system
object_typeStringAlways takes on the value ENTITY for entity webhooks
changeStringA Unit21-defined value describing the nature of the change to this entity. For more details on this, see above section Change trigger types
change_timeNumberTime the change was triggered in Epoch time format (number of seconds elapsed since 1 Jan 1970 00:00:00 UTC)

Additional fields for VERIFICATION_WORKFLOW_EXECUTED:**

Sample JSON response:

{
  "unit21_id": 1,
  "entity_id": "external_id",
  "object_type": "ENTITY",
  "change": "VERIFICATION_WORKFLOW_EXECUTED",
  "verification_workflow_id": "test-workflow",
  "result": "$ACCEPT",
  "change_time": 123123123,
  "is_success": true,
  "generated_alert": 123,
  "tags": []
}
Field NameValue TypeDetails
verification_workflow_idStringIdentifier for the verification workflow executed for the entity
resultStringTerminal state for the workflow E.g: $ACCEPT, $REJECT, etc.
is_successBooleanBoolean for whether or not the workflow executed without errors
generated_alertNumberID for the alert generated by this workflow if the execution finished in a terminal state marked with Generate Alert
tagsString[]A list of tags that are associated with this entity, always of the format key:value

Additional fields for VERIFICATION_ENTITY_INITIATED:

Sample JSON response

{
  "unit21_id": 1,
  "entity_id": "external_id",
  "object_type": "ENTITY",
  "change": "VERIFICATION_ENTITY_INITIATED",
  "verification_workflow_id": "test-workflow"
}
Field NameValue TypeDetails
verification_workflow_idStringIdentifier for the verification workflow executed for the entity

Additional fields for VERIFICATION_ENTITY_STEP_COMPLETED:

Sample JSON response:

{
  "unit21_id": 1,
  "entity_id": "external_id",
  "object_type": "ENTITY",
  "change": "VERIFICATION_ENTITY_STEP_COMPLETED",
  "verification_workflow_id": "test-workflow",
  "content": { "some_field": "some_value" },
  "step": "PROVIDER:TYPE",
  "change_time": 123123123
}
Field NameValue TypeDetails
verification_workflow_idStringIdentifier for the verification workflow executed for the entity
contentObjectRaw JSON response from the provider. Shape depends on the provider executed in this step
stepStringName of the step completed. Represented as PROVIDER:TYPE. E.G. IDOLOGY:ID_VERIFICATION

Validating webhook request signatures

All Unit21's webhook requests are HTTP API calls that come with a HTTP request header unit21-signature. This header contains a keyed-hash message authentication code (HMAC) with SHA256 for security.

Sample webhook request headers

{
  "content-length": "452",
  "content-type": "application/json",
  "unit21-signature": "t=1582702424,s0=cbe7c96a57abff5e43e1b4b394f85ff6100d062f5bf551142d0527ae3213cfcc"
}
{
  "unit21_id": 123,
  "object_type": "ALERT",
  "alert_id": null,
  "alert_type": "kyc",
  "change": "CLOSED",
  "change_time": 1570062682,
  "disposition": "FALSE_POSITIVE",
  "status": "CLOSED",
  "changed_by": "[email protected]",
  "title": "Sample alert title",
  "description": "Sample alert description",
  "start_date": 1570052582,
  "end_date": 1570062582,
  "entities": [{"entity_id": "entity-886313e1", "entity_type": "user", "unit21_id": 46, "resolution": null}, {"entity_id": "entity-91a31re2", "entity_type": "user", "unit21_id": 72, "resolution": "false_positive"}],
  "events": [{"event_id": "event-1063e4e3e1", "event_type": "transaction", "unit21_id": 111, "resolution": null}],
  "instruments": [{"instrument_id": "instrument-4112950a", "instrument_type": "wallet", "unit21_id": 401, "resolution": null}],
  "triggered_by_rules": [{"unit21_id": 6, "rule_id": null}],
  "assigned_to": "[email protected]",
  "tags": ["rule_type:layering"],
  "custom_data": {"internal_priority": 3}
}

The unit21-signature header contains a timestamp and a signature. The signature (s0) is a hex code generated by using a per-endpoint secret key found on your unit21 webhooks dashboard as a hash key and a message created by concatenating the following in order:

  • timestamp (t) seen in the signature as a string
  • The . character
  • and the actual request body as an un-prettified JSON string

The sample on the right would be represented by this pre-hashed string:

1582702424.{"unit21_id": 123, "object_type": "ALERT", "alert_id": null, "alert_type": "kyc", "change": "CLOSED", "change_time": 1570062682, "disposition": "FALSE_POSITIVE", "status": "CLOSED", "changed_by": "[email protected]", "title": "Sample alert title", "description": "Sample alert description", "start_date": 1570052582, "end_date": 1570062582, "entities": [{"entity_id": "entity-886313e1", "entity_type": "user", "unit21_id": 46}, {"entity_id": "entity-91a31re2", "entity_type": "user", "unit21_id": 72, "resolution": "false_positive"}], "events": [{"event_id": "event-1063e4e3e1", "event_type": "transaction", "unit21_id": 111}], "instruments": [{"instrument_id": "instrument-4112950a", "instrument_type": "wallet", "unit21_id": 401}], "triggered_by_rules": [{"unit21_id": 6, "rule_id": null}], "assigned_to": "[email protected]", "tags": ["rule_type:layering"], "custom_data": {"internal_priority": 3}}

Using secret key 4acff285d1de621a4077 outputs the s0 signature:

c2c035b8759cb142441e7c3a40a7571adbdbb03a63d84c117c6772432e7c1bd9

Note that the secret key and concatenated body are used as UTF-8 encoded strings when generating the HMAC and the digest algorithm is SHA256