Shopify Reseller Price & Stock Evidence Monitor
Pricing
from $1.00 / 1,000 catalog-dealer evaluations
Shopify Reseller Price & Stock Evidence Monitor
Compare exact SKUs and barcodes across supplied Shopify dealer URLs. Capture price, currency, published availability and snapshot changes per catalog item and dealer context. Unofficial; no dealer discovery, exact stock quantities or MAP verdicts.
Pricing
from $1.00 / 1,000 catalog-dealer evaluations
Rating
0.0
(0)
Developer
Felix GoldWin
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Turn an explicit list of Shopify dealer product pages and a nonsecret SKU/barcode catalog into repeatable price and purchasability evidence. Each dataset row represents one catalog item × one dealer host/locale context, with exact candidate variants aggregated across the supplied product URLs. No credentials are needed.
This adapter supports Shopify-hosted theme storefronts exposing the documented Ajax Product API. It does not discover dealers, crawl collections, search a store, support arbitrary commerce platforms, or claim coverage of headless Shopify stores.
Input and a first run
Use examples/input.json for a small public Shopify Hardware example. Product availability and price may change. The example is a technical API check, not evidence that Shopify Hardware is an independent reseller or that any brand authorizes a dealer.
{"dealerHosts": ["hardware.shopify.com"],"productUrls": ["https://hardware.shopify.com/products/shopify-pos-go"],"catalog": [{"id":"shopify-pos-go","sku":"887675103492","barcode":"887675103492"}],"maxRequests": 4,"maxResults": 5,"maxBudgetUsd": 0.05}
npm ci --ignore-scriptsnpm testnpm run validate:schemanpm run smoke
For the actual SDK entrypoint, put the input at storage/key_value_stores/default/INPUT.json, then run npm start. Local smoke uses no account or paid Apify run. See PUBLISHING.md for deployment checks and QA.md for tested scope.
dealerHosts is an exact lowercase hostname allowlist (1–10). productUrls accepts 1–50 canonical HTTPS URLs in /products/handle or /locale/products/handle form. Queries, fragments, credentials, ports, percent escapes and custom headers are rejected. The Actor derives only those product .js endpoints and a same-host/same-locale cart.js GET for currency. It never mutates a cart or carries user cookies.
The catalog accepts 1–100 items with a unique id, and sku, barcode, or both. Identifiers are exact and case sensitive; leading zeros are preserved. Titles and vendor names never create a match. A single exact match is labeled unique_exact_match; more than one candidate is ambiguous_exact_matches. If one identifier matches but another supplied, published identifier disagrees, the row is identifier_conflict and preserves both values. A no-match row is not_matched_in_supplied_urls. Missing other identifiers remain unknown; they are not conflicts.
Evidence and changes
Each matching variant carries product/API URL, product and variant IDs/titles, vendor label, published-date validity, source SKU/barcode, matched/conflicting fields, raw price and compare-at price, normalized amounts, discount percentage, currency and currency-source URL, purchasable and requiresSellingPlan.
Amounts divide Shopify's integer representation by 100, including JPY/KRW; ISO minor-digit rules must not be substituted. Currency is read separately from anonymous same-host/locale cart.js. Cookies and custom market/currency query parameters are not supported, so evidence describes this anonymous server-side presentment context. Taxes, shipping, checkout, customer-specific discounts and selling-plan allocations are not evaluated. A positive compare-at spread is the published display discount, not proof of historical selling price. Null means missing or unknown.
purchasable is the published variant available flag. It is not an exact stock quantity, purchase/delivery guarantee, tested checkout, or legal MAP verdict. The Actor makes no requests that test inventory by adding quantities to a cart.
OUTPUT contains diagnostics, response SHA-256 hashes and observation times, exact normalized before/after changes, and a reusable previousSnapshot. Pass that snapshot explicitly on the next run with exactly the same catalog and URLs. There is no global or cross-user snapshot state. Input is limited to 1.5 MB, snapshots to 1 MB and strict known fields. Caller snapshots are structurally checked but are caller-provided evidence, not signed attestations.
Only complete scans return a reusable snapshot or changes. Source failures, unknown currency, exhausted limits, malformed responses, possible variant truncation, or incomplete dataset delivery suppress all comparison. A product HTTP 404 is a failed source read, not a removal. A matched candidate becoming absent from a complete response is a change in observed evidence, never a dealer-wide delisting assertion. Observed timestamps and response hashes are outside comparisons.
Coverage and limits
Shopify Product API returns at most 250 variants. A response containing 250 variants is conservatively marked possibly truncated. The single-product endpoint does not paginate; the Actor does not invent pagination or use undocumented bulk listings. Maximum 100 exact candidates per row; reaching a larger candidate set makes the run incomplete. Catalog rows are still emitted as current incomplete evidence when possible, with change.type: "not_compared".
| Limit | Default | Allowed maximum |
|---|---|---|
| Dealer hosts | explicit | 10 |
| Product URLs | explicit | 50 |
| Host/locale contexts | derived | 20 |
| Catalog items | explicit | 100 |
| Result rows | 100 | 500 |
| HTTP attempts, including retries | 30 | 150 |
| Retries per request | 2 | 3 |
| Scan seconds | 90 | 300 |
| Bytes per response | 2,000,000 | 5,000,000 |
| Aggregate response bytes | 20,000,000 | fixed |
| Event budget USD | 0.25 | 20 |
Requests run serially. HTTP 429 and selected transient 5xx responses retry within the request/time bounds, honoring Retry-After. Access denials and redirects are never bypassed. All DNS answers must be public unicast addresses; the selected address is pinned for the TLS connection, preventing a second DNS lookup from rebinding to a private address. IPv4, IPv6, mapped addresses, reserved/transition ranges, host syntax and redirects are checked. No proxy configuration or browser is used. Per-response streams are destroyed on overflow; an arriving network chunk can exceed the byte threshold before destruction, but no subsequent request starts after the aggregate threshold.
Approved listing rates
The user-approved listing rates are $0.005 automatic apify-actor-start per started 1 GB memory unit plus $0.001 per reseller-evidence dataset row. These rates are configured for this listing. They are not an earnings forecast. Each catalog/dealer-context row counts once, whether matched, ambiguous, conflicting, unmatched or incomplete. Candidate variants inside a row are not charged separately. OUTPUT diagnostics do not trigger events. Example: 25 delivered rows at 256 MB would be $0.030 in event charges in customer event charges; platform usage is included in the configured pay-per-event pricing.
On pay-per-event runs the entrypoint reads actual configured event prices and existing counts, reserves automatic starts, checks remaining capacity before source work and each push, and refuses a positive synthetic dataset-item price or an unexpected paid event. It never manually charges apify-actor-start. Outside pay-per-event mode maxBudgetUsd uses an estimate based on the approved rates only; compute/storage costs are outside that input cap. An automatic platform start can occur before input processing and cannot be undone by a zero input budget. Set platform max total charge appropriately as well.
Hosted verification — 2026-10-11 UTC
Apify build 0.0.1 succeeded using the supplied Node 22 Dockerfile. Two owner-account runs at 256 MB and a 180-second timeout completed against the public Shopify Hardware example: two HTTP 200 requests, one exact-match dataset row, complete delivery, and a reusable snapshot. The second run reported unchanged using the first run's snapshot. Both used a $0.006 event cap. Runtime confirmed pay-per-event mode with the configured $0.005 automatic start and $0.001 custom evaluation price; the code verifies one custom event-count increase per delivered row. The owner's Console reported usage costs rounded to $0.000 for each run. This is not a customer invoice test. Peak memory was 58.9 MB across these small tests, not a maximum-load guarantee.
The static diagnostics.platform sentence in this source still describes the builder's earlier local-only verification. For actual hosted execution, use the dated record above and current completeScan, deliveryComplete, billingMode, source-response and comparison fields. Failed/denied-source and budget boundary behavior also has offline fixture coverage; no source-denial bypass was used.
This Actor is unofficial and is not affiliated with Shopify.
Sources
- Official Shopify Product API
- Official Ajax requirements and limitations
- Official Cart API
- Official variant price representation, including JPY/KRW
Read NOTICE.md for attribution and source restrictions.