Working with Webhooks
The Encompass Partner Connect platform (EPC) supports real-time asynchronous transaction event notifications by leveraging Webhooks. A Webhook is an HTTP callback that is triggered when a certain asynchronous task is completed.
To support notifications via Webhook in an application, there are two steps:
Step | Description |
---|---|
Subscription | When creating a Webhook subscription for a given configuration of the product, provide 2 pieces of information when creating/updating the application registered via the https://api.elliemae.com/partner/v2/products API endpoint1. A functioning and reliable HTTPs callback URL where EPC will transmit the notifications2. A signing key that EPC uses to sign (generate a SHA256 HMAC for) the Webhook request body |
Notification | EPC notifies the application (per Webhook subscription) about the event by sending an HTTP POST request (i.e., Webhook) to the specified callback URL |
Once a Webhook subscription is registered, a notification is sent to the callback endpoint each time a specified event occurs for a transaction resource.
Webhook Endpoint Requirements
- Your webhook HTTPS endpoint should support CA-signed certificates. Self-signed certificates are not supported.
- Custom webhook endpoints must support Transport Layer Security (TLS) 1.2 and above to avoid security vulnerabilities.
- Avoid sending sensitive information like signing key in Webhook endpoint http error response.
Subscribing to Webhooks
Webhook subscriptions are maintained as part of your integrations configuration. To create and/or update webhook subscriptions for the resources described below - you would need to register subscription details when creating/updating your production configuration as follows:
{
"name": "AppraisalPoint",
"listingName": "Appraisal Point - by Appraisal Corp.",
...
"webhooks": [
{
"url": "{{webhook_url}}",
"signingkey": "{{webhook_signing_key}}",
"events": [
"created",
"updated"
],
"resource": "urn:elli:epc:transaction"
},
{
"url": "{{webhook_url}}",
"signingkey": "{{webhook_signing_key}}",
"events": [
"created"
],
"resource": "urn:elli:epc:transaction:event"
}
],
...
}
{
"name": "AppraisalPoint",
"listingName": "Appraisal Point - by Appraisal Corp.",
"webhooks": [
{
"url": "{{webhook_url}}",
"signingkey": "{{webhook_signing_key}}",
"events": [
"created",
"updated"
],
"resource": "urn:elli:epc:transaction"
},
{
"url": "{{webhook_url}}",
"signingkey": "{{webhook_signing_key}}",
"events": [
"created"
],
"resource": "urn:elli:epc:transaction:event"
}
]
}
Notification Signature
Notifications are signed by the EPC platform, so the subscriber (integration back-end) can verify the identity of the sender and integrity of the message. Partners provide the Webhook's signing key when creating a new subscription, updating an existing one, or when creating/updating a product configuration via the https://api.elliemae.com/partner/v2/products
API endpoint.
Symmetric encryption with a shared secret 🔒
Partners provide their webhook signing key via a trusted and secure transport (an authenticated, HTTPS
REST
API call). This enables partners to establish a shared secret with the EPC platform using which all webhooks delivered to the partner integration are signed. This mechanism enables partner integrations to be certain of both the origin of the message (the EPC platform) and its integrity.
When creating a signing key for a Webhook subscription, ensure it meets the following complexity requirements:
- Contains a minimum of 32 and a maximum of 64 characters
- Contains at least 1 uppercase letter and 1 lowercase letter
- Contains at least 1 number
- Contains at least 1 special character
Signing Key
Here is the regular expression you can use to test if a signing key meets the complexity requirement's mandated above:
^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#$^&*])([A-Za-z0-9!@#$^&*]){32,64}$
Partner integrations are expected to process notifications with only a valid Elli-Signature in their headers. The environment indicator and message signature are available in the Elli-Environment and Elli-Signature headers respectively. This is how integrations can validate that the Webhook message wasn't tampered with over the wire!
Header | Description |
---|---|
Elli-Signature | The SHA256 HMAC that was generated by signing the Webhook body with the signing key, which must be validated as described below to guarantee message integrity |
Elli-SubscriptionId | The unique subscription ID for the Webhook subscription |
Elli-Environment | The Ellie Mae (ICE Mortgage Technology) software environment from which the Webhook originated. This will always be prod for Partner applications |
Content-Length | The character length of the message body |
Content-Type | The MIME type of the message body |
The following code samples show how to generate the Elli-Signature header using the signing key maintained by the subscribing entity. The Elli-Signature received in the notification header and the one generated need to match to guarantee the integrity of the Webhook message.
var encoding = new System.Text.ASCIIEncoding();
byte[] keyByte = encoding.GetBytes(secret);
byte[] messageBytes = encoding.GetBytes(message);
using (var hmacsha256 = new HMACSHA256(keyByte))
{
byte[] hashmessage = hmacsha256.ComputeHash(messageBytes);
return Convert.ToBase64String(hashmessage);
}
var CryptoJS = require("crypto-js");
// Some psuedo-code collecting the necessary information for webhook validation
const body = webhookRequest.body
const elliSignature = webhookRequest.headers.get("Elli-Signature")
const signingKey = secretStore.getWebhookSharedSecret()
// Validate incoming webhook signature
const validateSignature = (elliSignature, body, signingKey) => {
const hmac = CryptoJS.HmacSHA256(body, signingKey);
const computedSignature = CryptoJS.enc.Base64.stringify(hmac);
return computedSignature == elliSignature;
}
Forgot your signing key?
Update the existing subscription with a new signing key that meets the specified complexity requirements via a
PATCH https://api.elliemae.com/partner/v2/products/:id
operation
EPC Resources that Emit Webhooks
Transaction resource
resource
Resource ID:
urn:elli:epc:transaction
Events Types Emitted:
==> created
Description: A new transaction resource has been created and is ready to be serviced by the subject application. This webhook is emitted when a lender initiates a new transaction request with your integration.
==> updated
Description: An existing transaction resource has been updated, and the updates are ready for processing by the partner application. This webhook is emitted when a lender updates an existing transaction request with your integration.
Message Body:
{
"eventTime" : "2020-05-02T11:08:52Z",
"eventType" : "created",
"meta" : {
"resourceType" : "urn:elli:epc:transaction",
"resourceId" : "{{TRANSACTION_ID}}",
"instanceId" : "{{PRODUCT_NAME}}",
"resourceRef" : "https://api.elliemae.com/partner/v2/transactions/{{TRANSACTION_ID}}"
}
}
{
"eventTime" : "2020-05-02T11:08:52Z",
"eventType" : "updated",
"meta" : {
"resourceType" : "urn:elli:epc:transaction",
"resourceId" : "{{TRANSACTION_ID}}",
"instanceId" : "{{PRODUCT_NAME}}",
"resourceRef" : "https://api.elliemae.com/partner/v2/transactions/{{TRANSACTION_ID}}"
}
}
Transaction Event resource
resource
Resource ID:
urn:elli:epc:transaction:event
Events Types Emitted:
==> created
Description: A new transaction event resource has been created and is ready to be picked up and processed by the partner application.
Transaction events are ancillary occurrences in relation to the life-cycle of a transaction. These may be System
generated events - such as when a transaction response update is successfully processed by an Encompass application, or when there is an error in processing a transaction response update. These may also be custom events delivered to you by the lender to inform you of information significant to the subject transaction (this may be useful for asynchronous fulfillment patterns - such as for appraisal and title services - where back and forth communication between both parties over the course of fulfillment is necessary).
- Our
System
generated transaction events are illustrated in the section titled Transaction Response Events - To learn more about how you can exchange custom messages for back and forth communication with a lender - look at our
REST
API specification for transaction events, as well as ourJavaScript
API's support for enabling lenders to send custom events to your integration via its user-interface.
Message Body:
{
"eventTime" : "2020-05-02T11:08:52Z",
"eventType" : "created",
"meta" : {
"resourceType" : "urn:elli:epc:transaction:event",
"resourceId" : "{{TRANSACTION_EVENT_ID}}",
"instanceId" : "{{PRODUCT_NAME}}",
"resourceRef" : "https://api.elliemae.com/partner/v2/transactions/{{TRANSACTION_ID}}/events/{{TRANSACTION_EVENT_ID}}"
}
}
Message Body Attributes
Attribute | Type | Description |
---|---|---|
$.eventId | string | The unique ID for the webhook. This ID is the same as the transaction event ID for the event that triggered the webhook - which you can access via our REST API. |
$.eventTime | string | The ISO 8601 UTC time-stamp indicating when the event was generated by the EPC platform |
$.eventType | string | The type of event that occurred to the subject resource. Can becreated or updated |
$.meta | object | The object containing additional metadata specific to the event type |
$.meta.instanceId | string | Attribute containing the name of the specific EPC product against which the transaction event ocurred |
$.meta.resourceId | string | A unique identifier of the resource associated with this event. In the case of EPC, either a transaction ID or transaction event ID |
$.meta.resourceType | string | The type of resource associated with this event. In the case of EPC, either a urn:elli:epc:transaction or a urn:elli:epc:transaction:event |
$.meta.resourceRef | string | The callback URL of the resource associated with this event |
Delivery Retries
If the EPC platform is unable to deliver a notification to the registered Webhook callback URL, or the callback fails to acknowledge the notification, it will retry. Be sure to acknowledge a successfully processed Webhook to prevent re-delivery of the same notification.
The following situations are considered a failed delivery attempt by EPC:
- HTTP status response outside the range
200-399
- A request timeout (30 seconds). Note that if a request timeout occurs, the next retry will occur at the specified interval after the timeout. For example, if the retry interval is 20 seconds and a request times out, the start of the next request will be 35 seconds after the start of the request that timed out.
- Any connection error, such as connection timeout, endpoint unreachable, bad SSL certificate, or others.
The platform will attempt delivery up to three times with a delay of 20 seconds between each retry. If after three attempts, the event is not delivered, the notification is discarded.
Updated 12 months ago