Merge webhooks sent to you

Configure Merge webhooks that send data payloads to your app.

Overview

Webhooks offer a real-time way to notify your app when data changes. This guide teaches how to setup these webhooks, which are inbound POST requests to your API, allowing you to create, update, or delete data in your app based on Merge events.

Webhooks are shared across your Merge organization.


Create webhooks

To create webhooks, go to the Webhooks management console under the Advanced configuration in your Merge dashboard and click +Webhook.

Create Webhook

On the next page, add the URL that you want Merge to send a POST request to. This URL should point to a POST route in your API that you’ll build to handle the incoming payload.

Select the event type that you want to trigger the webhook. We recommend the Common Model sync and/or changed data webhooks if you have a lot of data to keep in sync. You can detect the affected data models within your API by parsing the JSON payload.

If you want to test your webhook, click Send test POST request next to your URL. This will cause Merge to send a POST request carrying a sample payload to the URL you’ve specified, where you can log the output and program your endpoint to do something in response to the payload.

Dashboard Webhooks

Payload Properties

FieldTypeDescription
hookObjectThe webhook that was triggered
linked_accountObjectThe user whose data has changed
dataObjectThe affected data model. The structure of each model can be found in our API documentation.

Webhook event types

Receive an alert when a new Linked Account is linked.

Webhook payload example
1{
2 "hook": {
3 "id": "cb1fe0a7-c2a1-4bd6-8cf5-57e70c7f1d53",
4 "event": "LinkedAccount.linked",
5 "target": "https://yoururl.com"
6 },
7 "linked_account": {
8 "id": "a3602c03-aba7-4d9d-a349-dbc338504092",
9 "integration": "Workday",
10 "integration_slug": "workday",
11 "category": "ats",
12 "end_user_origin_id": "",
13 "end_user_organization_name": "Test",
14 "end_user_email_address": "test@merge.dev",
15 "status": "COMPLETE",
16 "webhook_listener_url": "https://api.merge.dev/api/integrations/webhook-listener/IDS",
17 "is_duplicate": null,
18 "account_type": "PRODUCTION"
19 },
20 "data": {
21 "account_token": "YOUR_ACCOUNT_TOKEN",
22 "is_relink": false
23 }
24}

Security

You’ll want to ensure that your API endpoint is verifying that incoming POST requests are from Merge and not a malicious source, and that payloads haven’t been altered in transit.

The best way to do that is to check that the X-Merge-Webhook-Signature field in the header of the incoming request matches an encoded combination of your organization’s webhook signature and the payload attached to the incoming request.

In your Webhooks page under configuration, you should see a Security module with your signature key. This key is unique to your organization and can be regenerated if it ever becomes known by an untrusted third party.

Webhook Security

Using this key, calculate the HMAC-SHA256 of the byte-formatted payload and encode it to Base64url to get a digest. Ensure that the digest matches the X-Merge-Webhook-Signature found in the headers of the incoming POST request to confirm that the request is valid.

1import base64
2import hashlib
3import hmac
4
5# Swap YOUR_WEBHOOK_SIGNATURE_KEY below with your webhook signature key from:
6# https://app.merge.dev/configuration/webhooks
7
8signature_key = "YOUR_WEBHOOK_SIGNATURE_KEY"
9raw_request_body = request.body
10
11# Reject any requests without a signature header present
12try:
13 webhook_signature = request.headers["X-Merge-Webhook-Signature"]
14except KeyError:
15 print('No signature sent, request did not originate from Merge.')
16 raise
17
18# Encode request body in UTF-8 and generate an HMAC digest using the webhook signature
19hmac_digest = hmac.new(signature_key.encode("utf-8"), raw_request_body.encode("utf-8"), hashlib.sha256).digest()
20
21# The generated digest must be base64 encoded before comparing
22b64_encoded = base64.urlsafe_b64encode(hmac_digest).decode()
23
24# Use hmac.compare_digest() instead of string comparison to prevent against timing attacks
25doesSignatureMatch = hmac.compare_digest(b64_encoded, webhook_signature)

Webhook visibility

All Webhooks are visible as Logs, and viewable from Merge’s dashboard.

Merge Link demo in dashboard