Webhooks

Send PixoMonitor alerts to any HTTP endpoint. Build custom integrations, connect to automation platforms, or create your own alert handling logic.

Overview

Webhooks provide the most flexible integration option in PixoMonitor. When a monitor status changes, PixoMonitor sends a POST request with structured JSON data to your specified URL.

Use webhooks for:

  • Custom alert handling and routing
  • Integration with automation platforms (Zapier, Make, n8n)
  • Triggering incident management workflows
  • Custom dashboards and reporting
  • Integration with systems not natively supported

Webhooks are the power-user integration. If PixoMonitor doesn't have a native integration for your tool, webhooks can usually bridge the gap.

Setting Up Webhooks

1

Prepare Your Endpoint

Create an HTTP endpoint that can receive POST requests. Your endpoint should:

  • Accept POST requests
  • Handle JSON content type
  • Return a 2xx status code on success
  • Respond within 30 seconds
2

Add Webhook Alert Channel

In PixoMonitor, go to Settings → Alert Channels and click Add Alert Channel:

  • Name: Descriptive name (e.g., "PagerDuty Webhook")
  • Type: Select Webhook
  • URL: Your endpoint URL (must be HTTPS for production)
  • Secret (optional): A shared secret for signature verification
3

Assign to Monitors

Add the webhook to monitors that should trigger it. You can also set it as a default for all new monitors.

4

Test the Integration

Use the Test button to send a test payload to your endpoint and verify it's working correctly.

Webhook Payload Format

PixoMonitor sends a JSON payload with the following structure:

Standard Alert Payload

{
  "event": "monitor.down",
  "monitor": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Production API",
    "url": "https://api.example.com/health",
    "type": "HTTP"
  },
  "alert": {
    "status": "DOWN",
    "error": "Connection timeout after 30000ms",
    "responseTime": null,
    "timestamp": "2026-03-24T10:30:45.123Z"
  }
}

Recovery Payload

{
  "event": "monitor.up",
  "monitor": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Production API",
    "url": "https://api.example.com/health",
    "type": "HTTP"
  },
  "alert": {
    "status": "UP",
    "error": null,
    "responseTime": 245,
    "timestamp": "2026-03-24T10:35:12.456Z"
  }
}

Anomaly Alert Payload

{
  "event": "monitor.anomaly",
  "monitor": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Production API",
    "url": "https://api.example.com/health",
    "type": "HTTP"
  },
  "alert": {
    "status": "ANOMALY",
    "error": null,
    "responseTime": 2450,
    "timestamp": "2026-03-24T10:32:00.789Z",
    "anomaly": {
      "responseTime": 2450,
      "baselineMean": 342,
      "baselineStdDev": 89,
      "threshold": 609
    }
  }
}

Event Types

EventDescription
monitor.downMonitor detected as down/unreachable
monitor.upMonitor recovered and is back online
monitor.anomalyPerformance anomaly detected (unusual response time)

Payload Fields Reference

Monitor Object

FieldTypeDescription
idUUIDUnique identifier for the monitor
namestringDisplay name of the monitor
urlstringTarget URL or host being monitored
typestringMonitor type (HTTP, TCP, PING, etc.)

Alert Object

FieldTypeDescription
statusstringCurrent status: UP, DOWN, ANOMALY
errorstring|nullError message if applicable
responseTimenumber|nullResponse time in milliseconds
timestampISO 8601When the alert was triggered

Anomaly Object (when applicable)

FieldTypeDescription
responseTimenumberActual response time that triggered the anomaly
baselineMeannumberAverage response time baseline
baselineStdDevnumberStandard deviation of baseline
thresholdnumberCalculated threshold that was exceeded

Webhook Security

Signature Verification

When you configure a secret for your webhook, PixoMonitor includes an HMAC-SHA256 signature in the request headers:

X-Signature: a1b2c3d4e5f6...

To verify the signature in your endpoint:

  1. Get the raw request body
  2. Compute HMAC-SHA256 using your secret
  3. Compare with the X-Signature header

Node.js Example:

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

Python Example:

import hmac
import hashlib
import json
 
def verify_signature(body, signature, secret):
    computed = hmac.new(
        secret.encode(),
        json.dumps(body).encode(),
        hashlib.sha256
    ).hexdigest()
    
    return hmac.compare_digest(signature, computed)

Always verify webhook signatures in production to ensure requests are genuinely from PixoMonitor and haven't been tampered with.

Request Details

Headers

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

HTTP Method

All webhook alerts are sent as POST requests.

Timeout

PixoMonitor waits up to 30 seconds for your endpoint to respond. Ensure your endpoint responds quickly to avoid timeouts.

Expected Response

Your endpoint should return:

  • 2xx status code — Alert delivered successfully
  • Other status codes — Alert will be logged as failed

Integration Examples

Zapier Integration

  1. Create a Zap with "Webhooks by Zapier" as the trigger
  2. Select "Catch Hook"
  3. Copy the webhook URL provided by Zapier
  4. Add this URL to PixoMonitor as a Webhook alert channel
  5. Build your Zap to handle the alert (send to email, create ticket, etc.)

PagerDuty Integration

Create a webhook that forwards to PagerDuty's Events API:

// Your webhook handler
async function handlePixoMonitorAlert(payload) {
  const pagerdutyPayload = {
    routing_key: 'YOUR_PAGERDUTY_KEY',
    event_action: payload.event === 'monitor.up' ? 'resolve' : 'trigger',
    dedup_key: `pixomonitor-${payload.monitor.id}`,
    payload: {
      summary: `${payload.monitor.name} is ${payload.alert.status}`,
      severity: payload.alert.status === 'DOWN' ? 'critical' : 'info',
      source: 'PixoMonitor',
      custom_details: payload
    }
  };
  
  await fetch('https://events.pagerduty.com/v2/enqueue', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(pagerdutyPayload)
  });
}

Custom Logging

Log all alerts to your own database or logging system:

async function handleAlert(payload) {
  await db.alerts.insert({
    monitor_id: payload.monitor.id,
    monitor_name: payload.monitor.name,
    event: payload.event,
    status: payload.alert.status,
    error: payload.alert.error,
    response_time: payload.alert.responseTime,
    received_at: new Date()
  });
  
  return { status: 'logged' };
}

Troubleshooting

Webhook Not Firing

  1. Check channel assignment: Ensure the webhook is attached to the monitor
  2. Verify URL: Make sure the URL is correct and accessible
  3. Test the channel: Use the Test button in alert channel settings
  4. Check endpoint logs: Review your endpoint's access logs

Invalid Signature

  • Verify you're using the exact secret configured in PixoMonitor
  • Ensure you're hashing the raw JSON body
  • Check for any middleware that might modify the request body

Timeout Errors

If your endpoint is timing out:

  • Optimize your handler to respond faster
  • Return immediately and process asynchronously
  • Increase your server's timeout settings (up to 30s)

Testing Locally

For local development, use tunneling services:

  • ngrok: ngrok http 3000 to expose local port
  • localtunnel: lt --port 3000
  • Cloudflare Tunnel: For production-grade tunneling

During development, use a service like webhook.site to inspect incoming webhook payloads before building your handler.