Event Webhooks

Receive real-time HTTP callbacks whenever something happens in your account — monitors created, incidents opened, team members added, and more.

Overview

Event webhooks push notifications to your server whenever account-level events occur. Unlike alert notifications (which fire on monitor state changes), event webhooks cover the full lifecycle of your account activity.

Use cases:

  • Sync monitor inventory with your CMDB or asset database
  • Trigger CI/CD pipelines on incident events
  • Feed events into Datadog, Splunk, or your data lake
  • Build custom dashboards or Slack/Teams integrations
  • Audit trail synchronization with external compliance tools

Setup

  1. Go to Dashboard → Settings → Event Webhooks
  2. Click "Add Webhook"
  3. Enter your endpoint URL (must be HTTPS in production)
  4. Select which event types to receive (or leave blank for all events)
  5. Click "Create" — a unique HMAC signing secret is generated automatically
  6. Copy the signing secret and store it securely — you'll need it to verify payloads

Use the "Test" button to send a test.ping event to verify your endpoint is receiving and processing webhooks correctly.

Event Types

EventTrigger
monitor.createdA new monitor is added
monitor.updatedMonitor settings changed (interval, URL, status, tags)
monitor.deletedA monitor is removed
incident.openedA new incident is created (auto or manual)
incident.updatedIncident status changed (investigating → identified → monitoring)
incident.closedIncident resolved
team.member_joinedA new member accepts a team invite
team.member_removedA team member is removed
status_page.updatedStatus page configuration changed
maintenance.startedA maintenance window is created
maintenance.endedA maintenance window is removed
test.pingManual test from the dashboard

Payload Format

All events are delivered as POST requests with a JSON body:

{
  "event": "monitor.created",
  "timestamp": "2026-04-07T14:30:00.000Z",
  "account_id": "a1b2c3d4-...",
  "data": {
    "resource_type": "monitor",
    "resource_id": "m1n2o3p4-...",
    "action": "created",
    "actor_email": "user@example.com",
    "details": {
      "website": "https://api.example.com",
      "check_type": "http",
      "interval_seconds": 60
    }
  }
}

The data.details object varies by event type and contains the relevant context for the action that occurred.

HMAC Signature Verification

Every webhook request includes an X-Signature-256 header containing an HMAC-SHA256 signature of the request body, computed using your webhook's signing secret.

Always verify this signature before processing the payload to ensure the request came from MyUpMonitor.

Node.js

const crypto = require('crypto');

function verifyWebhook(body, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(body)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

// In your Express handler:
app.post('/webhook', (req, res) => {
  const signature = req.headers['x-signature-256'];
  const body = JSON.stringify(req.body);

  if (!verifyWebhook(body, signature, process.env.WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }

  // Process the event
  console.log('Event:', req.body.event);
  res.status(200).send('OK');
});

Python

import hmac
import hashlib

def verify_webhook(body: bytes, signature: str, secret: str) -> bool:
    expected = hmac.new(
        secret.encode(), body, hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(signature, expected)

# In your Flask handler:
@app.route('/webhook', methods=['POST'])
def handle_webhook():
    signature = request.headers.get('X-Signature-256', '')
    if not verify_webhook(request.data, signature, WEBHOOK_SECRET):
        return 'Invalid signature', 401

    event = request.json
    print(f"Event: {event['event']}")
    return 'OK', 200

Go

package main

import (
    "crypto/hmac"
    "crypto/sha256"
    "encoding/hex"
    "io"
    "net/http"
)

func verifyWebhook(body []byte, signature, secret string) bool {
    mac := hmac.New(sha256.New, []byte(secret))
    mac.Write(body)
    expected := hex.EncodeToString(mac.Sum(nil))
    return hmac.Equal([]byte(signature), []byte(expected))
}

func handler(w http.ResponseWriter, r *http.Request) {
    body, _ := io.ReadAll(r.Body)
    signature := r.Header.Get("X-Signature-256")

    if !verifyWebhook(body, signature, os.Getenv("WEBHOOK_SECRET")) {
        http.Error(w, "Invalid signature", 401)
        return
    }

    // Process the event
    w.WriteHeader(200)
}

Retry Behavior

If your endpoint returns a non-2xx status code or the request times out (10 seconds), we retry with exponential backoff:

AttemptDelayTotal Elapsed
1st (initial)Immediate0s
2nd (retry)10 seconds10s
3rd (retry)30 seconds40s
4th (final)90 seconds130s

After 4 failed attempts, the event is dropped. Events are not queued — if your endpoint is down for an extended period, you may miss events.

Testing

Use these tools to test your webhook integration:

  • Dashboard test button — sends a test.ping event to your endpoint
  • webhook.site — free temporary endpoint for inspecting payloads
  • ngrok — expose your local server to receive webhooks during development

Best Practices

  • Respond with 2xx quickly — return a 200 status immediately, then process the event asynchronously. Slow responses trigger retries.
  • Verify signatures — always validate the X-Signature-256 header before processing.
  • Handle duplicates — retries may deliver the same event more than once. Use the timestamp and data.resource_id fields for idempotency.
  • Filter by event type — configure event filters in the dashboard to only receive events you need, reducing noise and bandwidth.
  • Use HTTPS — always use HTTPS endpoints in production to protect webhook payloads in transit.