Marketplace Listing Change Detector
Pricing
from $2.00 / 1,000 resolved listing comparisons
Marketplace Listing Change Detector
Compare marketplace listing snapshots and get field-level new, changed, removed, unchanged, or unknown results. Failed or incomplete evidence never becomes a false removal.
Pricing
from $2.00 / 1,000 resolved listing comparisons
Rating
0.0
(0)
Developer
Mehdi Badawi
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
6 days ago
Last modified
Categories
Share
Compare marketplace listing snapshots and get field-level new, changed,
removed, unchanged, or unknown results. Failed or incomplete evidence
never becomes a false removal.
Start in 30 seconds
- Select Try for free and run with no input for a labeled demo.
- Supply current and prior listing snapshots with source coverage details.
- Schedule repeat runs after your collector produces each new snapshot.
Price: $0.002 per resolved listing comparison, plus a $0.00005 start event. Unknown, failed, incomplete-evidence, and demo results are free.
This Actor compares supplied snapshots. It does not collect Amazon, Walmart, Etsy, or eBay listings or claim live status without complete upstream evidence.
Why Listing-Truth Diff Matters
E-commerce sellers face recurring silent failures where platforms suppress, alter, or delist items without timely notification:
- Etsy: Silent search invisibility incidents where shops disappear from search rankings.
- Walmart: Items unpublished with specific reason codes (
INCORRECT_PRICE,POLICY_VIOLATION) surfaced via the Unpublished Items API. - Amazon: Buy Box hijacking, title overwrites, and bot detection blocking visibility checks.
- eBay: Silent delistings or VeRO actions where notifications arrive after the fact.
Generic diff tools and price monitors fail because they infer that an item missing from a failed or partial scrape has been "removed", or that a failed fetch means "unchanged". This Actor enforces honest failure semantics: when observation evidence is missing, incomplete, or blocked, it reports unknown and never false unchanged or removed.
Core Architecture & Truth Semantics
The Actor follows a clean separation between pure deterministic rules and platform plumbing:
src/core/diff.mjs: Pure evaluation core with no I/O, no wall clock, and no network dependencies.src/core/canonical.mjs: Stable listing identity resolution, fact normalization, and deterministic deep equality.src/main.mjs: Thin platform adapter that maps inputs from Apify into datasets and key-value store records.
Stable Listing Identity
Listing identity is canonicalized as:
<marketplace>/<listingId>
Examples: walmart/55885233, amazon/B08N5WRWNW, etsy/1596891234, ebay/123456789012. Marketplace names are normalized to lowercase trimmed strings; listing IDs support aliases (listingId, asin, itemId, id).
The 5 Diff Statuses
| Status | Definition |
|---|---|
new | Listing present in current snapshot, absent in prior snapshot (with successful fetch). |
unchanged | Listing present in both snapshots; all normalized facts are identical. |
changed | Listing present in both snapshots; one or more facts differ (emits field-level before/after diffs). |
removed | Listing present in prior snapshot, absent in current snapshot, and current snapshot is complete and verified. |
unknown | Current snapshot or listing fetch failed or was incomplete; truthful status cannot be determined. |
Honest Failure Semantics
- Incomplete Current Snapshot (
complete: false): If a current snapshot is marked partial or incomplete, any listing in the prior snapshot not observed in current emitsunknownwith reasonsnapshot-incomplete. It is never emitted asremoved. - Failed Current Snapshot (
fetchStatus: "failed"): If the current snapshot fetch failed, absent listings emitunknownwith reasonsnapshot-fetch-failed. - Per-Listing Fetch Failure (
fetchStatus: "blocked", etc.): If an anti-bot challenge or 403 blocks a listing fetch in the current snapshot, its verdict isunknownwith reasonlisting-fetch-failed.
Exact Source Provenance
Every emitted row retains complete provenance for both current and prior observations:
sourceId: Identifier of the source or connector.mechanism: Extraction method (api,scrape,feed,manual).uri: Endpoint or public listing URL.fetchedAt: Exact ISO-8601 timestamp of extraction.fetchStatus:ok,failed,blocked,timeout, etc.httpStatus: HTTP response code when applicable.error: Upstream error payload or message when fetch failed.
Input Schema (.actor/input_schema.json)
{"contractVersion": "1.0.0","evaluationTime": "2026-09-21T16:00:00Z","currentSnapshot": {"snapshotId": "snap-20260921-current","timestamp": "2026-09-21T12:00:00Z","complete": true,"source": {"id": "walmart-items-api","mechanism": "api","fetchStatus": "ok"},"listings": [{"marketplace": "walmart","listingId": "55885233","title": "Water Bottle 32oz","price": { "amount": 24.99, "currency": "USD" },"status": "unpublished","reasonCodes": ["POLICY_VIOLATION"]}]},"priorSnapshot": {"snapshotId": "snap-20260920-prior","timestamp": "2026-09-20T12:00:00Z","complete": true,"listings": [{"marketplace": "walmart","listingId": "55885233","title": "Water Bottle 32oz","price": { "amount": 19.99, "currency": "USD" },"status": "active"}]}}
Dataset Item Shape (.actor/dataset_schema.json)
Each dataset item represents a single listing diff:
{"contractVersion": "1.0.0","key": "walmart/55885233","marketplace": "walmart","listingId": "55885233","status": "changed","changes": [{"field": "price","before": { "amount": 19.99, "currency": "USD" },"after": { "amount": 24.99, "currency": "USD" }},{"field": "status","before": "active","after": "unpublished"}],"facts": {"title": "Water Bottle 32oz","price": { "amount": 24.99, "currency": "USD" },"status": "unpublished","reasonCodes": ["POLICY_VIOLATION"]},"priorFacts": {"title": "Water Bottle 32oz","price": { "amount": 19.99, "currency": "USD" },"status": "active"},"reasons": [],"provenance": {"current": { "sourceId": "walmart-items-api", "fetchStatus": "ok" },"prior": { "sourceId": "walmart-items-api", "fetchStatus": "ok" }},"evaluatedAt": "2026-09-21T16:00:00Z"}
Local Development & Testing
Running Tests
Tests use Node.js built-in test runner (node:test) and require no external dependencies, cloud accounts, or network access:
$npm test
Running the Actor (Credential-Free)
Running the Actor without credentials or input executes built-in multi-marketplace reference snapshots demonstrating all 5 statuses:
$npm start
Docker
Build and run using the standard Apify Node.js 22 runtime:
docker build -t marketplace-listing-truth .docker run --rm marketplace-listing-truth
Listing snapshots may contain nonpublic prices or inventory. Minimize supplied fields, preserve observed-at and evaluated-at timestamps, and delete datasets under the customer's retention policy. Upstream authentication, proxy cost, and collection rights remain outside this Actor. Support owner: Mehdi Badawi through the Apify Store support channel, with an initial-response target of two business days.