Alerts and webhooks

Be told when something happens on a testnet, instead of polling for it.

An alert is a rule and a URL. When a block matches the rule, the testnet posts to the URL — one request per block, carrying everything in it that matched. Set them up on the testnet's Alerts page, or with the create_alert agent tool.

KindFires onNarrow it with
Transactionsa transaction landingfrom, to, and outcome — only reverts, only successes, or either
Logsa contract emitting an eventthe contract address and the event's topic
Blocksevery block

What arrives

POST body
{
  "alert": { "id": "a1b2c3d4", "name": "Failed transactions" },
  "environment": "…",
  "chainId": 7357056,
  "block": { "number": "0x…", "hash": "0x…", "timestamp": "0x…" },
  "matches": [
    { "type": "transaction",
      "transaction": { "hash": "0x…", "status": "reverted", "revertReason": "…" } }
  ],
  "truncated": false,
  "sentAt": "2026-09-11T12:00:00.000Z"
}

At most 50 matches per delivery; truncated says when there were more.

Checking it came from forkstate

Each alert has a signing secret, shown once when you create it. Every body is sent with x-forkstate-signature: sha256=<hex>, an HMAC of the exact bytes:

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

export function fromForkstate(rawBody: string, header: string, secret: string) {
  const expected = "sha256=" + createHmac("sha256", secret).update(rawBody).digest("hex");
  return expected.length === header.length
    && timingSafeEqual(Buffer.from(expected), Buffer.from(header));
}
Check against the raw request body. Parsing the JSON and serialising it again changes the bytes, and the signature will not match.

Delivery

  • Three attempts, a few seconds apart; each result is listed under the alert.
  • Twenty failures in a row turn the alert off; turning it back on resets the count.
  • Alerts fire only for blocks that were written — never for a transaction that was rolled back.
  • The URL must be reachable from the internet; private and local addresses are refused.
  • Up to 25 alerts per testnet. A test delivery can be sent from the Alerts page.