Creating and Managing Outgoing Webhooks

In the Integrations section of the Console, you can create Outgoing webhooks:

  • If you've defined a Notification Rule based on a system event, you can link this to an Outgoing webhook as the endpoint for the Notification and to create a Webhook Notification integration configuration. See Utilizing Events and Notifications for more details.

  • Currently, only the M3TER_SIGNED_REQUEST credentials format can be used as the authentication method used for connecting to a webhook. See the Webhook Authentication section below for more details on how to work with this format.

  • If credentials are not required, then dummy values can be used.

Tip: Integrations Webhook API Example? See Integrations Webhook API Example in our API Reference for a worked example of creating a webhook destination using the API.

This topic explains how to create and manage your integration Outgoing Webhooks. Detailed guidance is also given on how to construct and verify a secure signature for the M3TER_SIGNED_REQUEST:

Creating Outgoing Webhooks

To create an Outgoing webhook:

1. Select Integrations:

The Configurations page of the Integrations section opens.

2. Select Outgoing webhooks:

The Outgoing webhooks page opens.

3. Select Create outgoing webhook. The Create page opens.

4. Enter Outgoing webhook details:

  • Name and Code:

    • Note that when you enter a name and click in the Code field, a default code is entered based on the name you've entered, which you can then edit as required.

  • Description for the Outgoing webhook.

  • URL for the Outgoing webhook.

Important - only valid Domain Name System (DNS) entries permitted! If you enter an invalid DNS entry for URL, then an error message will show when you try to save the Outgoing webhook.

5. In the Credentials panel:

  • Credential type. Method of authentication with the Outgoing webhook.

    • Note that only the M3TER_SIGNED_REQUEST authentication method is currently available and the Credential type field is pre-populated with this value.

  • Enter the API key and API secret you want use for the M3TER_SIGNED_REQUEST authentication when connecting to the Outgoing webhook.

6. Select Create outgoing webhook. You are returned to the Outgoing webhook details page. The Outgoing webhook is now available for linking your Notifications to it.

Managing Outgoing Webhooks

You can edit, view details, or delete an Outgoing webhook.

To manage Outgoing webhooks:

1. Select Integrations. The Configurations page opens.

2. Select Outgoing webhooks:

The Outgoing webhooks page opens.

3. If you want to edit an Outgoing webhook select Edit:

4. On the Edit page, make your changes and select Update outgoing webhook.

5. If you want to view the details of an Outgoing webhook, select its NAME hotlink. The Outgoing webhook details page opens:

In this example, Outgoing Webhook 1 details are shown. Note that you can Copy directly to your Clipboard the:

  • URL

  • API key

  • ID

5. If you want to delete an Outgoing webhook, select Delete:

A confirmation dialog appears. Select Yes to confirm the delete action.

Warning! If you try to delete an Outgoing webhook to which you've linked a Notification, then you won't be able to and an error message will show.

Webhook Authentication for M3TER_SIGNED_REQUEST

Currently, the only authentication support for connecting to a webhook is signing a request using an ApiKey and ApiSecret. In m3ter, this is the M3TER_SIGNED_REQUEST credentials format. This format implements a signed request for webhook access and is designed to enable you to build secure webhook endpoints and safeguard them from malicious attacks.

m3ter will sign all the requests it makes to your webhook. When you receive a request on your configured endpoint, you should:

  • Validate that the timestamp of the request is within an acceptable grace period.

  • Compute the signature based on the information you receive and compare that with the signature m3ter passes. This allows you to verify that the request was made by m3ter and not a third party as bad actor.

You'll receive the following m3ter headers:

  • X-m3ter-timestamp - the timestamp when m3ter made the request.

  • X-m3ter-apikey - the apiKey corresponding to the apiSecret used to sign the request.

  • X-m3ter-signature - the signature m3ter computed for this request. You need to validate this header.

  • X-m3ter-signaturemethod - the algorithm used for computing the signature. Currently, the algorithm used is always HmacSHA256.

  • X-m3ter-version - the m3ter signature algorithm. Currently, this is always 1.

Validating the X-m3ter-signature Header

To validate the X-m3ter-signature header, you must prepare a payload String that you sign with your API Secret.

To compute the payload, you must concatenate the following data using a pipe | separator:

  • url

  • query string - Currently, there's no support for passing in query parameters. For now, you can hard code to this String: {}

  • API Key - provided in the X-m3ter-apikey header.

  • timestamp -provided in the X-m3ter-timestamp header.

  • body - the request body.

Example

1
POST https://test.com
2
X-m3ter-timestamp: 1688460685310
3
X-m3ter-apikey: testApiKey
4
X-m3ter-signature: a9f9936e662512f943a904f3a71d0141c9bdfbf9fd5496902172864e9333ba15
5
X-m3ter-signaturemethod: HmacSHA256
6
X-m3ter-version: 1
7
8
body: {"orgId":"f49e8e22-ddd2-4367-b1ed-761e7e1fbdfd","entityId":"136f7b01-6bbd-4779-88a1-4a22d47b4f97","requestType":"NOTIFICATION","name":"Bill Approved for Locking","description":"Bill approved for locking","accountId":"16c14570-5790-43b5-9ed8-109541b780bb","originalEventId":"8ab97599-02a4-4604-b9fb-e0110ef3dbb9","eventName":"billing.bill.updated","notificationEventId":"679c70ef-f843-4dac-add2-75420666f598","notificationCode":"bill_approved_for_locking"}
9

The payload will be:

1
payload = "https://test.com|{}|testApiKey|1688460685310|{\"orgId\":\"f49e8e22-ddd2-4367-b1ed-761e7e1fbdfd\",\"entityId\":\"136f7b01-6bbd-4779-88a1-4a22d47b4f97\",\"requestType\":\"NOTIFICATION\",\"name\":\"Bill Approved for Locking\",\"description\":\"Bill approved for locking\",\"accountId\":\"16c14570-5790-43b5-9ed8-109541b780bb\",\"originalEventId\":\"8ab97599-02a4-4604-b9fb-e0110ef3dbb9\",\"eventName\":\"billing.bill.updated\",\"notificationEventId\":\"679c70ef-f843-4dac-add2-75420666f598\",\"notificationCode\":\"bill_approved_for_locking\"}"
2

Nodejs Example

1
const crypto = require('crypto');
2
3
// Main function to validate request authenticity
4
exports.validateSecret = function({ url, queryString, apiKey, apiSecret, timestamp, body, signature }) {
5
var currentTimestamp = Date.now();
6
var result = false;
7
8
// Check if the provided timestamp is in the past by comparing it with the current timestamp
9
if (currentTimestamp - 30 * 1000 > timestamp) {
10
var details = "timestamp in the past: " + currentTimestamp;
11
return {"result": result, "log": details};
12
}
13
14
// Prepare the payload string by concatenating the request data
15
var sharedSecret = apiSecret; // Secret associated with the apiKey
16
var safeQueryString = !queryString ? '{}' : queryString;
17
var payload = url + "|" + safeQueryString + "|" + apiKey + "|" + timestamp + "|" + body;
18
19
// Generate a cryptographic signature of the payload using HMAC-SHA256
20
var sig = crypto.createHmac('sha256', sharedSecret)
21
.update(payload)
22
.digest('hex');
23
24
// Compare the generated signature with the provided signature using a timing-safe comparison
25
result = crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(signature));
26
27
// Return the result and additional information for debugging
28
return {"result": result, "log": {"payload": payload, "sig": sig, "signature": signature}};
29
};
30
31

Next: Creating and Managing Integration Credentials



Additional Support

Login to the Support portal for additional help and to send questions to our Support team.