Agent skill

Auvik Webhooks Skill

Receive and authenticate Auvik webhooks. Use when setting up an Auvik alert webhook endpoint (MSP dashboard Webhook integration), checking the custom header used for Header authentication, debugging 401s, or handling Triggered and Cleared network alerts.

Install this skill

npx skills add hookdeck/webhook-skills --skill auvik-webhooks


Auvik's Webhook integration posts a JSON alert notification to your URL when a network monitoring alert is triggered or cleared. Requests are not signed. Choose Header authentication and Auvik sends a custom HTTP header (a Key and a Value that you pick) on every request; your endpoint authenticates the sender by comparing that header with the value you stored.

Choose Header authentication on the Auvik webhook, not OAuth. Basic Authentication and OAuth 2.0 are not covered by this skill or by Hookdeck's Auvik source.

When to Use This Skill

  • How do I receive Auvik webhooks?
  • How do I authenticate an Auvik webhook with a custom header?
  • Does Auvik sign webhook payloads? (No: use the shared header value)
  • How do I handle Triggered and Cleared Auvik alerts?
  • Why does my Auvik webhook endpoint return 401?

Verification (core)

const crypto = require('crypto');

// Hash both sides: equal-length buffers, so timingSafeEqual never throws.
function safeEqual(a, b) {
  const ha = crypto.createHash('sha256').update(String(a)).digest();
  const hb = crypto.createHash('sha256').update(String(b)).digest();
  return crypto.timingSafeEqual(ha, hb);
}

function verifyAuvikRequest(headers,
    name = process.env.AUVIK_WEBHOOK_HEADER || 'Authorization',
    secret = process.env.AUVIK_WEBHOOK_SECRET) {
  if (!secret) return false;                  // never accept when unconfigured
  const received = headers[name.toLowerCase()]; // Node lowercases header names
  return typeof received === 'string' && received !== '' && safeEqual(received, secret);
}
  • The header name is whatever Key you typed in Auvik, so read it from AUVIK_WEBHOOK_HEADER (default Authorization) and look it up case-insensitively.
  • Compare the whole header value with AUVIK_WEBHOOK_SECRET, including any Bearer prefix you typed in Auvik. Do not strip or parse a prefix.
  • Missing header or mismatch: return 401. Invalid JSON or a non-object body: 400. Handled: 200.
  • Read the body raw (express.raw({ type: '*/*' })) so any content type works, and parse it only after the credential check.
  • Python: encode both sides to bytes before hmac.compare_digest (a non-ASCII str raises).

A static shared credential authenticates the sender, not the body. There is no signature and no timestamp, so it gives no replay protection and no integrity check. Use HTTPS, and rotate the credential (change it in Auvik and in AUVIK_WEBHOOK_SECRET) if it leaks.

For complete handlers with tests, see examples/express/, examples/nextjs/, examples/fastapi/.

Alert Payload

The default body is a JSON object; dispatch on alertStatusString.

FieldMeaning
alertIdAlert identifier. Differs between a trigger and its clear in Auvik's examples
correlationIdIdentifier of the alert trigger, shared by a trigger and its clear in Auvik's examples
alertNameName of the alert
alertStatusNumeric status: 0 Triggered, 1 Cleared
alertStatusStringTriggered or Cleared
alertDescriptionDescription of the alert
entityNameAsset that triggered the alert
companyNameSite the asset is located in
dateWhen the occurrence was detected, in UTC
linkLink to the alert in Auvik

More fields may be present. Test Connection sends {"my-api-test-field":"my-api-test-value"}, so return 200 for a body with no alert fields. An optional JSONata expression on the integration can reshape the body, in which case these field names will differ.

Event (alertStatusString)Sent When
TriggeredAn alert fires
ClearedAn alert clears

Environment Variables

AUVIK_WEBHOOK_HEADER=Authorization       # the Key you entered in Auvik (default Authorization)
AUVIK_WEBHOOK_SECRET=your-header-value   # the exact, whole Value you entered in Auvik

Local Development

Auvik can't reach localhost. Tunnel with the Hookdeck CLI (no account required):

npx hookdeck-cli listen 3000 auvik --path /webhooks/auvik

Use the printed URL as the webhook URL in Auvik.

Resources


Repository

hookdeck/webhook-skills

v0.1.0 · MIT · Updated Nov 5, 2026

View on GitHub →