Skip to main content

Webhooks

Using webhooks, Skywalk API can send data to your system when a specified event occurs. These webhooks remove the need for polling, but they require you to have a publicly available HTTPS URL.

Types of Webhooks#

You can set up webhooks on your project in a few different ways. Any or all of these webhooks can be triggered. All webhooks configured for an event will be triggered for said event.

Global Webhooks#

You can configure your project to have global webhooks. Skywalk API will call these webhooks for any event triggered by using an API key for that project.

You can configure multiple Global Webhooks and all of them will be called for each event.

Configure a global webhook in Project Settings > Webhooks.

Scheduled Job Webhook#

Each Scheduled Job can be configured with a single webhook. This webhook will be triggered for any event triggered by the scheduled job.

You may configure a Scheduled Job Webhook when creating the Scheduled Job.

API Webhook#

Each API call can also be passed an X-API-NOTIFY-URL header. The URL in this header will also get notified of any event triggered by this API call.

Note that a webhook may not be triggered in certain instances, for example: if the resulting operation is prevented by rate limiting, or ends in an error.

URL Requirements#

Your webhook URL must be served over HTTPS and made accessible by the Skywalk API servers. This URL must not be blocked by a firewall or authentication scheme.

Within 20 seconds, Skywalk API requires a valid 2XX HTTP response. Otherwise, the API will terminate the connection. If your webhook responds with a non-2XX status code, the request will not be retried.

You can configure and test your webhook in Project Settings > Webhooks. We recommended using a tool like ngrok for public HTTPS URLs that work in local testing.

Data Format#

Webhooks are sent as a POST with a JSON request body, indicated by the request header Content-Type: application/json.

The contents of the request body follow the format of the original API endpoint that triggered the callback.

You may want to use meta.path to disambiguate when using a Global Webhook. For more information, see Response Details.

Attributes


metaobject
Metadata about the response

dataarray or object
The primary response data

 

NOTE: Rather than paginate results, Skywalk API sends webhooks the full request payload, which may become rather large. If you do a lot of processing on the data, we advise you to queue the processing and respond immediately with a 2XX to avoid being sent retries.

Sample Webhook Data
{
"meta": {
"path": "/v1/properties",
"count": 172,
"updatedAt": 1610992228,
"status": "ok"
},
"data": [
{ ...object },
...
]
}

Verification#

Since webhook endpoints must be accessible to the open internet, you should be aware of the possibility of forged requests. You may verify the authenticity of a Webhook request by using some of the headers sent in the request.

To verify your data, Skywalk API first sends a X-SKYWALK-BODY-SHA-256 request header that contains a SHA-256 checksum of the raw request body. Then, Skywalk API adds a X-SKYWALK-SIGNATURE header that contains an HMAC-SHA256 request signature. In this signature, the request body checksum is the message, and your project’s Webhook Secret is the key.

Since only Skywalk API and your application know the Webhook Secret, a valid HMAC proves that the request is valid. You can locate your account's Webhook Secret in the Dashboard by visiting Project Settings > Webhooks.

You can verify the validity of this example message using:

Here's some example code for generating the hashes in Node:

const crypto = require('crypto');
const webhookSecret = 'YOUR WEBHOOK SECRET';
const rawRequestBody = ...; // The raw request body as a UTF8 string
const shaHeader = ...; // The value from X-SKYWALK-BODY-SHA-256
const hmacHeader = ...; // The value from X-SKYWALK-SIGNATURE
const shaComputed = crypto
.createHash('sha256')
.update(rawRequestBody)
.digest('hex');
const hmacComputed = crypto
.createHmac('sha256', webhookSecret)
.update(shaComputed)
.digest('hex');
if (shaHeader === shaComputed) {
// Our methods for computing a body hash are compatible
}
if (hmacHeader === hmacComputed) {
// The message is authentic
}
Verification Headers
X-SKYWALK-BODY-SHA-256: efeb1ee3489e33ef268e89ae6bcd71ee0a60df22d1df5bcd2a679ea4dbf5f6ce
X-SKYWALK-SIGNATURE: 8a3c049e00e2c03876d738b69e15c4bd9b5d6621b9667fbecd463d06064adc09
Request Body
{
"meta": {
"path": "/v1/test",
"lastUpdated": 1610992228
},
"data": {
"type": "test"
}
}