seekoutside.com
Audited 5 days ago· bigcommerce
Agent-readiness across all five AI commerce surfaces.
Surfaces — click to filter
24 failing · 14 not checked · 38 shown
14 checks couldn't run on this store — each is listed below with the reason. Your score reflects only what we could verify.
Set price as a number and priceCurrency as an ISO 4217 code
Why this matters: Agents need a price with a currency to show and compare your product.
Findings (11)
Parsed Offer price and priceCurrency on Product JSON-LD across 20 sampled product pages (0 valid, 0%).
How: Parse Offer price (or AggregateOffer lowPrice) as a parseable numeric price ≥ 0; require priceCurrency to match /^[A-Z]{3}$/i.
Coverage
0/20 · 0%
- Offer is missing a numeric price or valid priceCurrencyCRITICAL× 10
Render
priceas a number andpriceCurrencyas a 3-letter ISO 4217 code.Affected (10)
- /large-titanium-wood-stove-stovepipeno Offer on Product node
- /12-person-tipi-preno Offer on Product node
- /extra-large-titanium-wood-stove-stovepipeno Offer on Product node
- /medium-titanium-wood-stove-stovepipeno Offer on Product node
- /8-person-tipi-preno Offer on Product node
- /rain-snow-cap-not-compatible-with-uturnno Offer on Product node
- /6-person-tipi-preno Offer on Product node
- /6-person-liner-halfno Offer on Product node
- /8-person-liner-halfno Offer on Product node
- /12-person-liner-halfmissing/invalid `price`, missing/invalid `priceCurrency`
…and 1 more
Use a canonical Schema.org availability IRI on every Offer
Why this matters: Agents suppress out-of-stock or ambiguous items; a valid availability URL keeps you eligible.
Findings (5)
Checked Offer availability on 5 sampled product pages with an Offer (0 use a canonical Schema.org URL, 0%).
How: On each Offer, accept availability only if it matches one of the canonical Schema.org ItemAvailability IRIs (http or https, trailing slash optional).
Coverage
0/5 · 0%
- Offer
availabilityis missing or not a canonical Schema.org URLHIGH× 5Use https://schema.org/InStock (or OutOfStock / PreOrder / BackOrder).
Affected (5)
- /12-person-liner-halfvalue: InStock
- /utility-tray-mediumvalue: InStock
- /12-person-tipi-stove-liner-bundlevalue: InStock
- /8-person-half-nest-inner-tentvalue: InStock
- /atwood-3-32-x-50ft-reflective-cordagevalue: InStock
Add a resolvable image URL to every Product node
Why this matters: Agents show your product image in shopping cards; a missing image weakens or drops the listing.
Findings (11)
Read the image field on Product JSON-LD across 20 sampled product pages (5 resolve at least one URL, 25%).
How: Resolve image on each Product node into a list of URL strings (string, array, or ImageObject.url/contentUrl); require at least one non-empty URL.
Coverage
5/20 · 25%
- Product JSON-LD has no resolvable
imageURLHIGH× 10Set
imageto an absolute URL or array of URLs.
…and 1 more
Add an offers object to every Product node
Why this matters: Without an Offer, agents can't see that the product is for sale.
Findings (11)
Looked for an offers (or AggregateOffer) block on Product JSON-LD across 20 sampled product pages (5 carry one, 25%).
How: On each Product node, require a resolvable Offer (or first Offer inside an AggregateOffer) via findOffer.
Coverage
5/20 · 25%
- Product JSON-LD has no resolvable
offersHIGH× 10Add an
offersobject with at minimumprice,priceCurrency, andavailability.
…and 1 more
Emit a single Product JSON-LD node per PDP
Why this matters: Duplicate Product nodes on a single PDP cause Google's merchant scraper to drop the listing or pick the wrong variant.
Findings (16)
Sampled 20 PDP(s); 16 carried multiple Product JSON-LD nodes.
How: For each sampled PDP, count JSON-LD nodes whose @type is Product or whose @type array contains Product. Each PDP must expose at most one.
Coverage
4/20 · 20%
- PDP exposes 2 Product JSON-LD nodesHIGH× 16
Emit exactly one Product JSON-LD block per PDP; model variants via
hasVariantor multiple Offer children.Affected (16)
- /large-titanium-wood-stove-stovepipe2 Product nodes detected
- /12-person-tipi-pre2 Product nodes detected
- /extra-large-titanium-wood-stove-stovepipe2 Product nodes detected
- /medium-titanium-wood-stove-stovepipe2 Product nodes detected
- /8-person-tipi-pre2 Product nodes detected
- /rain-snow-cap-not-compatible-with-uturn2 Product nodes detected
- /6-person-tipi-pre2 Product nodes detected
- /6-person-liner-half2 Product nodes detected
- /8-person-liner-half2 Product nodes detected
- /utility-tray-large2 Product nodes detected
- …and 6 more
…and 6 more
Surface brand attribution on every PDP
Why this matters: Brand on every product is a primary agent filter and a required feed field.
Findings (11)
Checked 20 sampled product pages for brand attribution via Product JSON-LD or visible HTML signals (1 attributed, 5%).
How: On each PDP, accept brand attribution from either (a) extractBrand on the first Product JSON-LD node OR (b) an HTML brand signal (OG product:brand, brand meta, og:brand, Microdata itemprop="brand").
Coverage
1/20 · 5%
- No brand attribution on this PDP (neither JSON-LD
brandnor OG/Microdata)HIGH× 10Add
brandto the Product JSON-LD or a<meta property="product:brand">tag.
…and 1 more
Populate gtin on every branded Product node
Why this matters: GTINs let agents match your product to the same item elsewhere; without them you lose cross-catalog matching.
Findings (11)
Checked 20 sampled product pages for a GTIN in the Product JSON-LD (0 carry a valid GTIN, 0%).
How: Extract gtin / gtin8 / gtin12 / gtin13 / gtin14 from the first Product JSON-LD node on each PDP; validate digit length.
Coverage
0/20 · 0%
- No valid GTIN on this product pageHIGH× 10
Populate gtin/gtin8/gtin12/gtin13/gtin14 with the manufacturer's barcode.
…and 1 more
Emit hasMerchantReturnPolicy on Product or Offer JSON-LD
Why this matters: Without the entry-point return-policy node, agents can't render or quote your return terms — they fall back to platform defaults or skip your store.
Findings (11)
Inspected hasMerchantReturnPolicy on Product/Offer JSON-LD across 20 sampled product pages (5 present, 25%).
How: On each PDP, locate the Product JSON-LD node and check for a hasMerchantReturnPolicy object/array at Product level OR Offer level. Pass band ≥ 85% coverage, partial ≥ 50%.
Coverage
5/20 · 25%
- Product JSON-LD missing
hasMerchantReturnPolicyHIGH× 10Add a MerchantReturnPolicy node to Product or Offer with category + applicableCountry (or merchantReturnLink).
…and 1 more
Emit shippingDetails (OfferShippingDetails) on Offer JSON-LD
Why this matters: Without shippingDetails, AI agents fall back to vague defaults — they can't quote your rates, destinations, or delivery windows in shopping cards.
Findings (11)
Inspected shippingDetails on Product/Offer JSON-LD across 20 sampled PDPs (5 present, 25%).
How: On each PDP, locate the Product JSON-LD node and check for shippingDetails (single object or array) at Product or Offer level. Pass band ≥ 85% coverage.
Coverage
5/20 · 25%
- Offer JSON-LD missing
shippingDetailsHIGH× 10Add OfferShippingDetails with shippingRate, shippingDestination, and deliveryTime.
…and 1 more
Publish /.well-known/ucp with at minimum a version field
Why this matters: Without `/.well-known/ucp`, Google's AI Mode can't identify your storefront as a UCP-conformant merchant.
Findings (1)
Inspected /.well-known/ucp for a parseable JSON document with a top-level version string.
How: Confirm ctx.wellKnownUcp is non-null and carries a non-empty version string (the only universally-required UCP profile field).
- /.well-known/ucp is not reachable or not parseable as JSONHIGH
Serve a JSON document at /.well-known/ucp with a top-level
versionstring (e.g., "2026-04-08").
Add every required top-level key to the UCP profile
Why this matters: A profile missing one of the four required keys is treated as non-conformant — agent runtimes fall back to default behaviour and may skip the merchant.
Findings (1)
Wanted to inspect UCP root keys, but no profile was found.
How: Read the profile root (or top-level ucp wrapper) and verify the presence of version, services, capabilities, and signing_keys keys.
- No /.well-known/ucp profile presentHIGH
Publish /.well-known/ucp first (see ucp-profile-present).
Declare a shopping service entry with a recognised transport and an HTTPS endpoint
Why this matters: Without a valid shopping service entry, agents can recognise you as a UCP merchant but have no way to fetch your catalog.
Findings (1)
Wanted to walk the UCP profile's services[] for a valid shopping entry, but no profile was found.
How: List every services[] entry whose namespace is shopping (or contains shopping) and require at least one with transport ∈ {rest,mcp,a2a,embedded} AND a syntactically valid https:// endpoint.
- No /.well-known/ucp profile presentHIGH
Publish /.well-known/ucp first (see ucp-profile-present), then declare the shopping service.
Make every signing_keys[] entry a JWK with kty + kty-specific params
Why this matters: Malformed JWK entries are rejected silently by agents — signed payloads cannot be verified and the merchant loses trust signal.
Findings (1)
Wanted to validate signing_keys[], but no UCP profile was found.
How: Walk signing_keys[] and validate each entry per RFC 7517 §4.1 (kty required) + RFC 7518 §6 (kty-specific required parameters). kid is OPTIONAL per RFC 7517 §4.5 and not enforced here.
- No /.well-known/ucp profile presentHIGH
Publish a product feed or a crawlable product sitemap
Why this matters: Agents build their catalog from a feed or by crawling product pages; if neither yields products, your store is invisible.
Findings (1)
Confirmed your products are discoverable by crawling product pages and reading their structured data. Verified 20 product pages of 40 sampled, but no declared feed.
How: Read the product-discovery cascade result from ctx.discovery. Score by discovery method (feed / platform_api / sitemap_typed → pass when verifiedProductCount ≥ MIN_CONFIDENT_PRODUCTS; content_verified → partial; none or under-threshold → fail).
- Products are crawlable, but no declared product feedHIGH
/method=content_verified, verified=20
Publish a Google Merchant XML or ACP product feed at a stable URL and declare it in /.well-known/ucp and /llms.txt; crawl-only discovery is fragile.
Skipped — No UCP profile present; Cache-Control policy is not evaluable.
Context: If your UCP profile says `no-cache`, agent runtimes re-fetch on every interaction — brittle at scale and prone to rate-limit failures.
Why this was skipped
No UCP profile present; Cache-Control policy is not evaluable.
How: Parse the Cache-Control header on the /.well-known/ucp response; require public, max-age ≥ 60, and no no-store/no-cache/private.
Skipped — No UCP profile present; Content-Type is not evaluable.
Context: Agent runtimes that gate parsing on Content-Type will skip your profile if it's served as HTML or plain text.
Why this was skipped
No UCP profile present; Content-Type is not evaluable.
How: Check that the Content-Type header on /.well-known/ucp starts with application/json (optionally with a charset parameter).
Skipped — No UCP profile reachable; public-fetch evaluation deferred to ucp-profile-present.
Context: Agents fetch `/.well-known/ucp` without credentials — a 401 or 403 means they never see the profile.
Why this was skipped
No UCP profile reachable; public-fetch evaluation deferred to ucp-profile-present.
How: Confirm an unauthenticated GET to /.well-known/ucp returns a 2xx status.
Skipped — No UCP profile present; redirect behaviour is not evaluable.
Context: Lightweight agent clients fetch `/.well-known/ucp` without following redirects — a 301/302 means they never see your profile.
Why this was skipped
No UCP profile present; redirect behaviour is not evaluable.
How: Inspect the final HTTP status of GET /.well-known/ucp and whether any 3xx redirect was followed to reach it.
Skipped — No UCP profile present.
Context: A service declared with the right transport but missing endpoint/schema is unreachable — agents can't negotiate or connect.
Why this was skipped
No UCP profile present.
How: For each services[] entry with a recognised transport, require the transport-conditional fields: rest/mcp → endpoint+schema; a2a → endpoint; embedded → schema.
Skipped — No UCP profile present.
Context: An unrecognised transport leaves agents with no handler to dispatch — your service appears absent.
Why this was skipped
No UCP profile present.
How: For each services[] entry, require transport to be one of: rest, mcp, a2a, embedded.
Populate description on every Product JSON-LD node
Why this matters: Agents quote your description to answer shopper questions; an empty description gives them nothing to work with.
Findings (11)
Read description on Product JSON-LD across 20 sampled product pages (5 non-empty after HTML strip, 25%).
How: Read description on each Product node; strip HTML tags and collapse whitespace; require length > 0.
Coverage
5/20 · 25%
- Product JSON-LD has no
description(empty after HTML strip)MEDIUM× 10Fill in the product description in your store admin; the JSON-LD template typically binds to that field.
…and 1 more
Emit brand as either a string or a typed Brand object on every Product
Why this matters: Brand on every product is a primary agent filter and a required feed field.
Findings (11)
Inspected the brand field on Product JSON-LD across 20 sampled product pages (1 valid as string or object, 5%).
How: On each Product node, accept brand if it's a non-empty trimmed string OR an object with a non-empty name. Objects with @type Brand/Organization but no name are rejected.
Coverage
1/20 · 5%
- Product
brandis missing or empty (neither a string nor an object withname)MEDIUM× 10Emit
brandas"Acme"(string) or{"@type":"Brand","name":"Acme"}(object).
…and 1 more
Populate sku on every Product JSON-LD node
Why this matters: A stable SKU lets agents track and re-identify your product across catalogs.
Findings (11)
Read the sku field on Product JSON-LD across 20 sampled product pages (5 populated, 25%).
How: On each PDP with a Product node, accept sku if it is a non-empty trimmed string or a number.
Coverage
5/20 · 25%
- Product JSON-LD has no populated
skuMEDIUM× 10Fill in the SKU field in your product admin; the JSON-LD template typically binds to that field.
…and 1 more
Add includeSubDomains to your Strict-Transport-Security header
Why this matters: Without includeSubDomains, an HTTP subdomain (staging, mail, …) can be used to attack the apex's cookies.
Findings (1)
Inspected the homepage Strict-Transport-Security header ("max-age=63072000") and the includeSubDomains directive is absent.
How: Parse the homepage Strict-Transport-Security header for the includeSubDomains directive (RFC 6797 §6.1.2).
- HSTS header is missing the includeSubDomains directiveMEDIUM
What we found
max-age=63072000What we expected
Strict-Transport-Security: max-age=31536000; includeSubDomainsAppend
; includeSubDomainsto your STS header once every subdomain you operate supports HTTPS.
Install a third-party review platform so agents see syndicated reviews on your storefront
Why this matters: Third-party review widgets feed the ratings AI agents trust when ranking merchants.
Findings (1)
Scanned the homepage and 20 sampled PDPs for 8 review-platform asset fingerprints; none matched.
How: Substring scan of homepage and sampled PDP HTML for known review-platform asset fingerprints (judge.me, yotpo, stamped.io, reviews.io, okendo, loox, trustpilot, bazaarvoice).
- No third-party review-platform integration detectedMEDIUM
none of 8 fingerprints matched across 21 sources
Install a Judge.me / Yotpo / Loox / Okendo / Stamped / Reviews.io / Trustpilot / Bazaarvoice widget on your storefront.
Skipped — No MerchantReturnPolicy node carried a `merchantReturnLink` URL, so reachability has nothing to evaluate.
Context: A broken return-link makes Option B policies invisible — agents can't render or follow the link.
Why this was skipped
No MerchantReturnPolicy node carried a merchantReturnLink URL, so reachability has nothing to evaluate.
How: Collect every unique merchantReturnLink URL across all MerchantReturnPolicy nodes; probe each once via politeFetch (failSoft). 2xx counts as reachable.
Skipped — No OfferShippingDetails node carried `shippingRate`, so the MonetaryAmount check has nothing to evaluate.
Context: An invalid rate object is silently dropped; agents can't quote your shipping cost in shopping cards.
Why this was skipped
No OfferShippingDetails node carried shippingRate, so the MonetaryAmount check has nothing to evaluate.
How: On each OfferShippingDetails node where shippingRate is set, require an object with numeric value/maxValue (typed or numeric string) and a 3-letter ISO 4217 currency.
Skipped — No UCP profile present.
Context: Capabilities missing version/spec/schema can't be matched against agent support tables — agents skip them silently.
Why this was skipped
No UCP profile present.
How: For each capabilities[] entry, require non-empty string values for version, spec, and schema.
Skipped — No UCP profile present.
Context: A spec URL on an unrelated authority signals the service was copy-pasted from stale documentation — agents can't trust the conformance claim.
Why this was skipped
No UCP profile present.
How: For each service with a spec URL, require the URL origin to be a canonical UCP authority OR the host/path to include the namespace token.
Skipped — No UCP profile present; service version formats are not evaluable.
Context: Free-form version labels like `1.0` or `latest` defeat the version-pinning agents rely on, leaving them unable to negotiate the correct spec generation.
Why this was skipped
No UCP profile present; service version formats are not evaluable.
How: For each services[] entry, require version to be a string matching /^\d{4}-\d{2}-\d{2}$/.
Upload higher-resolution product images (area ≥ 50,000 pixels)
Why this matters: Tiny product images get dropped from Google’s shopping rich-result modules and are unhelpful to AI agents quoting your product visually.
Findings (11)
Inspected <img width=… height=…> attributes on 20 sampled product pages (8 have at least one image with area ≥ 50,000 px; dimensions absent from HTML are not HEAD-probed and count as indeterminate).
How: For every sampled PDP, parse <img> tags and read explicit width and height attributes; a PDP passes when at least one image has width × height ≥ 50,000. PDPs without any explicit-dimension <img> are marked indeterminate (this check does not HEAD image URLs).
Coverage
8/20 · 40%
- No <img> on this PDP carries explicit width+height attributesLOW× 10
Server-render explicit width and height attributes so crawlers can verify image area without fetching.
Affected (10)
- /12-person-tipi-pre25 <img> tags found, none with width+height
- /rain-snow-cap-not-compatible-with-uturn7 <img> tags found, none with width+height
- /6-person-liner-half20 <img> tags found, none with width+height
- /8-person-liner-half20 <img> tags found, none with width+height
- /12-person-liner-half20 <img> tags found, none with width+height
- /utility-tray-medium11 <img> tags found, none with width+height
- /utility-tray-large11 <img> tags found, none with width+height
- /utility-tray-xl11 <img> tags found, none with width+height
- /standard-titanium-rollup-stove-pipe12 <img> tags found, none with width+height
- /stove-pipe-rings8 <img> tags found, none with width+height
…and 1 more
Add preload to your Strict-Transport-Security header and submit to hstspreload.org
Why this matters: HSTS preload-list inclusion is the strongest downgrade protection available — first-time visits are protected too.
Findings (1)
Inspected the homepage Strict-Transport-Security header ("max-age=63072000") and the preload directive is absent.
How: Parse the homepage Strict-Transport-Security header for the preload directive (hstspreload.org vendor extension to RFC 6797).
- HSTS header is missing the preload directiveLOW
What we found
max-age=63072000What we expected
Strict-Transport-Security: max-age=31536000; includeSubDomains; preloadAppend
; preloadafterincludeSubDomainsand submit your domain at https://hstspreload.org/.
Add descriptive alt text to product images (WCAG 2.x SC 1.1.1)
Why this matters: Alt text is the only text description AI agents and screen readers have for your product imagery.
Findings (11)
Parsed <img> alt attributes across 20 sampled product pages (1 have alt text on at least 80% of images).
How: Per PDP, count <img> tags via regex; a tag 'has alt text' when its alt attribute is present AND non-empty after trim. A PDP passes when it carries no <img> at all OR ≥80% of its <img> tags have non-empty alt.
Coverage
1/20 · 5%
- Most images on this product page lack alt textLOW× 10
What we expected
<img src="/img/sneaker.webp" alt="Red leather running shoe, side view" />Populate the alt attribute on each <img> with a description of what the image shows; use alt="" only for decorative images.
Affected (10)
- /large-titanium-wood-stove-stovepipe8/28 <img> tags have non-empty alt (29%)
- /12-person-tipi-pre9/25 <img> tags have non-empty alt (36%)
- /extra-large-titanium-wood-stove-stovepipe7/27 <img> tags have non-empty alt (26%)
- /medium-titanium-wood-stove-stovepipe6/24 <img> tags have non-empty alt (25%)
- /8-person-tipi-pre17/28 <img> tags have non-empty alt (61%)
- /rain-snow-cap-not-compatible-with-uturn2/7 <img> tags have non-empty alt (29%)
- /6-person-tipi-pre9/25 <img> tags have non-empty alt (36%)
- /6-person-liner-half5/20 <img> tags have non-empty alt (25%)
- /8-person-liner-half12/20 <img> tags have non-empty alt (60%)
- /12-person-liner-half5/20 <img> tags have non-empty alt (25%)
…and 1 more
Skipped — No OfferShippingDetails node carried `deliveryTime`, so the ShippingDeliveryTime check has nothing to evaluate.
Context: Without populated handling/transit times, agents can't quote a delivery window in shopping cards.
Why this was skipped
No OfferShippingDetails node carried deliveryTime, so the ShippingDeliveryTime check has nothing to evaluate.
How: On each OfferShippingDetails node where deliveryTime is set, require an object with at least one of handlingTime / transitTime populated as a QuantitativeValue.
Skipped — No UCP profile found; MCP transport validity is not evaluable.
Context: If you advertise MCP transport, agents will try to connect — broken or non-HTTPS endpoints fail silently and lose the integration.
Why this was skipped
No UCP profile found; MCP transport validity is not evaluable.
How: Filter services[] to entries where transport=mcp and validate that endpoint is an absolute https:// URL.
Enable Apple Pay through your payment processor (informational only)
Why this matters: Apple Pay is a checkout-quality signal for human shoppers — informational only, does not affect the agent-readiness score.
Findings (1)
Scanned the homepage and 20 sampled PDPs for Apple Pay markers; none matched.
How: Substring match on known Apple Pay SDK/markup signatures (ApplePaySession, apple-pay-button, /apple-developer-merchantid-domain-association) across the homepage and every sampled PDP HTML.
- No Apple Pay markers detected on the homepage or PDPsINFO
Enable Apple Pay in your payment processor's dashboard (Stripe / Adyen / Braintree). Informational only — does not affect the score.
Enable Google Pay through your payment processor (informational only)
Why this matters: Google Pay is a checkout-quality signal for human shoppers — informational only, does not affect the agent-readiness score.
Findings (1)
Scanned the homepage and 20 sampled PDPs for Google Pay markers; none matched.
How: Substring match on known Google Pay SDK/markup signatures (pay.google.com/gp/p/js/pay.js, google.payments.api, <google-pay-button) across the homepage and every sampled PDP HTML.
- No Google Pay markers detected on the homepage or PDPsINFO
Enable Google Pay in your payment processor's dashboard (Stripe / Adyen / Braintree). Informational only — does not affect the score.
Skipped — Looked for /llms.txt at the site root; the fetcher returned no file.
Context: An /llms.txt manifest points agents at your feed and key pages without them having to guess.
Why this was skipped
Looked for /llms.txt at the site root; the fetcher returned no file.
How: Check whether the fetcher reached an /llms.txt at the site root. Informational only — no failure path per llmstxt.org being a voluntary community convention.