Product Data QA & Price/Stock Change Report
Pricing
$0.25 / completed report
Product Data QA & Price/Stock Change Report
Validate product feeds and compare price/stock changes in two Apify datasets or JSON snapshots. Flag incomplete catalogs before updating your baseline.
Pricing
$0.25 / completed report
Rating
0.0
(0)
Developer
Adam
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
25 days ago
Last modified
Categories
Share
Product feed validation for developers running Apify product scrapers, pricing pipelines and ecommerce analytics agencies. Compare Apify datasets or small JSON snapshots for catalog QA and exact price/stock diffs before updating your baseline.
An incomplete scrape can look like a price change, a stockout or a deleted product. This Actor flags quality problems and recommends HOLD when the next baseline needs review. You supply two snapshots from the same collection scope; your workflow decides what to do with the recommendation.
Start in three steps
- Try the default demo. Run the prefilled synthetic input below; no source Dataset or report event is needed.
- Compare your snapshots. Choose
datasetsfor two completed Apify Dataset IDs orinlinefor two small arrays. Map the product key and price/currency/stock fields; confirm completeness only after checking the collections. - Read the report. Open Output → REPORT and check
gateandbaselineRecommendation. Keep the previous approved baseline after REVIEW/BLOCKED. Check MANIFEST and the result records before automating downstream actions.
What the result means
| Example | Result | What your workflow should do |
|---|---|---|
| Complete inline snapshot: A changes $100 → $90 and in stock → out of stock | PASS / ADVANCE; one changed product, one price change and one stock change | Consider advancing the baseline after your collection checks |
| Partial example below: B is absent from the current collection | REVIEW / HOLD; one NOT_OBSERVED product | Keep the previous baseline; absence is not proof of deletion or stockout |
| Identical valid snapshots | PASS / ADVANCE; zero changed products | A completed no-change report still counts as one report |
The partial example uses maxMissingPercent: 100 to show REVIEW. With the default 20% threshold, that same 50% missing collection is BLOCKED / HOLD. Neither result advances the baseline.
Price
$0.25 per completed comparison report, including platform usage in the listed customer price. PASS, REVIEW, BLOCKED and no-change reports each count as one report. There are no paid start or per-row events. The default demo has no report event; the copyable inline and datasets examples cost $0.25 when a report completes. Your upstream scraper and account services have their own costs.
Before you start
You must already have two product snapshots. This Actor does not scrape websites, provide an instant Shopify tracker, match products by similarity, convert currencies, or decide that a missing product was deleted. It recommends a baseline action; it does not change your baseline itself.
Inputs are limited to 10,000 combined rows, 10 MiB of remote data, or a 1 MiB inline body. Source Datasets are read only. The n8n workflow draft is UNVERIFIED and is not a ready-to-run integration.
Try a synthetic example
{"mode": "demo","monitorKey": "demo-catalog-usd","previousComplete": true,"currentComplete": true}
Demo uses fixed synthetic products and requests no report-completed event. It returns a PASS report with one price change and two stock changes across two products. Platform/account charges, where applicable, are separate from this statement.
Demo also writes one summary row to the run's default Dataset for Store health checks. It references the verified report fingerprint; the full report remains in the key-value store. Non-demo comparisons use only the key-value store outputs below. The prefilled completeness declarations apply to this synthetic example; verify them before comparing your own collection.
Try the incomplete-collection example ($0.25)
{"mode": "inline","monitorKey": "example-partial","previousComplete": true,"currentComplete": false,"maxMissingPercent": 100,"previousItems": [{ "sku": "A", "price": "100", "currency": "USD", "inStock": true },{ "sku": "B", "price": "200", "currency": "USD", "inStock": true }],"currentItems": [{ "sku": "A", "price": "90", "currency": "USD", "inStock": false }]}
Expected: REVIEW / HOLD, one unobserved product and one changed product. Keep the previous baseline; B is not reported as deleted. The 100% missing threshold here demonstrates a review case; the default 20% threshold would produce BLOCKED / HOLD for this input. Both are completed diagnostic reports and the report price applies.
Compare your own data
Use mode: "datasets" with two different Dataset IDs, or mode: "inline" with two small arrays. The selected source Datasets are read only. One row must represent one product or variant. Both snapshots use the same field mappings.
Compare two Apify datasets
Select two completed snapshots from your own account in the Previous Dataset and Current Dataset fields. Replace the example IDs below; the Actor requests READ access only. Set both completeness declarations to true only when you have checked that both collections are complete.
{"mode": "datasets","monitorKey": "my-store-usd","previousDatasetId": "REPLACE_PREVIOUS_DATASET_ID","currentDatasetId": "REPLACE_CURRENT_DATASET_ID","previousComplete": false,"currentComplete": false}
With these conservative declarations, a valid comparison returns HOLD. Use the same store, region, currency, filters and field mappings on both sides. Missing or inaccessible IDs are rejected without a report event.
Compare small JSON snapshots ($0.25)
{"mode": "inline","monitorKey": "my-store-usd","keyFields": ["sku"],"comparisonScope": "price_and_stock","previousComplete": true,"currentComplete": true,"previousItems": [{ "sku": "A", "price": "100.00", "currency": "USD", "inStock": true }],"currentItems": [{ "sku": "A", "price": "90.00", "currency": "USD", "inStock": false }]}
The observed price change has before="100", after="90", delta="-10" and percent="-10". Both fields changed, but changedProducts is 1. This complete, valid input passes the default quality rules.
Only set the completeness declarations to true after checking your collection. They are caller declarations, not independently verified evidence.
No changes
{"mode": "inline","monitorKey": "example-no-change","previousComplete": true,"currentComplete": true,"previousItems": [{ "sku": "A", "price": "100", "currency": "USD", "inStock": true }],"currentItems": [{ "sku": "A", "price": "100", "currency": "USD", "inStock": true }]}
Expected: PASS / ADVANCE, zero changed products. This is a completed report and the report price applies.
Results
Outputs are fixed records in the run's default key-value store:
| Record | Contents |
|---|---|
| REPORT | Quality gate, baseline recommendation, checked fields, settings, version and summary |
| CHANGES | Typed product keys, source row references and normalized changes |
| ISSUES | Issue codes, affected source rows and corrective guidance |
| CHANGES_CSV / ISSUES_CSV | Human-readable exports |
| MANIFEST | Completion marker, required records and SHA-256 fingerprints |
| BILLING_STATUS | Report-event request/reconciliation status |
Check MANIFEST.reportReady and the required records before consuming the report. A successful platform run does not by itself mean the data passed QA. JSON is the automation format. CSV identity/text fields use JSON-style rendering to reduce formula-injection risks; spreadsheet import and re-saving behavior varies.
Quality gates and baselines
- PASS / ADVANCE: the performed checks passed, both snapshots were declared complete and no hold condition was found.
- REVIEW / HOLD: incomplete declarations, unobserved keys below the blocking threshold, invalid field values, unknown stock, currency mismatch, extreme price changes or an undefined percentage from a zero baseline.
- BLOCKED / HOLD: missing or duplicate identities, an empty current snapshot, no unambiguous matched keys, or excessive unobserved keys.
An empty previous snapshot is rejected. An empty current snapshot produces a completed BLOCKED diagnostic report. Neither case is interpreted as proof of product deletion.
Duplicate keys on either side are excluded from both sides. Missing percentage uses eligible previous keys, not the difference in row counts. At a zero missing threshold, zero missing keys passes; any missing key blocks.
A permanently unobserved product can keep the monitor on HOLD indefinitely. To intentionally change scope, pause the workflow and explicitly select a new baseline, recording the reason; use a new monitor key when appropriate. A manually selected baseline is not presented as an Actor-validated PASS.
Supported values and limits
- Combined input: 10,000 rows across both snapshots.
- Remote input: 10 MiB decompressed response bytes in total, including metadata.
- Inline input: 1 MiB serialized UTF-8 body, checked after the SDK loads the input.
- Exact identity: one or two string/safe-integer fields. String
"001"and number1are different keys. - Safe dot paths: up to four levels. Array indices, wildcards, code and prototype paths are unsupported.
- Prices: nonnegative plain decimals, up to 18 integer digits and 8 fractional digits. Decimal strings are recommended. Existing JSON-number precision loss cannot be recovered.
- Money output: decimal strings. Percentage display rounds to four decimal places; thresholds use the exact value before rounding.
- Currency: trimmed uppercase three-letter format. Registry membership and exchange conversion are not checked.
- Stock:
true,false,"in_stock","out_of_stock". Other values remain unknown.price_onlyskips stock inspection. - Default thresholds: price alert 5%, extreme change review 50%, missing-key block 20%, with inclusive boundaries for actual changes/missing keys.
Prices with symbols, commas, exponent strings or locale-specific separators are not automatically corrected. Missing/null/empty values are not converted to zero or false. A zero baseline has no percentage change; 0→0 is unchanged and 0→positive requires review.
Use 512 MiB and a run timeout no greater than 60 seconds. Inputs are rejected on limits or detected source changes; data is not silently truncated into a normal report. Metadata checks do not guarantee transactional snapshot consistency.
For synthetic demo mode only, the Actor also accepts the 300-second platform timeout used by Store automated tests. Its internal 60-second execution deadline still applies. Inline and Dataset comparisons require a platform timeout of 60 seconds or less.
Report-event billing
The price is $0.25 per completed report, with platform usage included in the listed customer price. PASS, REVIEW, BLOCKED and no-change reports each count as one completed report. There are no paid start or per-row events. The Actor requests report-completed only after verifying the required results and MANIFEST were saved.
Demo, invalid input, unavailable sources, input-limit rejection and mandatory-result-save failures do not request this report event. Set a finite maximum run charge that permits one configured report event. Other paid event types are unsupported by this implementation.
If an event request or reconciliation is ambiguous, results remain available and BILLING_UNCONFIRMED is returned. The Actor does not blindly issue a fresh charge on same-run recovery. This is not a guarantee of settlement or distributed exactly-once behavior. Do not start a new paid run just because polling timed out; reconcile the existing run first.
Privacy and automation
Only provide product/variant data you are permitted to process. Source data is not modified. Input and output can remain in Apify storage according to your account's retention settings. Raw product payloads, credentials and signed URLs are not intentionally logged. No LLM or external telemetry service is used by the comparison engine.
Keep the last PASS baseline after REVIEW/BLOCKED. Deduplicate collection events by source run ID and serialize processing per monitor. The accompanying n8n state-transition draft is UNVERIFIED and is not a ready-to-run hosted integration.
For issue reports, share the engine version, safe error code and a synthetic reproduction. Do not include credentials, personal data or signed URLs. Custom data transformations and managed workflows are outside the supported scope.