Pulse Webhook Events

Pulse sends webhook notifications on monitor state changes via Solenoid Relay. Webhooks require Starter tier or higher.

Event types

monitor.down

Fires when a monitor crosses the consecutive_threshold (default 1).

{
  "event": "monitor.down",
  "monitor_id": "550e8400-e29b-41d4-a716-446655440000",
  "url": "https://api.example.com/health",
  "status": "down",
  "previous_status": "up",
  "latency_ms": 10042,
  "consecutive_failures": 3,
  "checked_at": 1234567890,
  "timestamp": 1234567890
}

monitor.up

Fires when a monitor recovers. Only sent if notify_recovery: true.

{
  "event": "monitor.up",
  "monitor_id": "550e8400-e29b-41d4-a716-446655440000",
  "url": "https://api.example.com/health",
  "status": "up",
  "previous_status": "down",
  "latency_ms": 142,
  "consecutive_failures": 0,
  "checked_at": 1234567890,
  "timestamp": 1234567890
}

Payload fields:

  • event"monitor.down" or "monitor.up"
  • monitor_id — UUID of the monitor
  • previous_status — status before this transition
  • latency_ms — check latency (equals timeout value if timed out)
  • consecutive_failures — current failure count (0 on recovery)
  • checked_at — Unix timestamp of the check
  • timestamp — Unix timestamp when notification was sent

Delivery

Webhooks are delivered via Solenoid Relay with these headers:

Content-Type: application/json
X-Solenoid-Event: monitor.down
X-Solenoid-Signature: sha256=abc123...
X-Solenoid-Delivery-Id: 550e8400-e29b-41d4-a716-446655440000
User-Agent: Solenoid-Relay/1.0
  • Retries — 3 attempts with exponential backoff (1s, 5s, 15s) on 5xx or timeout
  • Idempotency — same event (monitor_id + status + checked_at) delivered once
  • No retry on 4xx — treated as client error

Verifying signatures

Verify the X-Solenoid-Signature header using your API key as the HMAC secret:

import crypto from "crypto";

function verifyWebhook(payload, signature, apiKey) {
  const hmac = crypto.createHmac("sha256", apiKey);
  hmac.update(payload);
  const expected = `sha256=${hmac.digest("hex")}`;
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

Cooldown behavior

Cooldown prevents notification spam when a service is flapping. Default: 5 minutes (300,000ms). Configurable via cooldown_ms (60,000-3,600,000ms).

  • State change (UP to DOWN, DOWN to UP) — fires immediately
  • DOWN to DOWN — suppressed until cooldown expires
  • UP to UP — no notification

Consecutive threshold

consecutive_threshold sets how many failures trigger a DOWN alert. Default: 1.

  • Threshold 1 — immediate alerts, sensitive to transient errors
  • Threshold 2-3 — reduces false positives from network blips
  • Threshold 5+ — only alerts on sustained outages

Email alerts (Pro/Scale)

Set email_alert: true to receive email notifications to the address on your API key. Email alerts follow the same cooldown rules as webhooks.

Testing webhooks

POST /v1/pulse/:monitorId/check does not trigger notifications — safe for testing.

To test webhook delivery, create a monitor pointing at an intentionally failing URL (e.g., https://httpstat.us/500) with a webhook_url pointing to webhook.site or a similar tool. Wait for a scheduled check to fire.

Delivery tracking

Query Relay for delivery status:

curl "https://api.solenoid.systems/v1/relay?filter=pulse" \
  -H "Authorization: Bearer YOUR_KEY"

See Relay docs for details.