← Blog
Developer Guides 8 min read

Webhook Monitoring: How to Verify Your Integrations Are Working

Webhooks are the connective tissue of modern SaaS — but they fail silently. No error page, no bounce, no user complaint until a critical flow breaks completely. Here's how to know your webhooks are actually delivering.

Every modern SaaS product relies on webhooks. Stripe fires a webhook when a subscription renews. GitHub fires one when a pull request is merged. Your own product probably sends webhooks to customer systems when something important happens. And your monitoring tool — hopefully — sends webhooks to your incident channel when something goes down.

The problem with webhooks is that they're push-based and fire-and-forget. The sender fires the request and moves on. If the receiver is down, if the URL changed, if the payload format was updated and the consumer stopped accepting it — the sender typically doesn't know. The integration breaks silently, sometimes for days before anyone notices.


How webhooks fail silently

There are several ways a webhook integration can stop working without producing an obvious error:

The receiving endpoint goes down

Your webhook receiver is an HTTP endpoint — a URL that accepts POST requests. If that endpoint returns a 500, or times out, or the server it's hosted on goes down, webhooks stop delivering. The sending service may log a delivery failure, but the consumer doesn't know unless someone checks the sender's dashboard. If you're not monitoring the webhook endpoint itself, you won't catch this until a user asks "why didn't we get notified about X?"

The URL changes without updating the sender

Your backend gets refactored. The webhook endpoint moves from /api/webhooks/stripe to /webhooks/stripe. The old URL now returns 404. Stripe is still sending to the old URL. Payments aren't being processed. Nobody knows.

Schema drift

The sending service updates their webhook payload format. A field gets renamed, a new required field is added, an enum value changes. Your consumer breaks because it expects the old format. It may silently discard the payload (if you have a try/catch that swallows errors) or it may start throwing 500s — which the sender logs as failures but doesn't alert you about.

Authentication failures

Many webhooks use a shared secret for verification. The sender signs the payload, the receiver verifies the signature. If the secret gets rotated on either side without updating the other, every webhook silently fails signature verification and gets discarded.


Strategy 1: Monitor the webhook endpoint with HTTP monitoring

The simplest layer of webhook monitoring: treat your webhook receiver URL like any other HTTP endpoint and add an HTTP monitor to it.

The catch is that webhook endpoints accept POST requests, not GET. Most monitoring tools default to GET. You need a monitor that:

PingBase HTTP monitors support custom HTTP methods (POST, PUT, etc.) and custom request bodies. You can configure a monitor that sends a POST to your webhook endpoint every minute with a test payload, verifying the endpoint is reachable and returning a healthy response code.

This catches the most common failures: endpoint down, URL changed, server crash. It doesn't verify end-to-end delivery — just that the endpoint is accepting requests.


Strategy 2: Heartbeat monitoring for webhook consumers

For deeper verification, use a heartbeat monitor. The idea: your webhook consumer, after successfully processing a webhook, pings a heartbeat URL. If PingBase stops receiving pings, it alerts you — the consumer stopped processing.

Implementation sketch for a Stripe webhook handler:

// After processing a webhook event successfully

app.post('/webhooks/stripe', async (req, res) => {

const event = stripe.webhooks.constructEvent(

req.body, req.headers['stripe-signature'], secret

);

await handleStripeEvent(event);

// Ping heartbeat to confirm successful processing

await fetch('https://app.pingba.se/ping/your-heartbeat-id');

res.sendStatus(200);

});

Configure the heartbeat monitor in PingBase with an interval that matches how frequently you expect webhooks: if Stripe fires a webhook at least once every hour (subscription renewals, payment attempts, etc.), set the heartbeat interval to 90 minutes. If PingBase doesn't receive a ping within that window, it alerts you — something stopped the consumer from processing.

This approach catches failures that HTTP monitoring misses: the endpoint returns 200 but the processing code throws an error that gets swallowed, the signature verification fails silently, the database write fails after the 200 is sent.


Strategy 3: Monitor your own webhook delivery

If your product sends webhooks to customer systems, you need to monitor delivery from your end too. Key metrics to track:

PingBase uses exponential backoff retry logic for its own webhook delivery: if a delivery fails, it retries at 1 minute, then 5 minutes, then 30 minutes, then 2 hours. After exhausting retries, the delivery is marked as permanently failed and the customer is notified via alternative channels. Your webhook system should do the same.

Common mistake: alerting on every delivery failure

Don't alert your team every time a single webhook delivery fails. Customer endpoints go down temporarily all the time. Alert when a delivery has failed across all retries — meaning the integration is permanently broken until the customer fixes their endpoint.


Verifying webhook signature validation

Most webhook senders sign their payloads with an HMAC signature. Your receiver should verify this signature on every request. But this verification code is often undertested — it's easy to accidentally disable it in development and forget to re-enable it, or to have a bug that makes verification always pass.

Test your signature validation explicitly:

  1. Send a webhook request with an invalid signature — your endpoint should return 400 or 401, not 200
  2. Send a webhook request with a missing signature header — same, should reject
  3. Send a webhook request with a valid signature — should return 200

Add these as integration tests that run in CI. A monitoring check that verifies your endpoint returns 4xx for unsigned requests can also be set up as an HTTP monitor with an expected response code of 400.


Webhook monitoring checklist

Check How to monitor
Webhook endpoint is reachableHTTP monitor (POST) on the endpoint URL
Consumer is processing eventsHeartbeat monitor — ping after each successful process
Outgoing deliveries succeedingApplication metric: delivery success rate
Retry queue not backing upApplication metric: queue depth alert
Signature validation workingIntegration test — invalid signature returns 4xx

Monitor your webhook endpoints with PingBase

HTTP monitors for webhook endpoint reachability, heartbeat monitors for end-to-end processing verification. Free for up to 5 monitors.

Get started free →

Related