GuidesReceiving Webhooks

Receiving Webhooks

When DiffHook detects a change, it sends an HTTP POST to the resolved delivery URL: per-monitor notification_config.webhook_url if set, otherwise your workspace default webhook from Integrations. The JSON body below is the payload DiffHook sends (not the monitor configuration).

Webhook payload

{
  "event": "page.changed",
  "monitor_id": "mon_abc123",
  "url": "https://competitor.com/pricing",
  "triggered_at": "2026-03-16T14:22:00Z",
  "content": "Pro plan: $59/month — …"
}

Field reference

event — Always page.changed for content change events.

monitor_id — The ID of the monitor that triggered the event.

url — The monitored URL for this event.

triggered_at — ISO 8601 timestamp of when the change was detected.

content — The new page content after the change (normalised / extracted text used for monitoring — same as the snapshot DiffHook diffed against the previous version).

Delivery guarantees

  • On each detected change, DiffHook makes one immediate HTTP POST. If that fails (non-2xx, network error, or timeout), it schedules up to 10 more attempts11 delivery tries in total if your endpoint never succeeds.
  • Backoff between attempts is exponential in minutes: after each failure, the next try is eligible after 1, 2, 4, 8, 16, 32, 64, 128, 256, then 512 minutes (each delay is double the previous). Retries are picked up on a roughly once-per-minute schedule, so timing is not sub-second precise.
  • A delivery is considered successful when your endpoint returns 2xx within 10 seconds.
  • After all attempts are used, the delivery stops; the row in App → Logs shows failed or exhausted depending on channel state.

Responding to webhooks

Your endpoint should return 200 OK as quickly as possible. Process the payload asynchronously:

app.post('/webhook', (req, res) => {
  res.status(200).send('OK')       // Respond first
  processChangeAsync(req.body)     // Then process
})

Retry behavior

AttemptWhen it runs
1stImmediately when the change is detected
2nd1 minute after the 1st fails
3rd2 minutes after the 2nd fails
4th4 minutes after the 3rd fails
5th8 minutes after the 4th fails
6th16 minutes after the 5th fails
7th32 minutes after the 6th fails
8th64 minutes (~1 h) after the 7th fails
9th128 minutes (~2 h) after the 8th fails
10th256 minutes (~4 h) after the 9th fails
11th512 minutes (~8.5 h) after the 10th fails

After 11 unsuccessful attempts (1 initial + 10 retries), no further automatic delivery runs for that event. Fix your endpoint and use Trigger now on the monitor if you need another fire.