Webhooks
MX provides webhooks that send HTTPS POST callback requests to the URL of your choice. This enables you to subscribe to certain events, be notified when those events occur, and have information related to events delivered to you. If you are subscribed to multiple events, a different URL can be configured for each event.
You can set up and configure webhooks on the client dashboard.
Features
The current version of MX webhooks has the following features:
- Webhooks are delivered via RESTful HTTPS requests to your listening service;
- Webhooks are triggered when a qualifying event occurs in the MX system;
- Webhooks can make requests to any specified URL;
- Configuration for this is done offline, out of band;
- Each POST request includes a JSON-formatted payload;
- The frequency of request retries diminishes over the course of approximately 24 hours, with no more than 12 total retries after an initial request.
Best Practices
- Don't rely on webhooks as triggers in your UX: Use postMessages or API request to determine the state of the MX system instead of relying on the receipt of a webhook. If a webhook is being used as a trigger in your UX flow then we recommend putting in a failsafe timer and reading the status from our API as a backup mechanism if a webhook doesn't arrive in a timely manner. This ensures the end-user isn't left waiting while the UI is waiting for a message that's sitting in a queue trying to be delivered.
- Respond to webhook requests immediately: It's crucial to respond promptly to webhook requests, whether with a success or error code, to prevent resource tie-ups for both your system and MX.
- Send a 204 No Content response upon successful receipt of a webhook: This avoids unnecessary resource consumption, crucial for preventing delays in payload processing on both systems.
- Only issue error codes when the webhook wasn’t successfully received: MX payloads may contain null values or include unexpected new fields. If your systems encounter difficulty parsing such situations, issuing an error code won't resolve the problem as MX will resend the same unexpected payload, resulting in the same error.
- Design your webhook payload processing to be resilient to changes: While existing fields won’t be removed, new fields may be added, and the order of fields isn't guaranteed.
- Put every webhook you receive into an internal queue for processing: This helps you process requests as quickly as your system allows and lets you have your own error retry queue for internal errors. Any webhooks that your system can’t process should be placed in a separate list for examination, where you can log and resolve any errors.
- Ensure proper handling of duplicate webhooks: If you receive a duplicate webhook for a single event, log every event you process and don’t process any event that has already been logged. This practice helps prevent future occurrences of duplicate events.
- Compare version fields: Object-based webhooks, such as the member webhook, contain a version field. The version is incremented each time the object is updated on the MX platform. If you're using object-based webhooks, you should compare the version field of the payload you just received with that of the object you have previously stored in your database to determine if the payload just received is the most recent object version.
Changes to Expected Payloads
MX will not remove fields from a webhook payload without a major version change. However, fields may be added to a webhook payload at any time. You should allow for this and should assume neither a fixed set of fields nor a fixed ordering of fields. Any processing should allow for these changes.
Many fields can also return a null
value. You should account for this when handling the webhook payload.
Date and Time Formats
Date and time fields are supported in either Unix Epoch time (no milliseconds), or in ISO 8601 with no timestamp (YYYY-MM-DD).
- Fields ending in
_at
are Unix Epoch time (no milliseconds), e.g.1504224000
. - Fields ending in
_on
are ISO 8601 (no timestamp), e.g.2017-09-01
.
Error Handling
MX checks the status code you send in your response and takes appropriate action based on that. MX will retry a webhook for all status codes outside of the successful 200 range listed above. This could be a connection timeout, write timeout, read timeout, DNS error, etc. Because of this, it's important that you respond to each webhook request as soon as possible, whether with a success code or an error code. Delays tie up resources for both you and MX.
Retries always contain a payload identical to the initial request. This means it's very important that you only send error codes in situations where retrying the webhook will be beneficial, and not in cases where sending the same payload will result in the same error. In cases where the same error will occur, you should return a success status code to MX and put the request into their own internal retry queue, or log the error internally for investigation. In other words, error codes should only be returned when the webhook was not successfully received.
For example, MX payloads may contain null
values, and may include new fields you don't expect. If your systems can't parse these situations, sending an error code will not help because MX will respond by sending the exact same unexpected payload, resulting in the same error.
The most common error codes are within the 500 range (something went wrong on the receiving end) that prevent you from receiving the webhook. A 400-level error should only be returned in cases where a payload is truly invalid, such as if it contains invalid JSON, but not in situations where you can't process the payload for some internal reason.
Successful Status Codes
200 OK
201 CREATED
202 ACCEPTED
203 NON_AUTHORITATIVE_INFORMATION
204 NO_CONTENT
205 RESET_CONTENT
206 PARTIAL_CONTENT
Duplicate Webhooks
If you receive a duplicate webhook for a single event, log every event you process and don’t process any event that has already been logged to avoid this in the future. For true duplicate events that you don’t want to process on your end because they've' already been logged, you must still send a success code to us. Otherwise, we'll continue to retry sending the duplicate event. If this does not solve duplicate events, you may be handling errors incorrectly.
Fields Ending in _set_by
Fields ending in _set_by
indicate the source of the data for the associated field. Possible values are as follows.
Value | Definition |
---|---|
FEED | The data source was the MX data feed. |
USER | The data source was the user. |
SYSTEM | The data source was the MX system. |
Retries
MX webhooks will automatically retry a request in the case of a failed delivery such as a connection timeout, write timeout, read timeout, DNS error, etc.
Retry attempts will contain the same payload as the original request. Retry attempts follow a pattern of incrementally decreasing in frequency with each attempt. You can expect to see a number of retries within the first hour of the initial attempt and then gradually these retry attempts will become less and less frequent. Retry attempts have an element of randomness to them in order to avoid having a flood of retry requests be sent to your system all at once.
If the webhook cannot be successfully delivered after 12 successive retries, it will not be delivered.
Example Retry Schedule
This schedule is only an example and is not exact.
Retry Number | Time Elapsed Since Initial Attempt |
---|---|
1 | 0h 0m 30s |
2 | 0h 1m 16s |
3 | 0h 2m 32s |
4 | 0h 5m 8s |
5 | 0h 10m 54s |
6 | 0h 23m 4s |
7 | 0h 46m 40s |
8 | 1h 28m 56s |
9 | 2h 39m 42s |
10 | 4h 31m 48s |
11 | 7h 21m 28s |
12 | 11h 28m 44s |
Security
All webhook requests are encrypted by default. However, MX recommends using an additional layer of security as well. One or more of the following are typical.
HTTP Basic Authorization
Provide MX with a username and password for making basic HTTP requests to your chosen URL.
Mutual Certificate Authentication
In order to set up mutual authentication, MX will generate a Certificate Signing Request (CSR) for you. You'll first need to provide MX with the following information:
- Common Name
- Organization
- Department
- City
- State/Province
- Country
- Key Size: MX uses the recommended size of RSA 2048.
Use this CSR to purchase a certificate, and then send it to MX. This certificate will be used to authenticate requests originating from MX.
OAuth 2 Access Token Authentication (Client Credentials)
To secure webhooks with OAuth access tokens, provide MX with an ID and secret to be used for basic authorization. MX will use these to make a request to your token endpoint to generate a new access token using the client_credentials
grant type. This token will then be used to make requests to your webhook URL until the token expires. MX then repeats the process.
MX can configure our token requests to send the grant type in either the body or the query string.
Grant Type In Query Sting
Grant Type In Body
Testing
To test an existing webhook, please visit your webhook profile on the client dashboard.
Webhooks can be tested in two ways.
First, simple test webhooks can be generated from your dashboard for a limited number of webhook types. These contain dummy data and aren't strictly part of your integration. But they will allow you to confirm that the URL and security settings you've chosen in the dashboard are working as expected.
Second, MX can generate special test webhooks at your request. These are tied to your particular integration and can be generated for any webhook type you are subscribed to. The payload of a special test webhook will have its action
field set to test
and includes a field indicating the type of webhook being tested, as shown in the example.
MX-Generated Test Payload
_10{_10 "action": "test",_10 "account": {},_10 "version": 1_10}
Available Webhooks
For Platform API clients, only the aggregation, balance, connection status, history, insights, and statements webhooks are available.
For other clients, any of the listed webhooks may be available depending on your specific integration details.
Webhook Timing
We attempt to deliver webhooks in near real time, but can't guarantee they'll always arrive in a timely manner or in the order in which the events occurred. The delivery of a particular event might be delayed due to server-related issues, connection issues, and so on.
It's possible to receive an earlier payload of a webhook after receiving a more recent payload for the same webhook if the delivery of the earlier webhook was delayed. This is especially true when a delivery issue causes it to go into our retry queue. You should account for the possibility of receiving webhooks out of order.