Learn Center has been sunset. Visit our new Docs site at: docs.canopyservicing.com
logo

Webhooks

Webhooks and Canopy

Activity that occurs in Canopy drives many downstream dependent actions. For example, sending email or text notifications to borrowers, executing logic in response to missed borrower payments, and more. All events that occur within the lifecycle of any borrowers on Canopy send webhook notifications for your dependent systems.

Organization-level Webhook URL

To assign your webhook URL to your Canopy organization, navigate to the “App Keys” page from the top right account dropdown. Under the Webhook URL section, paste your webhook URL into that input and hit the save button. Once configured in the Canopy UI, this URL will receive the following events.

Delivery Guarantees

Webhook messages have an ‘at least once’ guarantee. In order to facilitate this, a message may be delivered more than once. It is up to the receiver to detect duplicate messages. This can currently be done with the hmac_signature.
Ordering There is no guarantee on delivery order of webhooks. If there is an error in receiving the webhook there will be a retry which might change the ordering of webhooks.

Response Pattern

Events will hit your webhook URL in the following pattern:
sql
{ "event": String, // The event name "data": Object, // The webhook payload "hmac_signature": String // The signature of the field "data" }
🧠
Your endpoint must respond with a 200 or 202

Other response codes and Retry

  • Events associated with error codes 429 and 5XX are retried before sent to dead letter queue (DLQ).
  • Events associated with error codes 1XX, 3XX, and 4XX (excluding 429) aren't retried before sent to DLQ.
  • Canopy will retry a single webhook event with exponential backoff, with the first retry 1 minute after the first failure, and will stop with the last retry approximately 24 hours after the first failure.
  • The endpoint will pause if several error codes are received consecutively or if one 401 code is received
  • Events stored in the dead letter queue (DLQ) are kept for 5 days, and you have the option to resend all DLQ events back to your webhook endpoint. A single put on the Canopy API route /organization/subscribe/replay_failed_events will replay all failed events to your webhook endpoint again.

Verifying HMAC Signatures

  • You can verify the key on any HMAC library with encryption SHA256 and on Base64. This algorithm needs to be applied on the payload data field, and needs to be equal to the hmac_signature field.
  • You can retrieve your HMAC secret key via a GET call to Canopy:
    • https://{{hostname}}/organization/subscribe/get_webhook_secret
  • To manually verify, you can do so within an online SHA256 generation tool such as the one found here.

Example

javascript
const CryptoJS = require("crypto-js"); const data = {...}; const HMACData = JSON.stringify(data); secret_key = '***'***'; const generatedHMAC = CryptoJS.HmacSHA256(HMACData, secret_key); const generatedHMACBase64 = CryptoJS.enc.Base64.stringify(generatedHMAC); console.log(generatedHMACBase64);

Testing Webhooks

If you are testing using controlled processing, you will need to include an additional query parameter in you request to admin/roll/account called roll_webhooks set to true.

Webhooks

Test Event schema: test_event
Statement schema statement_generation
Line Item Creation line_item_create
Line Item Update line_item_update
Account Creation account_create
Account Update account_update
Minimum Payment Due minimum_payment_due
Account Calculation Change : account_calculation_change

Configurable Webhooks

Subscribing to Configurable Webhooks
Configurable Webhooks are not enabled by default. You need to explicitly subscribe to them on behalf of each account, with a request to:
PUT /accounts/{{account_id}}/notification_config
Here is a sample subscription payload:
{ "notification_type": "payment_due_date", -- the webhook payload (see below) "time_offset": "-1 days", -- time offset from the notification event "time": "17:00:00"------at which webhook will be triggered in product timezone }
For this payload, we subscribe to a notification at 5PM, 1 day before the payment due date for the account.
Webhook Payloads
Payment Due Date payment_due_date
Minimum Payment Missed minimum_payment_missed
Account Delinquency account_delinquency


Archived Webhook Payloads
Minimum Payment Due minimum_payment_due — Deprecated in favor of payment_due_date