Retail assortment gap analysis
Compare defined category samples or complete collections and identify evidence-backed
assortment gaps. Keep a product absent from the collected sample distinct from one
confirmed absent from a fully enumerated catalog.
Setup and API contract
Set CRAWLORA_API_KEY to your key from crawlora.net.
Run the bundled scripts/crawlora.sh from this skill directory or by absolute
path. It sends x-api-key to https://api.crawlora.net/api/v1; keep the key in
the environment. Read reference/endpoints.md for the
selected endpoints, required parameters, limits, and response behavior.
Check the application code as well as HTTP status; successful payloads are
inside data. Stop on 401/403, back off on 429, and retry a transient
5xx once. A failed or partial fetch is not an empty market or catalog.
Bound requests to the user's scope and credit budget. For repeated collection,
save the query, source IDs, pagination progress, and retrieval timestamps with
the results so interrupted work can resume; do not create monitors implicitly.
Define and collect the comparison
- Agree on stores, target market, category boundaries, price-band edges, and
counting unit: parent products or sellable variants. Fix store, country,
language, currency, and retrieval window before collecting data. Use the user's
own assortment when supplied, alongside public competitor records.
- For Shopify, resolve a storefront with
/shopify/store, discover handles via
/shopify/collections, and enumerate /shopify/collections/{handle}/products.
/shopify/products provides the broader storefront catalog. Keep url fixed
across pages and detail calls. Use returned product handles for detail.
Classic transport does not support server-side sort/facets; do not pass
sortBy unless transport_mode is ssr_embedded and the reference permits it.
- For Target, discover
/target/categories, browse /target/category-products,
and retain returned dynamic filter option IDs. Preserve the same store_id
when supplied by the user for browsing and /target/product?tcin=... detail.
This skill has no Target store-discovery tool: report the default store context
if a verified ID is unavailable, rather than inventing a local store match.
- For IKEA,
/ikea/search finds seed products; fetch detail to take category keys from
its category paths for /ikea/category pagination and item numbers for detail.
Keep country and language fixed. Keyword search is a candidate sample,
not an exhaustive assortment even when its returned page is full.
- Record pages/offsets, filters, declared totals, unique IDs, and stopping reason.
Follow each endpoint's pagination limits; Shopify supports up to 250 per page,
Target category browsing caps at page 50, IKEA category uses offset/size.
A request budget or endpoint cap means partial coverage. Deduplicate overlapping
collections and stop if pages repeat rather than assuming new coverage.
scripts/crawlora.sh /ikea/search q=desk country=us language=en size=10
scripts/crawlora.sh /target/categories
# For a user-selected Shopify store, use its URL unchanged through discovery:
# scripts/crawlora.sh /shopify/collections url="$STOREFRONT_URL" limit=50 page=1
Normalize and identify gaps
- Build a shared category/attribute mapping while preserving each store's original
taxonomy. Store-specific category IDs and labels are not cross-store keys.
- Match identical products using a returned GTIN or verified brand/model/variant
combination. Treat retailer-local IDs as local. A similar title is only a
candidate match; private-label alternatives belong in an attribute comparison.
- Count parent products once for breadth; count sizes/colors only in the variant
view. A sold-out variant is an availability gap, not a missing catalog product.
- Use consistent currency, tax context, pack quantity, dimensions, and sale versus
regular price basis. Do not compare a multipack with a single item by sticker
price alone. Avoid counting a product's minimum variant price as every variant's
price. Keep missing brand, attributes, or prices in an unknown bucket.
- Calculate category/brand/price-band shares with explicit denominators and unknown
counts. For incomplete coverage, label differences as observed sample gaps.
A niche carried by a competitor is not proof of sales, demand, or profitability.
Deliverable
Return a coverage ledger, comparable assortment matrix, and prioritized gap list.
For each proposed gap show category/attribute, stores observed, product and variant
counts, price basis, example source URLs/IDs, collection time, confidence, and what
would validate demand. Explain whether evidence supports absence, out-of-stock,
unknown coverage, or a taxonomy mismatch. Do not turn a snapshot into a trend;
changes require comparable saved snapshots and the same collection scope.
1---2name: retail-assortment-gap-analysis3description: Compare competing retail assortments through Crawlora catalogs. Use to find observed gaps in categories, brands, product attributes, variants, and price bands, with explicit catalog coverage and product-matching evidence.4---56# Retail assortment gap analysis78Compare defined category samples or complete collections and identify evidence-backed9assortment gaps. Keep a product absent from the collected sample distinct from one10confirmed absent from a fully enumerated catalog.1112## Setup and API contract1314Set `CRAWLORA_API_KEY` to your key from [crawlora.net](https://crawlora.net).15Run the bundled `scripts/crawlora.sh` from this skill directory or by absolute16path. It sends `x-api-key` to `https://api.crawlora.net/api/v1`; keep the key in17the environment. Read [reference/endpoints.md](reference/endpoints.md) for the18selected endpoints, required parameters, limits, and response behavior.19Check the application `code` as well as HTTP status; successful payloads are20inside `data`. Stop on `401`/`403`, back off on `429`, and retry a transient21`5xx` once. A failed or partial fetch is not an empty market or catalog.22Bound requests to the user's scope and credit budget. For repeated collection,23save the query, source IDs, pagination progress, and retrieval timestamps with24the results so interrupted work can resume; do not create monitors implicitly.2526## Define and collect the comparison27281. Agree on stores, target market, category boundaries, price-band edges, and29 counting unit: parent products or sellable variants. Fix store, country,30 language, currency, and retrieval window before collecting data. Use the user's31 own assortment when supplied, alongside public competitor records.322. For Shopify, resolve a storefront with `/shopify/store`, discover handles via33 `/shopify/collections`, and enumerate `/shopify/collections/{handle}/products`.34 `/shopify/products` provides the broader storefront catalog. Keep `url` fixed35 across pages and detail calls. Use returned product handles for detail.36 Classic transport does not support server-side sort/facets; do not pass37 `sortBy` unless `transport_mode` is `ssr_embedded` and the reference permits it.383. For Target, discover `/target/categories`, browse `/target/category-products`,39 and retain returned dynamic filter option IDs. Preserve the same `store_id`40 when supplied by the user for browsing and `/target/product?tcin=...` detail.41 This skill has no Target store-discovery tool: report the default store context42 if a verified ID is unavailable, rather than inventing a local store match.434. For IKEA, `/ikea/search` finds seed products; fetch detail to take category keys from44 its category paths for `/ikea/category` pagination and item numbers for detail.45 Keep `country` and `language` fixed. Keyword search is a candidate sample,46 not an exhaustive assortment even when its returned page is full.475. Record pages/offsets, filters, declared totals, unique IDs, and stopping reason.48 Follow each endpoint's pagination limits; Shopify supports up to 250 per page,49 Target category browsing caps at page 50, IKEA category uses offset/size.50 A request budget or endpoint cap means partial coverage. Deduplicate overlapping51 collections and stop if pages repeat rather than assuming new coverage.5253```sh54scripts/crawlora.sh /ikea/search q=desk country=us language=en size=1055scripts/crawlora.sh /target/categories56# For a user-selected Shopify store, use its URL unchanged through discovery:57# scripts/crawlora.sh /shopify/collections url="$STOREFRONT_URL" limit=50 page=158```5960## Normalize and identify gaps6162- Build a shared category/attribute mapping while preserving each store's original63 taxonomy. Store-specific category IDs and labels are not cross-store keys.64- Match identical products using a returned GTIN or verified brand/model/variant65 combination. Treat retailer-local IDs as local. A similar title is only a66 candidate match; private-label alternatives belong in an attribute comparison.67- Count parent products once for breadth; count sizes/colors only in the variant68 view. A sold-out variant is an availability gap, not a missing catalog product.69- Use consistent currency, tax context, pack quantity, dimensions, and sale versus70 regular price basis. Do not compare a multipack with a single item by sticker71 price alone. Avoid counting a product's minimum variant price as every variant's72 price. Keep missing brand, attributes, or prices in an unknown bucket.73- Calculate category/brand/price-band shares with explicit denominators and unknown74 counts. For incomplete coverage, label differences as observed sample gaps.75 A niche carried by a competitor is not proof of sales, demand, or profitability.7677## Deliverable7879Return a coverage ledger, comparable assortment matrix, and prioritized gap list.80For each proposed gap show category/attribute, stores observed, product and variant81counts, price basis, example source URLs/IDs, collection time, confidence, and what82would validate demand. Explain whether evidence supports absence, out-of-stock,83unknown coverage, or a taxonomy mismatch. Do not turn a snapshot into a trend;84changes require comparable saved snapshots and the same collection scope.