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
- Go to Dashboard → Settings → Event Webhooks
- Click "Add Webhook"
- Enter your endpoint URL (must be HTTPS in production)
- Select which event types to receive (or leave blank for all events)
- Click "Create" — a unique HMAC signing secret is generated automatically
- 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
| Event | Trigger |
|---|---|
monitor.created | A new monitor is added |
monitor.updated | Monitor settings changed (interval, URL, status, tags) |
monitor.deleted | A monitor is removed |
incident.opened | A new incident is created (auto or manual) |
incident.updated | Incident status changed (investigating → identified → monitoring) |
incident.closed | Incident resolved |
team.member_joined | A new member accepts a team invite |
team.member_removed | A team member is removed |
status_page.updated | Status page configuration changed |
maintenance.started | A maintenance window is created |
maintenance.ended | A maintenance window is removed |
test.ping | Manual 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:
| Attempt | Delay | Total Elapsed |
|---|---|---|
| 1st (initial) | Immediate | 0s |
| 2nd (retry) | 10 seconds | 10s |
| 3rd (retry) | 30 seconds | 40s |
| 4th (final) | 90 seconds | 130s |
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.pingevent 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-256header before processing. - Handle duplicates — retries may deliver the same event more than once. Use the
timestampanddata.resource_idfields 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.