Alert webhooks

Send an alert to your own server as a signed message, so a script of yours can act on it.

What a message looks like

One POST with a JSON body. Your server answers with any 2xx status.

{
  "topic": "alert",
  "sent": 1793433600,
  "events": [
    {
      "id": 4182,
      "alertId": "9fa5f4ddca68194d",
      "target": "btc-fee",
      "title": "Fee for the next block went above 50 sat/vB",
      "body": "Fee for the next block went above 50 sat/vB. It reads 52 sat/vB.",
      "path": "/live/block-clock",
      "reading": { "display": "52 sat/vB", "value": 52, "observedOn": "2026-10-31" },
      "at": "2026-10-31T09:59:50.000Z"
    }
  ]
}

Paste your link in your account. Maketo sends a check message first.

What comes with it
x-maketo-signature
sha256= then the hex HMAC-SHA256 of timestamp + "." + raw body
x-maketo-timestamp
Seconds since 1970, when the message was signed
x-maketo-topic
alert (ping for the check message)
x-maketo-delivery
One value per message, the same on every retry
x-maketo-attempt
1, then 2 to 4 on retries
user-agent
maketo-alerts/1.0
Check the signature

The signature is an HMAC-SHA256 of the timestamp, a dot, then the raw body, made with the secret shown once when you connect. Compare in constant time and refuse a timestamp older than 5 minutes.

JavaScript

import { createHmac, timingSafeEqual } from "node:crypto";

export function verify(secret, headers, rawBody, nowSeconds, maxAge = 300) {
  const ts = headers["x-maketo-timestamp"];
  if (Math.abs(nowSeconds - Number(ts)) > maxAge) return false;
  const expected = Buffer.from(
    "sha256=" + createHmac("sha256", secret).update(`${ts}.`).update(rawBody).digest("hex")
  );
  const given = Buffer.from(headers["x-maketo-signature"] ?? "");
  return given.length === expected.length && timingSafeEqual(given, expected);
}

Python

import hashlib, hmac

def verify(secret: str, headers: dict, raw_body: bytes, now: float, max_age: int = 300) -> bool:
    ts = headers["x-maketo-timestamp"]
    if abs(now - int(ts)) > max_age:
        return False
    expected = "sha256=" + hmac.new(secret.encode(), f"{ts}.".encode() + raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, headers["x-maketo-signature"])
Retries and switch-off

A message that fails is tried again 1, 5 and 15 minutes later, with the same x-maketo-delivery value, so you can drop repeats.

A redirect, an error, a timeout after 5 seconds or no answer counts as a failure.

After 20 failures in a row the webhook is switched off, and your account shows it as not working. Fix your server, then connect again.

The check message on connect

Before the link is saved, Maketo sends one signed message, {"topic":"ping","sent":<epoch seconds>,"challenge":"<32 hex characters>"}.

Your server answers 2xx with the challenge back, as JSON {"challenge":"..."} or as plain text. Anything else and the link is not saved.

This keeps a link from being used to send traffic at a server that did not ask for it.

The link must be https on port 443 and a plain web name. Addresses made of numbers, local names, and maketo.com are refused.

Discord and Slack

Discord and Slack need no code. Paste the link of an incoming webhook from the channel's settings, and Maketo posts the alert text there.

Limits

1 webhook on your account, up to 100 messages a day.

Webhook messages do not count against your daily limit for email, Telegram, Discord, Slack and your browser.

Your link and secret are stored encrypted, shown once, and deleted with your account.

Send a test message

Sends one signed test alert to the webhook you connected.

Alerts you can send