Integration

Webhooks

Custom integrations via HTTP callbacks

Webhooks

Build custom integrations with APIAssert. Webhooks send HTTP POST requests to your endpoint whenever monitors fail, recover, or trigger other events.

Why Webhooks?

  • Build anything — connect to any system that accepts HTTP
  • Full control — process alerts your way
  • Automation — trigger workflows, scripts, or CI/CD pipelines
  • Custom dashboards — feed data to your internal tools

What You'll Get

  • JSON payloads with complete monitor and alert data
  • Retry logic for failed deliveries
  • Signature verification for secure webhooks
  • Custom headers for authentication

Setup Guide

Step 1: Create Your Endpoint

Set up an HTTP endpoint to receive POST requests:

// Express.js example
app.post('/webhooks/pingpost', (req, res) => {
  const payload = req.body;

  console.log('Alert received:', payload.event);
  console.log('Monitor:', payload.monitor.name);

  // Process the alert...

  res.status(200).send('OK');
});

Step 2: Add Webhook in APIAssert

  1. Go to AlertsChannels in your APIAssert dashboard
  2. Click Add ChannelWebhook
  3. Enter your endpoint URL
  4. (Optional) Add authentication headers
  5. Click Save

Step 3: Test the Webhook

Click Send Test to verify your endpoint receives payloads correctly.

Step 4: Assign to Monitors

Edit your monitors and add the webhook channel under Alert Channels.

Payload Format

APIAssert sends JSON payloads with this structure:

{
  "event": "monitor.failed",
  "timestamp": "2024-12-11T14:34:00Z",
  "monitor": {
    "id": "mon_abc123",
    "name": "Production API",
    "url": "https://api.example.com/health",
    "method": "GET",
    "interval": 60
  },
  "check": {
    "id": "chk_xyz789",
    "status_code": 500,
    "response_time_ms": 2340,
    "region": "us-east",
    "checked_at": "2024-12-11T14:34:00Z"
  },
  "failure": {
    "type": "assertion",
    "message": "$.status expected 'success', got 'error'",
    "assertion": {
      "path": "$.status",
      "operator": "equals",
      "expected": "success",
      "actual": "error"
    }
  },
  "alert": {
    "id": "alt_def456",
    "state": "triggered",
    "consecutive_failures": 3
  }
}

Event Types

Event Description
monitor.failed Monitor detected a failure
monitor.recovered Monitor returned to healthy state
monitor.degraded Response time exceeded threshold
test Test webhook from dashboard

Authentication

Bearer Token

Add a Bearer token header:

Header: Authorization
Value: Bearer your-secret-token

Custom Headers

Add any custom headers your endpoint requires:

X-API-Key: your-api-key
X-Webhook-Source: pingpost

Signature Verification

APIAssert signs webhook payloads with HMAC-SHA256. Verify signatures to ensure requests are authentic:

const crypto = require('crypto');

function verifySignature(payload, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(JSON.stringify(payload))
    .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

// In your handler:
const signature = req.headers['x-pingpost-signature'];
if (!verifySignature(req.body, signature, process.env.WEBHOOK_SECRET)) {
  return res.status(401).send('Invalid signature');
}

Use Cases

Trigger CI/CD Pipeline

Restart services when health checks fail:

# GitHub Actions workflow
on:
  repository_dispatch:
    types: [pingpost-alert]

jobs:
  restart:
    runs-on: ubuntu-latest
    steps:
      - run: ./scripts/restart-service.sh

Update Status Page

Post to your status page when monitors fail:

app.post('/webhooks/pingpost', async (req, res) => {
  if (req.body.event === 'monitor.failed') {
    await statusPage.createIncident({
      name: `${req.body.monitor.name} is down`,
      status: 'investigating'
    });
  }
  res.send('OK');
});

Send to Custom Slack Format

Transform and forward to Slack with custom formatting:

app.post('/webhooks/pingpost', async (req, res) => {
  const { monitor, check, failure } = req.body;

  await fetch(process.env.SLACK_WEBHOOK, {
    method: 'POST',
    body: JSON.stringify({
      blocks: [
        {
          type: 'header',
          text: { type: 'plain_text', text: `🚨 ${monitor.name}` }
        },
        {
          type: 'section',
          text: { type: 'mrkdwn', text: failure.message }
        }
      ]
    })
  });

  res.send('OK');
});

Retry Policy

APIAssert retries failed webhook deliveries:

  • 3 attempts total
  • Exponential backoff: 10s, 30s, 90s
  • Timeout: 10 seconds per request
  • Success: Any 2xx response code

Troubleshooting

Not receiving webhooks?

  • Ensure your endpoint is publicly accessible
  • Check firewall rules allow incoming POST requests
  • Verify the URL is correct (no typos, correct protocol)

Getting 4xx/5xx errors?

  • Check your endpoint logs for errors
  • Verify authentication headers are correct
  • Ensure your endpoint returns 2xx on success

Payloads look different than expected?

  • Use the Send Test feature to see exact payload format
  • Check our API changelog for any recent changes

Next Steps