Agent skill
Dynatrace Webhooks Skill
Receive and authenticate Dynatrace problem notification webhooks. Use when setting up a Dynatrace custom webhook integration (Classic problem notifications), verifying a secret header, debugging 401s, or handling opened and resolved problems from a payload template with placeholders like {ProblemID}, {State} and {ProblemTitle}.
Install this skill
npx skills add hookdeck/webhook-skills --skill dynatrace-webhooks
Dynatrace (Classic) problem notifications can POST to a custom webhook URL when a problem opens or is resolved. Requests are not signed. The body is a payload template you write (JSON, text or XML) using placeholders such as {ProblemID}, {State}, {ProblemTitle}, {ImpactedEntity} and {ProblemImpact}; Dynatrace adds no event field of its own. You authenticate requests with a secret header you add as an Additional HTTP header on the integration.
Send the secret in a custom header, not as a token in the webhook URL. Dynatrace allows a token in the URL, but Hookdeck can't check it and URLs leak into logs.
When to Use This Skill
- How do I receive Dynatrace problem notification webhooks?
- How do I authenticate a Dynatrace webhook? (No signature: use a secret header)
- How do I handle opened and resolved problems from a Dynatrace payload template?
- Why does my Dynatrace 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 verifyDynatraceRequest(headers,
name = process.env.DYNATRACE_WEBHOOK_HEADER || 'Authorization',
secret = process.env.DYNATRACE_WEBHOOK_SECRET) {
if (!secret) return false; // never accept when unconfigured
const received = headers[name.toLowerCase()]; // case-insensitive lookup
return Boolean(received) && safeEqual(received, secret); // WHOLE value, no "Bearer " parsing
}
- The header name is whatever you typed in Dynatrace (
DYNATRACE_WEBHOOK_HEADER, defaultAuthorization). The expected value (DYNATRACE_WEBHOOK_SECRET) is the exact, whole header value, including anyBearerprefix you typed. Do not strip or parse the prefix. - Return
401for a missing header or mismatch,200once handled. - Read the body raw (
express.raw({ type: '*/*' })) so any content type works, and parse it only after the credential check. - A static shared credential authenticates the sender, not the body, and gives no replay protection (no signature, no timestamp). Use HTTPS and rotate the credential if it leaks.
For complete handlers with tests, see examples/express/, examples/nextjs/, examples/fastapi/.
Payload and Problem States
The payload is your template, so the shape below is an illustrative example, not a vendor schema. These examples assume this JSON template and dispatch on State:
{
"ProblemID": "{ProblemID}",
"State": "{State}",
"ProblemTitle": "{ProblemTitle}",
"ImpactedEntity": "{ImpactedEntity}"
}
State | Meaning |
|---|---|
OPEN | A problem was opened (the only value Dynatrace's docs show, in the test-notification example) |
A notification is also sent when a problem is resolved, but the docs don't show the {State} value it carries. The examples handle OPEN and log any other value; capture a real resolution (or check your Dynatrace environment) before matching on it. Include {State} in your template or you can't tell the two apart. The docs list no {ProblemURL} placeholder (their example has a literal "Problem URL": "https://example.com").
Environment Variables
DYNATRACE_WEBHOOK_HEADER=Authorization # header name you added in Dynatrace
DYNATRACE_WEBHOOK_SECRET=your-secret-value # exact, whole header value
Local Development
Dynatrace can't reach localhost. Tunnel with the Hookdeck CLI (no account required):
npx hookdeck-cli listen 3000 dynatrace --path /webhooks/dynatrace
Use the printed URL as the webhook URL in Dynatrace.
Resources
- references/overview.md - What Dynatrace problem webhooks are, payload template
- references/setup.md - Add the custom webhook integration and secret header
- references/verification.md - Header check details, gotchas, debugging 401s
- examples/ - Runnable Express, Next.js and FastAPI handlers with tests