Shopify Variant Image Association Audit avatar

Shopify Variant Image Association Audit

Pricing

from $20.00 / 1,000 snapshot audits

Go to Apify Store
Shopify Variant Image Association Audit

Shopify Variant Image Association Audit

Read-only audit of Shopify catalog snapshots: broken variant-image links, duplicate IDs and SKUs, missing alt text, and drift between two exports. Returns SKU-linked corrections.

Pricing

from $20.00 / 1,000 snapshot audits

Rating

0.0

(0)

Developer

Practical AI Lab

Practical AI Lab

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Security

Limited permissions

Share

A read-only audit for Shopify catalog snapshots. It finds broken product-variant-image links, duplicate identifiers, missing or weak image alt text, and drift between two exports, then returns one row per problem with the affected SKU and a suggested correction. It never edits a storefront.

Who it is for

Teams that migrate, merge, or bulk-edit Shopify catalogs and need to know what broke: store operators, catalog managers, and agencies reviewing a client export they are authorized to audit.

What it checks

CategoryIssue types
Variant-image linksVARIANT_IMAGE_NOT_IN_PRODUCT, VARIANT_IMAGE_FROM_OTHER_PRODUCT, IMAGE_VARIANT_LIST_MISMATCH, IMAGE_REFERENCES_UNKNOWN_VARIANT, VARIANT_PRODUCT_ID_MISMATCH, IMAGE_PRODUCT_ID_MISMATCH, optional VARIANT_WITHOUT_IMAGE
IdentifiersDUPLICATE_PRODUCT_ID, DUPLICATE_HANDLE, DUPLICATE_VARIANT_ID, DUPLICATE_SKU (case-insensitive), DUPLICATE_BARCODE, DUPLICATE_IMAGE_ID, MISSING_SKU
Alt textMISSING_ALT_TEXT, ALT_TEXT_TOO_LONG, ALT_TEXT_LOOKS_LIKE_FILENAME
Drift (needs a baseline)DRIFT_SKU_CHANGED, DRIFT_VARIANT_IMAGE_CHANGED, DRIFT_VARIANT_IMAGE_REMOVED, DRIFT_VARIANT_IMAGE_ADDED, DRIFT_VARIANT_REMOVED, DRIFT_VARIANT_ADDED, DRIFT_ALT_TEXT_REMOVED, DRIFT_ALT_TEXT_CHANGED

Input

Provide the current snapshot either as a pasted products array (Shopify products.json shape) or as a public feed URL. Do not provide both for the same snapshot. The input form is prefilled with a small sample (current and baseline) that runs without any network access; clear those arrays before using a URL.

Copyable sample:

{
"currentProducts": [
{
"id": 1001, "title": "Trail Jacket", "handle": "trail-jacket",
"variants": [
{"id": 2001, "product_id": 1001, "title": "Blue / S", "sku": "TJ-BLU-S", "image_id": 3001},
{"id": 2002, "product_id": 1001, "title": "Blue / M", "sku": "TJ-BLU-S", "image_id": 3999}
],
"images": [
{"id": 3001, "product_id": 1001, "src": "https://cdn.example.com/trail-jacket-blue.jpg", "alt": "", "variant_ids": [2001]}
]
}
],
"checkAltText": true
}

Main options: currentProducts / currentSnapshotUrl, baselineProducts / baselineSnapshotUrl, checkAltText, maxAltLength, flagVariantsWithoutImage, maxProducts, maxPages, requestDelaySecs, maxFindings.

URL snapshots

  • Only https://<host>/products.json and https://<host>/collections/<handle>/products.json are accepted. Query strings are discarded.
  • IP addresses, local or internal host names, credentials in URLs, and non-default ports are rejected. Hosts resolving to non-public addresses are rejected.
  • robots.txt is read first. If it disallows the feed or cannot be read (other than 404), the run stops without fetching the feed.
  • Redirects are not followed. Requests are paged (250 products per page), delayed, and bounded by maxPages, maxProducts, and a per-response size limit.
  • Audit only stores you own or are authorized to review.

Output

  • Dataset: one row per finding, sorted by severity (high, medium, low). Key fields: issueType, sku, productHandle, variantId, imageId, detail, suggestedAction, suggestedField, currentValue, suggestedValue, confidence. storefrontEdited is always false.
  • Key-value store SUMMARY: snapshot sizes, counts by severity, category and issue type, SKUs with the most findings, whether the findings cap truncated results, and the caveats below.

confidence: "high" is used only when exactly one image in the product explicitly lists the variant. Everything else is review.

Pricing

The code defines a single pay-per-event name, snapshot-audit, charged once after an audit has finished and its results are stored. Runs that fail (invalid input, unsafe URL, robots refusal, fetch error, empty snapshot) are not charged. No price is configured in this project.

Limitations and sample-size caveats

  • The audit only sees what the snapshot contains. Public products.json feeds list published products only and may omit fields that a full admin export has, so a clean public result does not prove the whole catalog is clean.
  • Inline arrays larger than maxProducts are truncated; URL feeds stop at maxPages or maxProducts. The run summary flags truncation.
  • Image drift matches variants by id and images by file name. Re-uploaded images with new file names show up as changes.
  • A variant whose image has an empty variant_ids list is not flagged as a list mismatch, because partial exports often omit that list.
  • Suggested alt text is a draft assembled from product and variant titles. It needs human review and is not a description of the picture.
  • Small snapshots, such as a handful of products, say little about catalog-wide health. Percentages from them should not be extrapolated.
  • DNS is checked before fetching, but the HTTP client resolves the host again; a hostile DNS server could in theory change its answer between the two steps.
  • No images are downloaded or analyzed; broken image URLs are not detected.
  • Shopify's JSON shape can change. Unknown or malformed entries are skipped rather than repaired.

Local tests

Tests run offline with the standard library:

python -m unittest discover