Webhook Guide

Enabling the Webhook

To enable the Envoy webhook, you must first specify a webhook endpoint using the $TRISA_WEBHOOK_URL as specified in the “configuration values”. This URL should be available for HTTP POST requests from the Envoy node. If this value is not specified, Envoy will not make any webhook callbacks.

When Envoy receives an incoming travel rule message from a remote counterparty it must return a response to that request (for both TRP and TRISA requests). Envoy may handle the request automatically using accept/reject policies or it may simply send a pending message back as the default response. Envoy also supports handling incoming messages by using a webhook callback for another compliance system to determine handling.

When the webhook is enabled, on every incoming travel rule message Envoy will:

  1. Decrypt the message (returning an error if decryption is unsuccessful)
  2. Validate the message (returning an error if the message is invalid)
  3. Make an http POST request to your webhook with the decrypted message as JSON
  4. Validate the JSON response from the webhook
  5. Encrypt the outgoing message and send back to the recipient
  6. Store the secure envelopes locally

The webhook will make an POST request to your endpoint supplying the data descrbed in the webhook request in JSON format. Envoy expects a status code 200 response from your endpoint with a reply in UTF-8 encoded JSON.

A couple of important things to note:

  • You must provide a valid response back to Envoy or an error will be returned to the counterparty and logged on the server.
  • If the webhook is unavailable, Envoy will return service unavailable to the counterparty.
  • Envoy has a request timeout of 30 seconds, however the counterparty may have a shorter duration timeout; if this is the case the request will be canceled.

Webhook Request

The webhook POST request will contain some metadata about the incoming secure envelope, the counterparty, and will contain one of an error or a payload as follows:

{
    "transaction_id": "",
    "timestamp": "",
    "counterparty": {},
    "hmac_signature": "",
    "public _key_signature": "",
    "transfer_state": "",
    "error": {},
    "payload": {}
}
FieldTypeDescription
transaction_iduuidthe id of both the Envoy transaction and the secure envelope id
timestamptimestampthe RFC3339Nano timestamp of the secure envelope
counterpartyobjectthe information about the counterparty that Envoy has in its database
hmac_signaturebase64if the secure envelope has a valid hmac_signature, this is the base64 encoded signature (omitted if not set)
public_key_signaturestringused to identify the public keys that sealed the incoming secure envelope (omitted if not set)
transfer_statestringthe TRISA transfer state of the secure envelope
errorobjectif the incoming envelope is a rejection or repair request the error will be set (omitted if payload is set)
payloadobjectif the incoming envelope contains a travel rule information payload, this will be the decrypted info (omitted if error is set)

Details of the counterparty, error, and payload objects are described below.

Webhook Reply

The reply to the POST request must have a 200 status code and the following data serialized as UTF-8 encoded JSON. Note that either the error field or the payload field may be specified but not both.

{
    "transaction_id": "",
    "error": {},
    "payload": {},
    "transfer_action": ""
}
FieldTypeDescription
transaction_iduuidthe transaction_id must match the transaction_id of the request
errorobjectif you’re rejection or requesting a repair, specify the details in this field (must be omitted if payload is set)
payloadobjectthe payload to return to the counterparty (may simply be an echo of the original payload) (must be omitted if error is set)
transfer_actionstringthe TRISA transfer action you’d like specified in the reply to the counterparty (see below for values)

If the transaction_id does not match the ID of the request, then Envoy will fail and return an error to the counterparty.

The transfer_action can be one of “PENDING”, “REVIEW”, “REPAIR”, “ACCEPTED”, “REJECTED”, or “COMPLETED”. See TRISA workflows for more about how these states determine responses to incoming messages. A basic summary is as follows:

Use "PENDING" if a compliance officer on your team needs to review the travel rule request, make sure you include a pending and identity in your reply.

Use "REVIEW" if the counterparty’s compliance officer needs to review the travel rule request, make sure you include a transaction and identity in your reply. This is generally used if you’ve made changes to the original payload.

Use "REPAIR" if you need the counterparty to make a change to the payload, e.g. if it is missing fields required for your jurisdiction, make sure you’ve included an error in your reply that describes the changes that need to be made.

Use "ACCEPTED" if you’re ready for the counterparty to make the on-chain transaction and you’re satisfied with the compliance exchange. Make sure to echo back the transaction and identity in your reply.

Use "REJECTED" if you do not want the counterparty to proceed with the on-chain transaction; make sure to include the error in your reply with the rejection information.

Use "COMPLETED" if the compliance exchange is accepted and the on-chain transaction has already been conducted and the payload contains a proper, chain-specific transaction ID in the payload. Make sure you echo back the transaction and identity in your reply.

API Objects

This section describes nested objects in the request and reply.

Error

Errors are mutually exclusive with payloads, meaning a response or reply to the webhook will have either an error field or a payload field but should not have both.

An error describes either a repair or a rejection (determined by the retry boolean flag). A rejection (retry=false) implies that the counterparty should stop the on-chain transaction as the compliance exchange has not been satisfied. A repair (retry=true) implies that the counterparty needs to amend the identity payload, e.g. because there are missing fields that are required for compliance in your jurisdiction.

The fields for the error are as follows:

{
    "code": 0,
    "message": "",
    "retry": false
}
FieldTypeDescription
codeint32the error code from the TRISA api package
messagestringa detailed message about why the request is being rejected or what needs to be repaired
retryboolshould be false if this is a rejection, true if a repair is being requested

View the available error codes in the TRISA API docs.

Payload

Payloads are mutually exclusive with errors, meaning a response or reply to the webhook will have either a payload field or an error field but should not have both.

Additionally, payloads have mutually exclusive fields pending and transaction - a payload can have one or the other, but not both.

The payload fields are as follows:

{
    "identity": {},
    "pending": {},
    "transaction": {},
    "sent_at": "",
    "received_at": ""
}
FieldTypeDescription
identityobjectan IVMS101 payload, see IVMS101 docs for more information
pendingobjecta TRISA pending message, see TRISA docs for more information
transactionobjecta TRISA generic transaction, see TRISA docs for more information
sent_atstringthe RFC3339 encoded timestamp of when the compliance exchange was initiated
received_atstringthe RFC3339 encoded timestamp of when the compliance exchange was approved by the counterparty

For more information about IVMS101, please see: Working with IVMS101.

For more information about the pending and transaction generic payloads, please see: TRISA Data Payloads.

Counterparty

The counterparty describes what the Envoy node knows about the remote counterparty. This information may be more complete if the counterparty record was created by the TRISA directory service or stored locally on the node. If the record was created by a TRP record, this information may be fairly sparse.

{
    "id": "",
    "source": "",
    "directory_id": "",
    "registered_directory": "",
    "protocol": "",
    "common_name": "",
    "endpoint": "",
    "travel_address": "",
    "name": "",
    "website": "",
    "country": "",
    "business_category": "",
    "vasp_categories": [],
    "verified_on": "",
    "ivms101": "",
    "created": "",
    "modified": ""
}
FieldTypeDescription
idulidthe Envoy id of the counterparty for api lookups
sourcestringthe source of the counterparty info (e.g. user, gds, x509)
directory_iduuidthe id of the counterparty in the TRISA directory
registered_directorystringthe id of the directory the counterparty is listed in
protocolstringthe preferred protocol of the counterparty (trp or trisa)
common_namestringthe common name associated with the counterparty’s certificates
endpointstringthe uri endpoint of the counterparty to send travel rule requests
travel_addressstringa travel address identifying the generic endpoint of the counterparty
namestringthe display name of the counterparty
websitestringthe website of the counterparty
countrystringthe alpha-2 country code of the counterparty
business_categorystringthe business category of the counterparty (e.g. private, government, etc)
vasp_categories[]stringthe type of virtual asset services the counterparty provides (e.g. Exchange or Miner)
verified_onstringthe RFC3339 timestamp of when the counterparty was verified by the TRISA network
ivms101IVMS 101the ivms101 record of the legal person representing the counterparty
createdstringthe RFC3339nano timestamp of when the counterparty was added to your Envoy node
modifiedstringthe RFC3339nano timestamp of when the counterparty was lasted modified on your Envoy node