Webhooks (Beta)
Konvert™ emits events based on many activities and changes that happen within a portal. These events are available to subscribe to externally via webhooks. Event data is transmitted in real time to any subscribed endpoints you have.
In this article, we will explain:
- Receiving webhook event data
- Requesting webhook registration or modifications
- Event structure
- List of events
- Non-standard events structure
RECEIVING WEBHOOK EVENT DATA
Webhook events can be sent to any publicly accessible web address that can receive POST calls. A single webhook can be subscribed to one or multiple event types. As events happen within your portal for the subscribed event types, the data is sent as the POST body to your webhook endpoint in the following format:
{ "event": {}, // event object, see Event Structure for details "webhookEndpoint": { "_id": "609c3325c3347773ff9b271e", // unique ID for your webhook endpoint "url": "https://yourwebhook.com/endpoint", // the url where your webhook data is sent "enabled": true, // if the webhook is enabled "pid": "D83vZg7HtfyQ9zzYa", // your portal ID "eventTypes": ["learningAssignment.completeModule"] // one or more event types which will be sent to this endpoint }, "timestamp": "2022-10-25T20:04:46.642Z" // The date/time the webhook event is being sent. If this is a retry due to previous failure, this will update to the date/time at the time of sending the retry. The date/time is in ISO-8601 format. }
WEBHOOK SECURITY AND AUTHENTICATION
In order to validate the integrity of the event data you receive, a signature is included with all webhook events which can be used to verify and validate that the data is coming from Konvert, and not a third party. Each webhook registration has a unique secret key assigned to it. This secret key is used to create a signature of the request body which can be verified by your receiving end.
Steps you should take to validate the event data:
- The signature included in the header
X-Konvert-Signature-v1
should be compared against a signature you generate. If they do not match, reject the webhook. See Signature Verification below. - To prevent replay attacks, you should reject the event if the timestamp within the request body is older than 5 minutes. This timestamp is updated for each initial attempt and retry attempt, so it should always be very close to the current UTC date / time.
Signature Verification
- Get the raw body of the request.
- Extract the signature from header
X-Konvert-Signature-v1
. - Calculate the HMAC of the raw body using the SHA-256 hash function and the webhook secret.
- The hash signature is in hex format. Some examples take the hash and encode to base64; please make sure to use the hex directly without converting to base64.
// Node.js example
const hmac = crypto.createHmac("sha256", secret);
const signature = hmac.update(body).digest("hex");
- Compare the calculated HMAC with the one sent in the
X-Konvert-Signature-v1
signature header.
There are a variety of helpful examples in different programming languages showing how to verify an HMAC signature here.
REQUESTING WEBHOOK REGISTRATION OR MODIFICATIONS
If you would like to register a webhook or set of webhooks at which to receive webhook events, please contact us with the following details:
- URL at which you would like to receive data
- Which event(s) you would like to subscribe to (if multiple webhooks, list which events for what endpoints is desired)
Please also contact us for any changes, removals or to pause webhook events.
SUCCESS, ERRORS AND RETRYING
If your server returns any 2XX response, the webhook call is considered successful and is done processing.
If your server returns anything other than a 2XX response, or it takes longer than 30 seconds to respond, the webhook will retry according to the schedule:
- Resend once every 5 minutes for the first 30 minutes
- Resend once every hour after not succeeding for 30 minutes
- Stop sending after 3 days without a successful response
EVENT STRUCTURE
Many events follow a standard structure when data is created, updated or removed. The list of events below will indicate if the event has a standard or non-standard structure. Those with non-standard will have their own list of fields.
Standard events contain the following structure:
{ "_id": "4edfeecf-b2b4-9cde-7250-f50ea77334d2", // this is the event ID "context": { // context is who has performed the action "pid": "D83vZg7HtfyQ9zzYa", // ID of your portal "uid": "Daka0mY3bzYWNCvTk", // User ID who performed the action "aid": "WeqYRGcnPfFoJfqZu", // Account ID of the user's current account "user": { "firstName": "John", "lastName": "Doe" } }, "createdAt": "2021-04-12T17:29:40Z", // time the event occured "eventType": "file.update", // event name "pid": "D83vZg7HtfyQ9zzYa", // ID of your portal "targetId": "zaYCuHMkTrg47EN2z", // ID of the target of the event. "diff": { // for updates - a snapshot of what has changed "added": {}, // what data has been added "deleted": {}, // what data has been removed "updated": {} // what data has been updated }, "originalDocument": {}, // for updates - the old document "updatedDocument": {}, // for updates - the new document "createdDocument": {}, // for creates "removedDocument": {} // for deletes }
LIST OF EVENTS
Event Name | Structure | |
---|---|---|
account.create | Standard | |
account.delete | Standard | |
account.update | Standard | |
attachment.create | Non-Standard | |
attachment.delete | Non-Standard | |
attachment.update | Non-Standard | |
banner.create | Standard | |
banner.delete | Standard | |
banner.update | Standard | |
certificate.create | Standard | |
certificate.delete | Standard | |
certificate.update | Standard | |
email.resetPassword | Non-Standard | |
email.verifyEmail | Non-Standard | |
email.welcome | Non-Standard | |
file.create | Standard | |
file.delete | Standard | |
file.update | Standard | |
fileCategory.create | Standard | |
fileCategory.delete | Standard | |
fileCategory.update | Standard | |
group.create | Standard | |
group.delete | Standard | |
group.update | Standard | |
inviteSetting.acceptInvite | Non-Standard | |
inviteSetting.create | Standard | |
inviteSetting.delete | Standard | |
inviteSetting.update | Standard | |
item.create | Standard | |
item.delete | Standard | |
item.update | Standard | |
learningAssignment.completeModule | Non-Standard | |
learningAssignment.create | Standard | |
learningAssignment.delete | Standard | |
learningAssignment.startModule | Non-Standard | |
learningAssignment.update | Standard | |
lmsMilestone.create | Standard | |
lmsMilestone.delete | Standard | |
lmsMilestone.update | Standard | |
location.create | Standard | |
location.delete | Standard | |
location.update | Standard | |
news.create | Standard | |
news.delete | Standard | |
news.update | Standard | |
portal.update | Standard | |
question.create | Standard | |
question.delete | Standard | |
question.update | Standard | |
section.create | Standard | |
section.delete | Standard | |
section.duplicateModule | Non-Standard | |
section.update | Standard | |
user.acceptAgreement | Non-Standard | |
user.addToPortal | Non-Standard | |
user.login | Non-Standard | |
user.removeFromPortal | Non-Standard | |
user.update | Standard | |
NON-STANDARD EVENTS STRUCTURE
Attachments
{ // standard event fields are available in addition to: type, // attachment type forceTranscode // update only - forces the transcoding of video }
{ email, // email address to send to user, // user object of the user receiving the email url // the url to use in the email }
inviteSetting.acceptInvite
{ inviteSetting, // inviteSetting being accepted user // user who is accepting }
learningAssignment.startModule / learningAssignment.completeModule
{ learningAssignment, // learning assignment object user, // user who is starting / completing section // module being started / completed }
section.duplicateModule
{ sourceModule, // module being duplicated createdModule // new module }
user.acceptAgreement
{ user, // user object type // agreement type }
user.addToPortal / user.removeFromPortal
{ user // user being added or removed }
user.login
{ user // user who logged in }
Webhooks are included in the Professional plan and the Enterprise plan.