Change & Alert Engine - Webhook on Change avatar

Change & Alert Engine - Webhook on Change

Pricing

from $10.00 / 1,000 change emitteds

Go to Apify Store
Change & Alert Engine - Webhook on Change

Change & Alert Engine - Webhook on Change

Generic change-detection engine: poll any URL, JSON feed or RSS/Atom feed, diff it against the last seen state (key-value store), and push ONLY the changes to the dataset and/or a webhook. Each change carries {item_id, change_type, before, after, changed_at}.

Pricing

from $10.00 / 1,000 change emitteds

Rating

0.0

(0)

Developer

Oaida Adrian

Oaida Adrian

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 hours ago

Last modified

Share

Change & Alert Engine — Webhook on Change (any URL / RSS / JSON)

A generic change-detection engine: point it at any URL — a JSON feed, an RSS/Atom feed, or a plain HTML page — and it diffs each poll against the last seen state (stored in the actor's key-value store) and emits ONLY the changes, with before and after values, to the dataset and/or your webhook.

Turn any batch poller into a push actor: no more re-downloading an entire feed to find what's new — the actor tells you exactly which items changed, and nothing else.

Why a change & alert engine?

  • Event-driven beats batch. Most data jobs re-pull the whole source every run and waste time/money on unchanged data. A delta engine wakes up, checks what actually moved, and pushes only the diff.
  • One actor, every source. Recalls lists, government notices, price tables, news feeds, release notes — if it's a URL, this engine watches it.
  • Structured before/after. Consumers get
    {item_id, change_type, before, after, changed_at}
    — enough to render "what changed" without keeping their own copy of the previous state.

How it works

  1. Poll — the actor fetches sourceUrl once per run (schedule it with your chosen interval; the actor is a single-shot poll).
  2. Parse — content is sniffed automatically:
    • JSON — arrays are used directly; object feeds auto-detect common list keys (items, results, data, records, entries…) or use itemsPath for a dot path (data.records).
    • RSS / Atom — items are parsed with stable ids (guid or link).
    • HTML — the page becomes a single monitored item keyed on a content hash (page-level change detection).
  3. Diff — each item gets a stable item_id (idField, natural keys, or a content hash fallback) and a content hash. The current snapshot is compared to the persisted one:
    • new id → added (before null)
    • same id, different hash → modified (before + after full values)
    • id missing from the current fetch → removed (only with includeRemovals: true)
  4. Emit — changed items are pushed to the dataset, one per item, and (optionally) one batched webhook POST is sent per run that has changes. Nothing is emitted on a clean poll.
  5. Persist — the new state is saved to the key-value store so the next poll diffs against it.

Input

FieldTypeDescription
sourceUrlstringURL to monitor (JSON feed, RSS/Atom, or HTML page). When empty, the actor polls the Hacker News front page feed by default.
intervalstringInformational — how often you schedule the actor (e.g. 15m, 1h, 0 9 * * *). Included in the webhook payload.
webhookstringOptional URL. One POST with the full changes payload per run that has changes; never fired on a clean run.
dedupebooltrue (default): persist state and emit only diffs. false: emit the full snapshot every run without persisting.
itemsPathstringDot path to the item list inside a JSON object (e.g. data.records). Auto-detected when empty.
idFieldstringField to use as the stable item id. Natural keys (id, guid, itemId, permalink, slug, link, url, title, name) are tried when empty.
ignoreFieldsstringComma-separated top-level fields stripped before hashing (e.g. updatedAt) so volatile metadata doesn't cause false modifications.
includeRemovalsboolReport items that disappeared from the feed as removed (after null). Off by default.
maxItemsintMax items considered per poll (default 500, max 20 000).

Example input:

{
"sourceUrl": "https://recalls-rappels.canada.ca/en/search?search_api_fulltext=",
"interval": "15m",
"webhook": "https://hooks.example.com/alerts",
"dedupe": true
}

Output

One dataset item per change:

FieldDescription
item_idStable id of the changed item.
change_typeadded, modified, or removed.
beforePrevious value (full item) — null for additions.
afterNew value (full item) — null for removals.
changed_atWhen the change was detected (ISO-8601 UTC).
sourceUrl / polledAtMonitoring context.

Webhook payload (one POST per run with changes):

{
"sourceUrl": "https://…",
"polledAt": "2026-08-13T12:00:00.000000+00:00",
"requestedInterval": "15m",
"changeCount": 2,
"changes": [
{"item_id": "r1", "change_type": "modified",
"before": {"id": "r1", "risk": "Fire"},
"after": {"id": "r1", "risk": "Fire + Shock"},
"changed_at": "2026-08-13T12:00:00.000000+00:00"}
]
}

Use cases

  • Government / safety monitors — watch a recalls search page or a regulatory feed; get a webhook the moment a new notice appears.
  • Price & inventory alerts — poll a product JSON endpoint; emit only rows whose price/stock changed, with old and new values side by side.
  • News / press-release watchers — diff an RSS feed and forward only the new entries to a chat webhook.
  • Status pages — monitor an HTML status page by content hash; you are notified only when the page actually changes.

Delivery semantics

  • At-least-once. State is persisted only after a successful webhook delivery (or immediately when no webhook is configured). If the POST fails, the run FAILS and the next run re-emits the same changes — an alert is never silently lost.
  • Within-run dedupe. Duplicate item ids in one fetch collapse to the last occurrence, so a feed that repeats entries won't double-notify.

Pricing

Pay per event — you only pay for what you extract:

  • apify-actor-start — one-time charge per run.
  • result — per change emitted (default primary event).

No monthly fee, no hidden costs. A clean poll (nothing changed) extracts nothing and charges nothing beyond the actor start.

Limitations

  • The engine compares current fetch vs last persisted fetch — items that leave the feed are only reported with includeRemovals: true (off by default because first-page rotation is often noise).
  • JSON items without any natural id fall back to a content hash as the id — with no stable id, any edit looks like an add+remove pair; set idField for clean modified detection.
  • The actor polls once per run; the interval is your schedule on the actor (or an external scheduler). It does not stay resident between polls.
  • Feeds with per-item volatile timestamps can look "modified" every poll — list those fields in ignoreFields to hash only what matters.