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 attempts — 11 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
failedorexhausteddepending 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
| Attempt | When it runs |
|---|---|
| 1st | Immediately when the change is detected |
| 2nd | ≥ 1 minute after the 1st fails |
| 3rd | ≥ 2 minutes after the 2nd fails |
| 4th | ≥ 4 minutes after the 3rd fails |
| 5th | ≥ 8 minutes after the 4th fails |
| 6th | ≥ 16 minutes after the 5th fails |
| 7th | ≥ 32 minutes after the 6th fails |
| 8th | ≥ 64 minutes (~1 h) after the 7th fails |
| 9th | ≥ 128 minutes (~2 h) after the 8th fails |
| 10th | ≥ 256 minutes (~4 h) after the 9th fails |
| 11th | ≥ 512 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.