Agent skill

FireHydrant Webhooks Skill

Receive and verify FireHydrant webhooks. Use when setting up FireHydrant webhook handlers, debugging fh-signature verification, or handling incident management events such as incident, change_event, and signals_alerts payloads.

Install this skill

npx skills add hookdeck/webhook-skills --skill firehydrant-webhooks


FireHydrant (incident management) sends an HTTP POST with a JSON body to your endpoint whenever a subscribed event happens. Each request carries an fh-signature header: the hex-encoded HMAC-SHA256 of the raw request body, keyed with the Secret you set when creating the webhook.

When to Use This Skill

  • How do I receive FireHydrant webhooks?
  • How do I verify the FireHydrant fh-signature header?
  • How do I handle incident, change event, or Signals alert webhooks from FireHydrant?
  • Why is my FireHydrant webhook signature verification failing?

Verification (core)

The signature is a bare hex digest (no sha256= prefix) of the raw body. There is no timestamp or message ID in the signed content.

const crypto = require('crypto');

function verifyFireHydrant(rawBody, signature, secret) {
  if (!signature) return false;
  const expected = crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
  const a = Buffer.from(signature, 'utf8');
  const b = Buffer.from(expected, 'utf8');
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}
expected = hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
valid = hmac.compare_digest(signature.encode(), expected.encode())

In Express, read the body with express.raw({ type: '*/*' }) so the signature verifies whatever Content-Type FireHydrant sends. Parse the JSON only after verification passes.

For complete handlers with tests, see examples/express/, examples/nextjs/, examples/fastapi/.

Event Types

Every payload has two top-level keys: data and event. Identify the event with event.resource_type and event.operation.

event.resource_typeevent.operationTriggered When
incidentUPDATEDAny change to an incident (fields, milestones, tasks, roles, notes, chat, teams)
change_eventupdatedA change event is created or updated
signals_alertsCREATED, UPDATEDA Signals alert is created, or its state changes (BETA)

Operation casing differs between resource types (UPDATED vs updated), so compare case-insensitively. See references/overview.md for payloads.

Environment Variables

# The Secret field on Settings → Webhooks → your webhook
FIREHYDRANT_WEBHOOK_SECRET=your_webhook_secret_here

Local Development

# Start tunnel (no account needed)
npx hookdeck-cli listen 3000 firehydrant --path /webhooks/firehydrant

Use the printed URL as the webhook URL in FireHydrant (Settings → Webhooks).

Reference Materials


Repository

hookdeck/webhook-skills

v0.1.0 · MIT · Updated Nov 3, 2026

View on GitHub →