Skip to content

Webhook Notifications

Using generic webhooks, you can send incident notifications in JSON format to any HTTPS endpoint. This is convenient for integrating with your own systems or automation tools.

  • HTTPS required: HTTP (unencrypted) URLs cannot be used
  • Public endpoint: Private network URLs are blocked
  • Signature verification secret: Any string of 1 or more characters
  1. Prepare a publicly reachable HTTPS endpoint that accepts a JSON POST body
  2. Generate a signature-verification secret known only to Manako and the receiver
  3. Verify the HMAC-SHA256 signature using the raw request body and X-Manako-Signature
  4. Return a 2xx response after accepting the request. Manako does not follow 3xx redirects
  1. In the dashboard, open Settings > Integrations, then select Configure for Webhook
  2. Enter a recognizable Name
  3. Enter the receiver under Webhook URL (HTTPS)
  4. Enter the shared secret under Secret
  5. Select Add

Notifications are sent as POST requests. The Content-Type is application/json.

Fields included in all events:

FieldTypeDescription
eventstringEvent type
teamIdstringTeam ID
timestampstringISO 8601 formatted timestamp

monitorName, monitorId, and incidentId are included in incident events. Maintenance events contain monitorIds and monitorNames instead.

EventFieldTypeDescription
incident.createdmonitorUrlstringMonitored URL
incident.createdseveritystringSeverity ("critical" or "warning")
incident.created / incident.resolvedtitlestring | undefinedTitle for manual incidents (omitted for automatic incidents)
maintenance.startedmonitorIds, monitorNames, maintenanceUntilstring[] / stringAffected monitors and scheduled end time
maintenance.endedmonitorIds, monitorNamesstring[]Affected monitors
{
"event": "incident.created",
"monitorName": "API Server",
"monitorId": "01JWAB1234567890ABCDEF",
"teamId": "01JWAB0987654321FEDCBA",
"incidentId": "01JWABINCIDENT12345678",
"monitorUrl": "https://api.example.com/health",
"severity": "critical",
"timestamp": "2025-01-15T10:30:00.000Z"
}

Notification requests include an X-Manako-Signature header. You can verify that the request was sent from Manako by validating the HMAC-SHA256 signature of the request body using your secret.

The signature format is sha256=\{hex_digest\}.

import crypto from "node:crypto";
function verifySignature(body, secret, signature) {
const expected =
"sha256=" +
crypto.createHmac("sha256", secret).update(body).digest("hex");
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(signature),
);
}
// Express example
app.post("/webhook", express.text({ type: "application/json" }), (req, res) => {
const signature = req.headers["x-manako-signature"];
if (!verifySignature(req.body, process.env.WEBHOOK_SECRET, signature)) {
return res.status(401).send("Invalid signature");
}
const payload = JSON.parse(req.body);
console.log(`Event: ${payload.event}, Monitor: ${payload.monitorName}`);
res.status(200).send("OK");
});
  • The URL is rejected during setup: It must be public HTTPS and must not resolve to a private or reserved address.
  • The receiver redirects: Manako sends with redirect: "manual"; configure the final receiver URL directly.
  • The signature does not match: Do not reserialize the JSON. Calculate sha256={hex} over the raw body using the same Secret stored in Manako.
  • A test arrives but normal notifications do not: Test uses event: "test". For normal notifications, also check monitor-specific channel links. If links exist but all are disabled, Manako does not fall back to team-wide channels.
  • Notifications stop during rapid state changes: After more than three state changes for the same monitor within 10 minutes, the flap guard suppresses subsequent notifications.
  • Notifications appear duplicated: A sent retry for the same incident, channel, and event type is skipped, and a database UNIQUE constraint also prevents duplicate records. Failed or pending records are retried.

Test sends an actual signed request with event: "test" and has a 60-second cooldown after success. A failed Webhook does not stop other channels.

The flap guard and incident-level sent check apply to incident notifications. Maintenance notifications bypass both controls and go to active, verified team channels.