{
"success": true,
"type": "monitor.check.completed",
"id": "whd_7a9c1e3b5d7f9a2c4e6b8d0f2a4c6e8b",
"created_at": "2026-10-12T06:01:27.944Z",
"monitor_id": "mon_3f9a1c2b7d4e4f6a8b0c1d2e3f4a5b6c",
"monitor_name": "Competitor pricing",
"check_id": "chk_8e2d4f6a1b3c4d5e6f7a8b9c0d1e2f3a",
"data": {
"status": "completed",
"trigger": "scheduled",
"summary": {
"total_pages": 19,
"same": 16,
"new": 1,
"changed": 1,
"removed": 1,
"error": 0
},
"started_at": "2026-10-12T06:00:04.112Z",
"finished_at": "2026-10-12T06:01:27.930Z",
"actual_credits": 24,
"error": null
},
"metadata": {
"env": "production"
}
}Webhooks
monitor.check.completed webhook
POSTed to your webhook once per check, with its status and page counts.
WEBHOOK
monitor.check.completed
{
"success": true,
"type": "monitor.check.completed",
"id": "whd_7a9c1e3b5d7f9a2c4e6b8d0f2a4c6e8b",
"created_at": "2026-10-12T06:01:27.944Z",
"monitor_id": "mon_3f9a1c2b7d4e4f6a8b0c1d2e3f4a5b6c",
"monitor_name": "Competitor pricing",
"check_id": "chk_8e2d4f6a1b3c4d5e6f7a8b9c0d1e2f3a",
"data": {
"status": "completed",
"trigger": "scheduled",
"summary": {
"total_pages": 19,
"same": 16,
"new": 1,
"changed": 1,
"removed": 1,
"error": 0
},
"started_at": "2026-10-12T06:00:04.112Z",
"finished_at": "2026-10-12T06:01:27.930Z",
"actual_credits": 24,
"error": null
},
"metadata": {
"env": "production"
}
}When it is sent
Once for every check that ran —completed, partial or failed — with the check’s summary counts and what it was charged.
It is also sent once when a monitor starts being skipped for lack of credits (skipped_no_credits), so you hear that checks have stopped. It is not repeated for every skipped check after that, and checks skipped because the previous one was still running (skipped_overlap) send nothing.
success is true only for a completed check. For a partial or failed check, data.error says why.
To receive only this event and not one per page, set the monitor’s webhook events to ["monitor.check.completed"].
Responding
Answer with any2xx within 10 seconds; failures are retried after 1, 5 and 15 minutes. The request is signed exactly like monitor.page — verify it the same way.
Reading the page results
The event carries counts, not pages. To see what changed, fetch the check:curl "https://api.prefetch.io/monitor/$MONITOR_ID/checks/$CHECK_ID?status=changed" \
-H "X-API-Key: $PREFETCH_API_KEY"
monitor_id and check_id are both in the event.
Related
monitor.page
One event per changed page, with its diff.
GET /monitor/{id}/checks/{checkId}
Everything a check found.
Authorizations
Your Prefetch API key. Obtain one from the dashboard.
Headers
The event type.
The delivery id — the same as id in the body, and stable across retries.
t=<unix seconds>,v1=<hex>, where hex is HMAC-SHA256 of "<t>.<raw body>" keyed with the monitor's webhook.secret.
Example:
"t=1760248862,v1=5f2b8c..."
Body
application/json
true only for a completed check.
Delivery id, also sent as X-Prefetch-Delivery. Stable across retries — use it to de-duplicate.
Example:
"whd_5c1e9a2b7d3f4e6a8b0c2d4e6f8a1b3c"
The metadata you set on the webhook.
Available options:
monitor.check.completed Show child attributes
Show child attributes
Response
200
Answer any 2xx within 10 seconds. Anything else, or no answer, is retried after 1, 5 and 15 minutes.