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
TriggeredandClearedAuvik 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(defaultAuthorization) and look it up case-insensitively. - Compare the whole header value with
AUVIK_WEBHOOK_SECRET, including anyBearerprefix 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-ASCIIstrraises).
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.
| Field | Meaning |
|---|---|
alertId | Alert identifier. Differs between a trigger and its clear in Auvik's examples |
correlationId | Identifier of the alert trigger, shared by a trigger and its clear in Auvik's examples |
alertName | Name of the alert |
alertStatus | Numeric status: 0 Triggered, 1 Cleared |
alertStatusString | Triggered or Cleared |
alertDescription | Description of the alert |
entityName | Asset that triggered the alert |
companyName | Site the asset is located in |
date | When the occurrence was detected, in UTC |
link | Link 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 |
|---|---|
Triggered | An alert fires |
Cleared | An 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
- references/overview.md - What Auvik webhooks are and the alert payload
- references/setup.md - Add the Webhook integration with Header authentication
- references/verification.md - Header check details, gotchas, debugging 401s
- examples/ - Runnable Express, Next.js and FastAPI handlers with tests