Integrations

Custom Webhooks

Custom Webhooks

Send monitoring events to any HTTP endpoint using custom webhooks. Perfect for integrating with custom tools, ticketing systems, incident management platforms, or automation workflows.

Pro Feature

Custom webhooks are available on Pro and Business plans.

Webhook Payload

When an event occurs, we'll send a POST request to your endpoint with a JSON payload:

{
  "event": "monitor.down",
  "timestamp": "2026-01-26T12:00:00Z",
  "monitor": {
    "id": 123,
    "name": "My Website",
    "url": "https://example.com",
    "dashboard_url": "https://sentinel.rootstuff.io/acme/monitors/123"
  },
  "status": {
    "current": "offline",
    "previous": "online",
    "root_cause": "HTTP 503 Service Unavailable",
    "region": "ash",
    "is_regional_issue": false
  },
  "incident": {
    "id": 456,
    "started_at": "2026-01-26T12:00:00Z",
    "dashboard_url": "https://sentinel.rootstuff.io/acme/incidents/456"
  }
}

The dashboard_url fields deep-link back into Sentinel. Map them into your incident tool's alert template so whoever gets paged can open the monitor or the incident in one click. Both are null in the rare case a monitor has no team.

Event Types

  • monitor.down — HTTP monitor went offline
  • monitor.up — HTTP monitor recovered and is back online
  • monitor.ping_failed / monitor.ping_recovered — ICMP ping reachability changed
  • monitor.port_failed / monitor.port_recovered — TCP port reachability changed
  • monitor.heartbeat_missed / monitor.heartbeat_recovered — heartbeat or cron job missed or resumed
  • monitor.keyword_found / monitor.keyword_missing / monitor.keyword_resolved — keyword-check transitions
  • monitor.json_assertion_failed / monitor.json_assertion_resolved — JSON response-body assertion transitions
  • monitor.payment_check_failed / monitor.payment_check_resolved — agent payment (x402/MPP 402 challenge) transitions

Request Headers

Every webhook request includes the following headers:

  • Content-Type: application/json
  • User-Agent: Sentinel Webhook/1.0
  • X-Webhook-Signature: sha256=<signature> (if secret configured)

Security

  • Webhook URLs must use HTTPS (HTTP not allowed)
  • Add a signing secret to verify requests are from Sentinel
  • Generate a secret automatically or use your own (min 16 characters)
  • Signatures are sent in the X-Webhook-Signature header
  • 10 second timeout on webhook requests

Delivery & Retries

  • Each event is delivered with up to 3 attempts (1s, then 5s between attempts)
  • Connection failures, 5xx responses, and 429 responses are retried
  • Other 4xx responses are not retried: fix the endpoint and use a test notification to verify
  • Respond with a 2xx status quickly and process asynchronously; slow endpoints risk hitting the 10 second timeout

Signature Verification

If you configure a webhook secret, we sign all payloads using HMAC-SHA256. Verify signatures to ensure requests are authentic:

// Node.js example
const crypto = require('crypto');

function verifySignature(payload, signature, secret) {
  const expected = 'sha256=' + crypto
    .createHmac('sha256', secret)
    .update(JSON.stringify(payload))
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

Delivery Log

Every delivery leaves a receipt: the payload Sentinel sent, the HTTP status your endpoint answered with (or the connection error if it never answered), how many attempts it took, and how long it waited. Receipts are kept for 30 days.

On the Integrations page, each endpoint shows its last delivery and, if the last few were rejected, a failure streak with the status your endpoint returned. Expand Recent deliveries under an endpoint to see the last ten.

The same receipts are available through the API, newest first, with the full payload attached so you can match a page in your incident tool to the exact event behind it:

GET /api/webhook-endpoints/{id}/deliveries
GET /api/webhook-endpoints/{id}/deliveries?failed=1

{
  "total": 42,
  "per_page": 50,
  "current_page": 1,
  "last_page": 1,
  "data": [
    {
      "id": 9812,
      "at": "2026-09-03T16:51:42Z",
      "event": "monitor.down",
      "monitor_id": 184,
      "monitor": "online.vbotickets.com",
      "succeeded": false,
      "response_status": 401,
      "response_excerpt": "invalid secret",
      "attempts": 1,
      "duration_ms": 214,
      "error": null,
      "payload": { "event": "monitor.down", "...": "..." }
    }
  ]
}

GET /api/webhook-endpoints/{id} also carries last_delivered_at, last_failed_at, last_response_status, and consecutive_failures, so an endpoint's health fits in one call.