Webhooks

Use webhook endpoints to receive automatic updates

Herald uses webhook endpoints to send an automatic updates when there is a status change associated with an object. If you do not see the status change or object you need in the table below, please poll.

Object / Subscription Statuses that trigger a webhook Statuses that do not trigger a webhook Webhook Payload
quote_status_update active, referred, referral, declined, rejected, unsupported, unresponsive pending, expired GET/quotes/{quote_id} response
file_status_update available, unresponsive processing, deleted GET/files{file_id} response
bind_order_status_update accepted, rejected, unresponsive pending GET/bind_orders/{bind_order_id} response
data_extraction available, unresponsive pending GET/data_extractions/{data_extraction_id} response

You can add any number of subscriptions to a webhook endpoint. Herald also supports multiple webhook endpoints.

Note on wait times:

[.h-code]quote_status_update[.h-code] the time it takes to generate a quote varies based on institution (carrier), so don't worry if quotes aren't sent to the webhook endpoint instantly. To give an idea, some institutions can take up to 2 minutes to process a quote.

[.h-code]data_extraction[.h-code]  Wait time varies by extraction methods used and can range from 5s to 30s depending on type of files used for the extraction.

Set Up

Reach out to a member of the Herald team to set up a webhook endpoint. Reference details are below. All webhook endpoints will use the same secret key (see Security below).

  • To get a webhook endpoint, you must provide a webhook URL (or URLs) in the standard format [.h-code]https://(www.)domain.com/resource[.h-code]
    • Each URL may be associated with one or more objects / subscriptions
    • You may have 1 or more URLs
    • We only support HTTPS URLs
  • Then, when a webhook subscription is trigged by a status change, Herald will send a [.h-code]POST[.h-code] request containing the quote data to the provided webhook URL. (see below for format)

Request Format

The webhook URL provided to Herald will receive requests in the following format:

  • Method
    • POST
  • Headers
    • x-herald-signature (more information on the format found under Security)
  • Request Body
    • Matches the object (see table above for details)

Security

In order to ensure that the [.h-code]POST[.h-code] request coming in to the webhook endpoint is from Herald, we have included [.h-code]x-herald-signature[.h-code] as a header in the [.h-code]POST[.h-code] request. The value of this header is a SHA-256 hash of the secret key provided to you concatenated with the stringified version of the request body. This ensures that the secret key is correct as well as ensure the content of the request has not been modified.

To verify this signature, the server consuming the webhook will need to concatenate the secret key with the stringified version of the request body and generate the SHA-256 hash. An authenticated request will meet the requirement that the [.h-code]x-herald-signature[.h-code] and the generated SHA-256 hash are equal.

Below is an example implementation of a simple Express server with a [.h-code]POST[.h-code] endpoint that authenticates the Herald signature header and request:

Copied

const express = require('express');
const bodyParser = require('body-parser');
const sha256 = require('crypto-js/sha256');
const Base64 = require('crypto-js/enc-base64');

const router = express.Router();
const app = express();

// Here we are configuring express to use body-parser as middle-ware
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

// Webhook POST endpoint
router.post('/webhook', (request, response) => {
  // Access Herald signature header
  const signature = request.headers['x-herald-signature'];
  // Secret key that is unique to the platform
  const secretKey = 'abc-123';
  // String value of secret key concatenated with string version of the request body
  const concatenatedValue = secretKey + JSON.stringify(request.body);
  const hashedValue = Base64.stringify(sha256(concatenatedValue, secretKey));
  if (signature === hashedValue) {
    console.log('Request body is valid');
  } else {
    console.log('Request body is NOT valid');
  }
  // Return a 200 status code to communicate request has been processed
  response.status(200).end();
});

// Add router in the Express app
app.use('/', router);
app.listen(5000);
 

Retries

Herald will send the webhook event when the quote finishes processing. This initial time will vary based on carrier response times. If there is a non-200 response from the configured webhook endpoint, Herald will retry sending the webhook up to two additional times at intervals spaced a few minutes apart.

[.icon-circle-blue][.icon-circle-blue]Note: The Herald signature and payload for each retry attempt will be the same as the original.