Webhooks format

Here are the format of webhooks you will get if you subscribed via webhooks:

When an incident is added or updated:

{
"meta": {
"unsubscribe": "",
"documentation": ""
},
"page": {
"id": "",
"status_indicator": "",
"status_description": "",
"url": ""
},
"incident": {
"backfilled": false,
"created_at": "",
"impact": "",
"name": "",
"resolved_at": "",
"status": "",
"updated_at": "",
"id": "",
"url": "",
"incident_updates": [
{
"id": "",
"incident_id": "",
"body": "",
"status": "",
"created_at": "",
"updated_at": ""
}
]
}
}

When a maintenance is added or updated:

{
"meta": {
"unsubscribe": "",
"documentation": "",
},
"page": {
"id": "",
"status_indicator": "",
"status_description": "",
"url": ""
},
"maintenance": {
"backfilled": false,
"created_at": "",
"impact": "",
"name": "",
"resolved_at": "",
"status": "",
"updated_at": "",
"id": "",
"url": ""
"duration": "",
"maintenance_updates": [{
"id": "",
"maintenance_id": "",
"body": "",
"status": "",
"created_at": "",
"updated_at": "",
}],
},
}

When a component is updated:

{
"meta": {
"unsubscribe": "https://dashboard.instatus.com/unsubscribe?id=${subscriber.id}&token=${subscriber.unsubscribeToken}",
"documentation": ""
},
"page": {
"id": "",
"status_indicator": "",
"status_description": "",
"url": ""
},
"component_update": {
"created_at": "",
"new_status": "",
"component_id": ""
},
"component": {
"created_at": "",
"id": "",
"name": "",
"status": ""
}
}

Possible status page statuses:

  • UP
  • HASISSUES
  • UNDERMAINTENANCE

Possible component statuses:

  • OPERATIONAL
  • UNDERMAINTENANCE
  • DEGRADEDPERFORMANCE
  • PARTIALOUTAGE
  • MAJOROUTAGE

Possible incident statuses:

  • INVESTIGATING
  • IDENTIFIED
  • MONITORING
  • RESOLVED

Possible maintenance statuses:

  • NOTSTARTEDYET
  • INPROGRESS
  • COMPLETED

Webhook Payload Verification

It is Highly recommended to validate the webhook payload in the webhook endpoint.

We sign webhook payloads with a secret and include the signature as a header named x-instatus-webhook-signature. This signature allows you to verify the webhook came from Instatus.

Steps To Verify Webhook

  1. Save your Webhook Secret that you generated while subscribing to the webhook (You can find it subscribing through a webhook to a page, you can also customize it there).
Webhook Secret
  1. Create a new endpoint on your server that will receive the webhook.

  2. Compare the signature with your server's generated signature to validate.

  3. If the signatures match, process the webhook.

Code Example

import crypto from 'crypto'
import express from 'express'
const app = express()
app.use(express.json())
const WEBHOOK_SECRET = 'your-webhook-secret'
function isVerifiedPayload(payload, signature, secret) {
const hmac = crypto.createHmac('sha256', secret)
const digest = hmac.update(JSON.stringify(payload)).digest('hex')
return crypto.timingSafeEqual(Buffer.from(digest), Buffer.from(signature))
}
app.post('/endpoint/to/webhook', (req, res) => {
const payload = req.body
const signature = req.header('x-instatus-webhook-signature')
if (!signature) {
return res.status(400).send('Signature missing')
}
if (!isVerifiedPayload(payload, signature, WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature')
}
// Process the valid webhook
res.status(200).send('Webhook received')
})
app.listen(3000, () => console.log('Server running on port 3000'))

Why Verification Matters

  • Ensures Authenticity: Guarantees that the webhook originates from our platform.
  • Prevents Tampering: Detects changes to the payload.
  • Improves Security: Protects against replay attacks and unauthorized access.