Define what matters on each source
Create a watchlist with an application ID, source URL, owner, and description of the relevant change. Choose the target by the question you want to answer:
Use the monitoring guide for cURL and SDK requests. For example, send this body to
POST /monitors, replacing the source and webhook URL:
Monitor request body
id, initial_run_id, and generated webhook secret with your watchlist record. Store the secret securely. The first run establishes a baseline; it is not a new-change alert.
Verify and persist before acknowledging
Read the raw webhook body and verifyX-Context-Signature using the signature verification implementation. The signature covers the timestamp and raw bytes. This Python equivalent uses the same protocol:
verify_webhook.py
accept_verified_event also checks that the event belongs to the monitor associated with the verified secret. Route your webhook using the application watch ID, resolve its stored monitor and secret, then verify the signature, validate the payload, and call this function.
digest_store.py
change.detected or run.completed schema before calling the store. Return 2xx only after the event insert commits. A worker can then call process_events; its transaction saves the derived records and marks the event processed together.
Deduplicate both levels. Event id handles a repeated delivery. Change id handles a changed run arriving through both event subscriptions, or later through polling. Both paths should produce one digest item.
Reconcile deliveries and failed checks
run.completed reports completed runs, including baselines and runs with no change. Failed and skipped checks require the runs API; absence of a webhook does not mean “no change.”
The following polling worker imports the store functions above. It reads every page of runs and changes and uses the same record IDs as the webhook path. For a larger history, persist a reconciliation cursor and continue the job across bounded worker executions.
reconcile_digest.py
webhook_failure and individual run delivery records when diagnosing delivery problems.
Make freshness visible in the digest
Compute the last successful observation from completed runs rather than from the latest attempt:Last successful check
Exercise duplicate and missing events
Process one change event twice, then process therun.completed event for the same changed run: the store should contain one change. Skip another webhook and reconcile it through the API. Add a failed run and check that the last successful observation remains intact while the failure appears in the watchlist.
Monitor setup and signatures
Configure targets, intervals, and verified webhook delivery.
Structured datasets
Refresh extracted records after a relevant source change.