The Problem: Two Systems, No Bridge
Your Datadog monitors are firing. You have alert policies, thresholds, and dashboards all configured exactly right. But when something breaks at 2 AM, the on-call rotation lives in Alert24, the status page is in Alert24, and the incident timeline is in Alert24. So you copy-paste monitor details into an incident form by hand, or worse, someone on your team misses the alert entirely because the two systems never talk to each other.
Datadog has its own incident management feature, but if your team has standardized on Alert24 for on-call routing, escalation policies, and customer-facing status pages, you do not want to maintain two parallel incident workflows. The fix is straightforward: wire a Datadog webhook notification channel to Alert24's incident API so that monitor state changes create and resolve incidents automatically.
How Datadog Webhook Notifications Work
Datadog lets you attach a webhook notification to any monitor. When the monitor transitions to an alert, warning, or recovery state, Datadog sends an HTTP POST to a URL you specify, with a JSON payload that includes metadata about the monitor, the triggering condition, and the affected host or service.
The payload uses template variables that Datadog substitutes at send time. The ones you will use most:
| Variable | Value |
|---|---|
$ALERT_TYPE |
alert, warning, recovery, no data |
$ALERT_TITLE |
Monitor name |
$ALERT_METRIC |
The metric that triggered the alert |
$ALERT_ID |
Numeric monitor ID |
$HOSTNAME |
Affected host |
$PRIORITY |
P1 through P5 |
$LINK |
URL to the monitor in Datadog |
$EVENT_MSG |
The message body from the monitor definition |
$LAST_UPDATED |
Unix timestamp |
The $ALERT_ID variable is critical for deduplication — it lets Alert24 know that a second webhook for the same monitor should update the existing incident rather than create a new one.
Mapping Datadog Priorities to Alert24 Severity
Datadog uses P1 through P5. Alert24 uses critical, high, medium, low, and info. The mapping is not one-to-one, so you need to decide where your team draws the line. A reasonable default:
| Datadog Priority | Alert24 Severity |
|---|---|
| P1 | critical |
| P2 | high |
| P3 | medium |
| P4 | low |
| P5 | info |
If your monitors are not explicitly prioritized, Datadog sends no priority value and $PRIORITY will be empty. In that case, map based on $ALERT_TYPE: alert becomes high, warning becomes medium.
The Direct Webhook Approach
If your Alert24 workspace accepts unauthenticated webhook sources from a known IP range, you can point the Datadog webhook directly at Alert24's incident API.
In Datadog, go to Integrations > Webhooks and create a new webhook. Set the URL to your Alert24 incident endpoint and configure the payload template:
{
"title": "$ALERT_TITLE",
"description": "$ALERT_METRIC on $HOSTNAME — $EVENT_MSG",
"severity": "$PRIORITY",
"source": "datadog",
"alert_id": "datadog-$ALERT_ID",
"status": "$ALERT_TYPE",
"link": "$LINK"
}
The alert_id field is what Alert24 uses for deduplication. By prefixing with datadog-, you avoid collisions if you are also forwarding incidents from other tools. When a recovery webhook arrives for the same $ALERT_ID, Alert24 will resolve the open incident automatically rather than creating a new one.
To attach this webhook to a monitor, add @webhook-YOUR_WEBHOOK_NAME to the monitor's notification message body. Datadog will trigger the webhook on each state transition for that monitor.
One limitation with the direct approach: $PRIORITY comes through as a raw string like P1, but Alert24 expects critical. You either need to handle this translation at the webhook level using Datadog's conditional template syntax, or use an adapter layer.
A Cloudflare Worker Adapter
For teams that want clean severity translation, request validation, and a place to add custom logic, a Cloudflare Worker is a natural fit. It sits between Datadog and Alert24, transforms the payload, and can log or discard anything unexpected.
const SEVERITY_MAP = {
P1: "critical",
P2: "high",
P3: "medium",
P4: "low",
P5: "info",
};
const ALERT_TYPE_MAP = {
alert: "high",
warning: "medium",
recovery: "info",
"no data": "low",
};
export default {
async fetch(request, env) {
if (request.method !== "POST") {
return new Response("Method not allowed", { status: 405 });
}
let payload;
try {
payload = await request.json();
} catch {
return new Response("Invalid JSON", { status: 400 });
}
const severity =
SEVERITY_MAP[payload.severity] ||
ALERT_TYPE_MAP[payload.status] ||
"medium";
const isResolved = payload.status === "recovery";
const incident = {
title: payload.title,
description: payload.description,
severity,
source: "datadog",
alert_id: payload.alert_id,
status: isResolved ? "resolved" : "open",
metadata: {
link: payload.link,
},
};
const response = await fetch(env.ALERT24_INCIDENT_API_URL, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${env.ALERT24_API_KEY}`,
},
body: JSON.stringify(incident),
});
if (!response.ok) {
const body = await response.text();
return new Response(`Alert24 error: ${body}`, { status: 502 });
}
return new Response("OK", { status: 200 });
},
};
Deploy this worker with two secrets: ALERT24_INCIDENT_API_URL and ALERT24_API_KEY. Point your Datadog webhook at the worker URL. The worker handles the severity translation, sets status correctly on recovery, and passes through the alert_id for deduplication.
You can extend this worker to filter noise — for example, skip no data alerts during a known maintenance window, or only escalate to critical if a monitor has been alerting for more than five minutes.
Testing the Integration
Before enabling on production monitors, test the end-to-end flow with a synthetic payload. Use curl to POST directly to your worker or Alert24 endpoint:
curl -X POST https://your-worker.workers.dev \
-H "Content-Type: application/json" \
-d '{
"title": "High CPU on web-01",
"description": "cpu.usage > 90% on web-01",
"severity": "P2",
"status": "alert",
"alert_id": "datadog-12345678",
"link": "https://app.datadoghq.com/monitors/12345678"
}'
Check that the incident appears in Alert24 with severity high. Then send the same payload with "status": "recovery" and confirm the incident moves to resolved state.
Once that passes, enable the webhook on a low-traffic monitor and verify alerts are flowing before rolling it out more broadly.
Next Steps
Start by creating the Cloudflare Worker above and deploying it to your account — it takes about ten minutes and gives you a stable, auditable translation layer. Then attach the Datadog webhook to one monitor and watch the incident lifecycle from creation through resolution in Alert24.
From there, you can use Alert24's escalation policies to route different severities to different on-call rotations, and your status page will reflect incident state automatically without any manual updates.