# Agentic Shopping Readiness Checklist > Can AI shopping agents find, parse, and transact with my store at all? A self-assessment of whether AI shopping agents can discover, read, and transact with your store: the eligibility layer, linking the validator that machine-checks each item. _Self-assessment, not a measured audit._ ## Bot access & crawlability Whether AI crawlers and agent fetchers can reach your pages at all. ### Allow the AI search and citation crawlers in robots.txt (OAI-SearchBot, Claude-SearchBot, PerplexityBot). - **Evidence:** spec-fact, [Overview of OpenAI Crawlers](https://developers.openai.com/api/docs/bots) (2026-07-08) - **Why:** These crawlers build the search and citation indexes that surface and link your pages; each honors robots.txt, so a Disallow removes you from that engine's answers. OpenAI states that disallowing OAI-SearchBot means you will not be shown in ChatGPT search answers. - **How to check:** Read your live robots.txt; confirm no `Disallow: /` under these agents. - Priority 3/3 · Effort S · Machine-checkable - **Verify with:** [Rankly UCP/ACP validator](https://tryrankly.com/ucp-validator) - **Learn more:** https://agentmint.net/ai-crawlers-robots-llms-txt/ **What good looks like:** A store's robots.txt has a dedicated block for each named crawler (OAI-SearchBot, Claude-SearchBot, PerplexityBot) with no Disallow line under it, not just a permissive wildcard rule the store owner assumes covers them too. Common mistakes: - Assuming a broad User-agent: * Allow: / rule covers these bots the same way it covers everything else, with no dedicated named-bot block at all. - Adding the bot names to a wildcard block meant for training crawlers, blocking search access by accident. Steps: 1. Fetch your live robots.txt in a private browser tab and read it top to bottom. 2. Search for each bot's exact user-agent string; confirm a dedicated block exists for it with no Disallow line under it. 3. Re-check after any SEO plugin update or CDN change, since both can regenerate robots.txt. **For your developer:** Per RFC 9309, the most specific User-agent record wins, not file order, so a named OAI-SearchBot record overrides a wildcard Disallow for that bot alone. The real risk is a missing named record, not block position. - **WooCommerce:** A static robots.txt in the site root always overrides Yoast's or RankMath's generated one. If plugin edits don't seem to take effect, remove any leftover static file. ``` User-agent: OAI-SearchBot Allow: / User-agent: Claude-SearchBot Allow: / User-agent: PerplexityBot Allow: / ``` ### Set the AI-training tokens (GPTBot, Google-Extended) as a deliberate, documented decision, separate from search access. - **Evidence:** spec-fact, [Google's common crawlers](https://developers.google.com/crawling/docs/crawlers-fetchers/google-common-crawlers) (2026-07-08) - **Why:** GPTBot governs model training; Google-Extended is a robots.txt control token for Gemini/Vertex training and grounding that does not affect Google Search ranking or inclusion. Blocking training does not block search crawlers. Decide each on its own merits, separately from search access. - **How to check:** Check robots.txt tokens per bot; confirm you haven't conflated training and search blocks. - Priority 2/3 · Effort S - **Learn more:** https://agentmint.net/ai-crawlers-robots-llms-txt/ **What good looks like:** A store's robots.txt has separate, clearly labeled blocks for GPTBot and Google-Extended, and a code comment or internal note recording that the training-access decision was made on purpose, distinct from the search-crawler rules above it. Common mistakes: - Copying a generic 'block all AI bots' robots.txt snippet from a blog post that lumps GPTBot in with OAI-SearchBot, accidentally losing search visibility too. - Never deciding at all, leaving the default (allowed) as the policy by omission instead of a considered choice. Steps: 1. List every AI-training token you know about (GPTBot, Google-Extended) separately from search tokens. 2. For each, decide allow or block based on your own content-licensing stance, not a copied template. 3. Write the decision down (even a one-line comment above the robots.txt block) so the next person doesn't second-guess it. **For your developer:** Google-Extended only gates Gemini/Vertex training and grounding use of your content; Search Console indexing and ranking are unaffected by it, so don't treat a Google-Extended Disallow as a search opt-out. ### Don't rely on robots.txt to control the user-initiated fetchers (ChatGPT-User, Perplexity-User). - **Evidence:** spec-fact, [Overview of OpenAI Crawlers](https://developers.openai.com/api/docs/bots) (2026-07-08) - **Why:** These fire when a human asks the assistant to read a URL. OpenAI states robots.txt may not apply to ChatGPT-User, and Perplexity states Perplexity-User generally ignores it (Anthropic's Claude-User does honor it). To gate them, use auth or a WAF, not robots.txt. - **How to check:** Confirm any intended block of these is enforced at WAF or auth, not just robots.txt. - Priority 2/3 · Effort S - **Learn more:** https://agentmint.net/ai-crawlers-robots-llms-txt/ **What good looks like:** A store that wants to keep certain pages away from on-demand fetchers protects them with a login wall or a WAF rule keyed to the fetcher's user-agent and IP range, rather than adding a Disallow line to robots.txt and assuming it works. Common mistakes: - Assuming a Disallow rule for ChatGPT-User or Perplexity-User in robots.txt actually stops the fetch, when the vendor documents that it may not honor it. - Blocking these fetchers entirely by mistake, which also blocks the case where a real shopper pasted your URL into the assistant to get a summary. Steps: 1. Identify any page you genuinely need to keep away from on-demand fetchers (checkout, account pages). 2. Gate those with authentication or a WAF rule matched on the fetcher's published user-agent or IP, not robots.txt alone. 3. Leave product pages open to these fetchers by default, since blocking them removes a channel real shoppers use. **For your developer:** OpenAI states robots.txt may not apply to ChatGPT-User and Perplexity documents that Perplexity-User generally ignores it; Claude-User is the one user-initiated fetcher that does honor robots.txt, so treat that as the exception, not the rule. ### Verify your WAF or bot protection isn't silently blocking legitimate agent IP ranges. - **Evidence:** spec-fact, [Overview of OpenAI Crawlers](https://developers.openai.com/api/docs/bots) (2026-07-08) - **Why:** A crawler allowed in robots.txt can still be blocked by a WAF challenge or rate rule, making you invisible. Vendors publish verifiable IP and user-agent endpoints (OpenAI's gptbot.json, searchbot.json, chatgpt-user.json; Perplexity's perplexitybot.json) precisely so you can allow-list the real agents. - **How to check:** Fetch your own product URL with each published user-agent/IP; confirm a 200, not a challenge page. - Priority 3/3 · Effort M - **Learn more:** https://agentmint.net/store-not-in-chatgpt-shopping/ **What good looks like:** A store periodically fetches its own bestselling product page using each vendor's published user-agent string and IP range, confirms a plain 200 response with full content, and keeps that check in the same runbook as an uptime check. Common mistakes: - Trusting that 'robots.txt says allow' means the request actually gets through, when a WAF challenge page or bot-fight-mode rule sits in front of it. - Testing once at launch and never again, missing a later WAF rule change or a new managed-rule-set update that starts challenging these agents. Steps: 1. Get each vendor's published IP/user-agent list (OpenAI's bot JSON endpoints, Perplexity's equivalent). 2. Fetch a real product URL using each user-agent (and, where possible, from a matching IP range). 3. Confirm a 200 with full page content, not a CAPTCHA, JS challenge, or redirect. 4. Add an allow rule for confirmed agents in your WAF and re-test after any WAF or CDN change. **For your developer:** Rate-limiting and bot-fight modes match on request signature, not just user-agent, so an agent can pass a user-agent check and still get challenged by a managed rule; verify with a real fetch, not a user-agent string comparison alone. ``` curl -A "OAI-SearchBot/1.0; +https://openai.com/searchbot" \ -o /dev/null -w "%{http_code}\n" -s \ https://example.com/products/sample-item ``` ### Ensure product content renders in server HTML without requiring JavaScript. - **Evidence:** hypothesis - **Why:** We expect crawlers and agents that don't execute or fully render JavaScript to miss price, availability, and specs injected client-side, so a JS-only product page can read as empty. Server-render the commerce-critical fields (title, description, price, availability) in the initial HTML. - **How to check:** Load the PDP with JS disabled (or view page source); confirm price, availability, title, and description are present. - Priority 3/3 · Effort L · Applies to: all (SPA storefronts most at risk) - **Learn more:** https://agentmint.net/ai-crawlers-robots-llms-txt/ **What good looks like:** A shopper or crawler with JavaScript disabled still sees the product title, price, availability, and description in the page source, because the storefront renders those fields server-side before any client script runs. Common mistakes: - A single-page app renders the whole product page client-side, leaving an empty shell in the raw HTML. - Title and description render server-side, but price and availability load via a client-side call afterward, so critical fields are still missing from the source. Steps: 1. View page source, or disable JavaScript and reload the product page. 2. Confirm title, description, price, and availability all appear in that raw HTML. 3. If any field is missing, move its rendering into the server response instead of a client-side fetch. **For your developer:** Check the raw response body with curl or 'view source,' not devtools, which always shows the post-hydration DOM; a non-executing crawler only ever sees the raw response. - **Shopify:** A standard Liquid theme server-renders these fields by default; a headless Hydrogen storefront needs an explicit SSR step for the product route. - **WooCommerce:** Default WooCommerce themes render server-side already; a fully decoupled headless build carries the same risk as any other single-page app. ### Give each product one clean, stable, canonical URL. - **Evidence:** spec-fact, [Merchant listing structured data](https://developers.google.com/search/docs/appearance/structured-data/merchant-listing) (2026-07-08) - **Why:** Duplicate or parameterized URLs split ranking signals and let an agent land on a non-purchasable or stale variant. Google's merchant-listing eligibility requires the page be one where a shopper can actually purchase, so give each product one stable canonical URL that matches the feed link. - **How to check:** Check `` per PDP; confirm it resolves to the purchasable page and matches the feed link. - Priority 2/3 · Effort M · Machine-checkable - **Verify with:** [Google Rich Results Test](https://search.google.com/test/rich-results) - **Learn more:** https://agentmint.net/product-schema-for-ai-shopping/ **What good looks like:** Every product has exactly one URL in across every variant of that page, and that same URL is the one listed in the product feed. Common mistakes: - Color or size variations each get their own indexable URL instead of one canonical parent, splitting the same product across several addresses. - The canonical tag points to a URL that itself redirects or 404s, or that doesn't match the link in the feed. Steps: 1. Pick one canonical URL per product (usually the shortest, parameter-free path). 2. Check on the product page and on any filtered or tracked variant of it. 3. Confirm the canonical URL resolves directly (200, no redirect) and matches the link field in your product feed. **For your developer:** The canonical URL should be absolute and match the feed's link field exactly, including trailing slash; a canonical/feed mismatch is exactly what Merchant Center's landing-page checks flag. - **Shopify:** The same product can be reached through multiple collection URLs (/collections/x/products/y); confirm your theme canonicalizes all of them to the single /products/y path. - **WooCommerce:** Product variations (size, color) share the parent product's canonical by default in most SEO plugins; verify that a variation-specific URL, if one exists, still canonicalizes to the parent. ``` ``` ## Structured data & feeds Whether your product data is present, valid, and feed-complete for machines to read. ### Ship Product/Offer JSON-LD with an active price > 0 and priceCurrency in ISO 4217. - **Evidence:** spec-fact, [Merchant listing structured data](https://developers.google.com/search/docs/appearance/structured-data/merchant-listing) (2026-07-08) - **Why:** Merchant-listing experiences require a price greater than zero plus a valid ISO 4217 currency; without them the Offer is ineligible. This is the machine-readable layer agents trust when the page and feed disagree, so it must be present and correct. - **How to check:** Run the URL through Google's Rich Results Test or the Schema.org validator. - Priority 3/3 · Effort M · Machine-checkable - **Verify with:** [Google Rich Results Test](https://search.google.com/test/rich-results) - **Learn more:** https://agentmint.net/product-schema-for-ai-shopping/ **What good looks like:** Every product page's JSON-LD Offer shows a numeric price above zero and a three-letter priceCurrency code, matching exactly what the shopper sees on the page and at checkout. Common mistakes: - A price of '0' ships in the markup during a migration or a misconfigured sale field, silently making the Offer ineligible. - priceCurrency is hardcoded to one value across a multi-currency store, so it's wrong for every currency except the default. Steps: 1. Pull the JSON-LD from a live product page (view source or Rich Results Test). 2. Confirm price is a plain number greater than 0, and priceCurrency is the correct ISO 4217 code for what's actually charged. 3. Re-check after any pricing, sale, or multi-currency change, since these are common places the two drift apart. **For your developer:** price must be a bare number without a currency symbol or thousands separator; priceCurrency is the ISO 4217 code, not a symbol like '$', and both should read from the same source as the checkout total. - **Shopify:** Multi-currency storefronts need the JSON-LD to read the shopper's resolved currency, not the shop's base currency, or priceCurrency is wrong for other markets. - **WooCommerce:** If a store shows tax-inclusive pricing but a schema plugin defaults to tax-exclusive price, the JSON-LD and visible price disagree. ``` { "@type": "Offer", "price": "49.99", "priceCurrency": "USD", "availability": "https://schema.org/InStock" } ``` ### Populate availability in structured data and keep it truthful to the page. - **Evidence:** spec-fact, [Merchant listing structured data](https://developers.google.com/search/docs/appearance/structured-data/merchant-listing) (2026-07-08) - **Why:** availability (InStock/OutOfStock/PreOrder) is a recommended Offer property, and Google requires markup to match the page. A false in-stock value gets products disapproved and erodes agent trust, so populate it and keep it truthful to what the shopper and checkout actually see. - **How to check:** Compare the markup availability to the visible PDP state and checkout. - Priority 2/3 · Effort M · Machine-checkable - **Verify with:** [Google Rich Results Test](https://search.google.com/test/rich-results) - **Learn more:** https://agentmint.net/product-schema-for-ai-shopping/ **What good looks like:** A product that sells out shows availability=OutOfStock in JSON-LD within minutes of the same happening on the storefront and at checkout, not a day later after a batch job runs. Common mistakes: - The markup still says InStock after a product sells out because it's generated once at page-cache time and never refreshed on stock change. - Backorder or preorder items are marked InStock, overstating what's actually available today. Steps: 1. Pick a product currently out of stock (or take one out temporarily) and check its JSON-LD availability value. 2. Confirm it matches what the storefront and checkout actually show for that same product. 3. Trace how availability gets into the markup: page cache, database field, or a separate feed job, and confirm that path updates on every stock change. **For your developer:** Map your internal stock states (in stock, backorder, preorder, discontinued) to the matching schema.org values explicitly (InStock, BackOrder, PreOrder, Discontinued); don't default everything to InStock and only override on zero-stock, since backorder and preorder need their own honest value. - **WooCommerce:** Products set to 'On backorder' report a stock status separate from 'In stock'; make sure your schema output maps that to BackOrder or PreOrder, not InStock by default. ### Include product identifiers (gtin*, brand, and mpn) where they exist. - **Evidence:** spec-fact, [Product data specification](https://support.google.com/merchants/answer/7052112) (2026-07-08) - **Why:** Merchant Center requires a GTIN for products that have one (or MPN if none) and brand for new products; Google recommends gtin8/12/13/14 in Product markup. Identifiers let agents match your item to the same product across competing stores. - **How to check:** Merchant Center diagnostics flag missing or invalid identifiers; check the feed and markup. - Priority 2/3 · Effort M · Applies to: all with manufacturer identifiers · Machine-checkable - **Verify with:** [Google Merchant Center diagnostics](https://support.google.com/merchants/answer/7052112) - **Learn more:** https://agentmint.net/product-schema-for-ai-shopping/ **What good looks like:** A product with a real manufacturer identifier carries its GTIN and brand in both the JSON-LD and the feed; a private-label product states the store's own brand name instead of leaving the field blank. Common mistakes: - GTIN is left blank across the catalog after a platform migration, even though the products have real UPCs on the box. - The same GTIN gets reused across different color or size variants that are actually different retail items. Steps: 1. Check whether your products have real manufacturer identifiers (look at the packaging or the manufacturer's own listing). 2. Populate gtin8/12/13/14, brand, and mpn in both markup and feed wherever an identifier genuinely exists. 3. For private-label or made-to-order items with no manufacturer GTIN, set brand to your own store or product line name instead of leaving it empty. **For your developer:** gtin accepts 8, 12, 13, or 14-digit codes in one property; never invent a placeholder GTIN to fill the field, since a fabricated identifier can cause a false product match. - **Shopify:** Barcode is a native field; map it directly to gtin rather than guessing in a schema plugin. - **WooCommerce:** There's no native GTIN field; it comes from a custom field or a schema plugin's identifier setting, mapped consistently, not entered ad hoc. ### Run a live product feed carrying all required Merchant Center attributes. - **Evidence:** spec-fact, [Product data specification](https://support.google.com/merchants/answer/7052112) (2026-07-08) - **Why:** id, title, description, link, image_link, availability, and price are required for all products; a missing required attribute disapproves the product, removing it from Shopping surfaces. The feed is the primary rail Google's shopping surfaces read, so keep it live and complete. - **How to check:** Check Merchant Center / Merchant API for disapprovals and required-attribute warnings. - Priority 3/3 · Effort M · Applies to: merchants targeting Google surfaces · Machine-checkable - **Verify with:** [Google Merchant Center diagnostics](https://support.google.com/merchants/answer/7052112) - **Learn more:** https://agentmint.net/make-product-feed-ai-readable/ **What good looks like:** The feed for a newly added product includes id, title, description, link, image_link, availability, and price the same day the product goes live on the site, not days later after a manual export. Common mistakes: - The feed is a one-time export that's never regenerated, so new products silently never appear in it. - A required attribute like image_link is present for most products but missing for a subset (bundles, digital goods), tripping disapprovals only for that subset. Steps: 1. Open Merchant Center (or your Merchant API dashboard) and check the diagnostics tab for disapproved items and missing-attribute warnings. 2. Confirm the feed regenerates automatically on a schedule, not only when someone remembers to run an export. 3. Spot-check a newly added and a newly discontinued product to confirm the feed reflects both promptly. **For your developer:** id must be stable and match the same value used in your Offer JSON-LD's sku or product URL, so Google (and any agent cross-referencing feed to page) can tie the two together; a regenerated feed that reassigns ids breaks that link silently. - **WooCommerce:** A feed plugin (or the Google Listings & Ads extension) needs its own scheduled sync configured; it doesn't regenerate automatically just because WooCommerce's product data changed. ### Validate structured data with the Rich Results Test / Schema.org validator and the feed with Merchant Center diagnostics. - **Evidence:** spec-fact, [Merchant listing structured data](https://developers.google.com/search/docs/appearance/structured-data/merchant-listing) (2026-07-08) - **Why:** Syntax and coverage errors are exactly what automated validators exist to catch; we don't re-implement them. The Rich Results Test, Schema.org validator, and Merchant Center diagnostics surface these; fix every error before worrying about selection. - **How to check:** Zero errors in the Rich Results Test and Schema.org validator; clean Merchant Center diagnostics. - Priority 2/3 · Effort S · Machine-checkable - **Verify with:** [Google Rich Results Test](https://search.google.com/test/rich-results) - **Learn more:** https://agentmint.net/product-schema-for-ai-shopping/ **What good looks like:** Before treating a product page as 'done,' its URL runs clean through the Rich Results Test and the Schema.org validator, and its SKU shows no diagnostic warnings in Merchant Center, all three checked, not assumed. Common mistakes: - Validating once during initial launch and never re-running the checks after a theme update or migration changes how markup renders. - Fixing the errors a validator reports but not the warnings, when a warning (like a missing recommended field) is often the actual thing agents weight. Steps: 1. Run the product URL through Google's Rich Results Test and the Schema.org validator. 2. Check Merchant Center diagnostics for the same product/SKU. 3. Fix every error first, then work through warnings, and re-run all three after any template or feed change. **For your developer:** Treat these three tools as complementary, not redundant: the Schema.org validator checks syntax and vocabulary against the spec, the Rich Results Test checks eligibility for a specific Google surface, and Merchant Center diagnostics check the feed itself, so a page can pass one and still fail another. ### Add hasMerchantReturnPolicy and shippingDetails to the Offer markup. - **Evidence:** spec-fact, [Merchant listing structured data](https://developers.google.com/search/docs/appearance/structured-data/merchant-listing) (2026-07-08) - **Why:** hasMerchantReturnPolicy and shippingDetails are recommended merchant-listing properties; their presence is the eligibility floor for return and shipping surfacing. This item is only that the markup exists; making the terms legible and complete is a separate selection concern. - **How to check:** The Rich Results Test shows the return and shipping objects parsed without error. - Priority 2/3 · Effort M · Machine-checkable - **Verify with:** [Google Rich Results Test](https://search.google.com/test/rich-results) - **Learn more:** https://agentmint.net/product-schema-for-ai-shopping/ **What good looks like:** The Offer markup for a product includes a hasMerchantReturnPolicy object with a real return window and a shippingDetails object with real cost and transit-time ranges, both parsed error-free in the Rich Results Test. Common mistakes: - The return and shipping objects are copy-pasted from a generator's example and never filled in with the store's real numbers. - shippingDetails exists but only covers domestic shipping, leaving international orders undeclared. Steps: 1. Pull the JSON-LD from a product page and locate the hasMerchantReturnPolicy and shippingDetails objects. 2. Confirm the return window and shipping cost/time figures match the actual published policy pages, not placeholder values. 3. Run the page through the Rich Results Test and confirm both objects parse without error. **For your developer:** hasMerchantReturnPolicy expects a MerchantReturnPolicy type with returnPolicyCategory and merchantReturnDays; shippingDetails expects an OfferShippingDetails type with shippingRate and a delivery-time range, both nested types, not flat Offer properties. - **Shopify:** Return and shipping policy pages exist as native settings, but a theme's schema output must be checked separately since policy text existing doesn't guarantee it's mapped into the Offer markup. - **WooCommerce:** There's no native output for either object; it has to come from a schema plugin's settings or a theme customization pulling the store's real shipping/return policy pages. ``` { "@type": "Offer", "hasMerchantReturnPolicy": { "@type": "MerchantReturnPolicy", "returnPolicyCategory": "https://schema.org/MerchantReturnFiniteReturnWindow", "merchantReturnDays": 30 }, "shippingDetails": { "@type": "OfferShippingDetails", "shippingRate": { "@type": "MonetaryAmount", "value": "5.00", "currency": "USD" } } } ``` ## Protocol presence Whether the commerce protocols and payment rails are in place to transact. ### If targeting Google/UCP surfaces, publish a /.well-known/ucp profile: public, no auth. - **Evidence:** spec-fact, [UCP business profile guide](https://developers.google.com/merchant/ucp/guides/ucp-profile) (2026-07-08) - **Why:** The UCP business profile at /.well-known/ucp must be publicly accessible without authentication and declare version, services, capabilities (checkout, fulfillment, order-management), payment_handlers, and signing_keys; agents read it to transact. Validators exist, so don't hand-roll it. Publish it only if you target Google/UCP surfaces. - **How to check:** Fetch /.well-known/ucp unauthenticated; run ucptools.dev, ucpchecker.com, or Rankly. - Priority 2/3 · Effort L · Applies to: merchants targeting Google/UCP surfaces · Machine-checkable - **Verify with:** [ucptools.dev](https://ucptools.dev) - **Learn more:** https://agentmint.net/ucp-vs-acp/ **What good looks like:** A store selling on Google's shopping surfaces publishes a JSON file at /.well-known/ucp reachable with no login, listing its real capabilities and a live signing key, not a copy-pasted template. Common mistakes: - Publishing the file behind the same login wall that protects the rest of the admin area, so it 404s or redirects for an unauthenticated fetch. - Copying a sample profile from documentation and forgetting to swap in the store's real capabilities and signing keys. Steps: 1. Fetch the profile URL from a logged-out browser or curl and confirm it returns the JSON body, not a redirect or login page. 2. Run it through a UCP validator and fix any missing required field. 3. Only publish this if you actually target Google/UCP surfaces; otherwise skip the item. **For your developer:** The file must be served over plain HTTPS with no auth in front of it, since agents fetch it directly and can't authenticate; treat it like robots.txt for access-control purposes. - **Shopify:** Hosted platforms without root-level file access may need a proxy or edge rule for this path; check with the platform before assuming it's possible. - **WooCommerce:** A static file at the site's document root, or a simple rewrite rule, is enough since a self-hosted store controls its own web server. ### If targeting ChatGPT checkout, build the ACP product feed and checkout and set the eligibility flags. - **Evidence:** spec-fact, [ACP product feed specification](https://developers.openai.com/commerce/specs/file-upload/products) (2026-07-08) - **Why:** ChatGPT discoverability requires is_eligible_search=true (and is_eligible_checkout for buy-in-chat), a compliant feed (item_id, price, availability, and return_policy when checkout-eligible), plus enrollment in OpenAI's merchant program. ACP is the rail ChatGPT's shopping surfaces read. Only relevant if you target ChatGPT checkout. - **How to check:** Validate a sample feed; ucptools.dev reports ACP/ChatGPT readiness. - Priority 3/3 · Effort L · Applies to: merchants targeting ChatGPT checkout · Machine-checkable - **Verify with:** [ucptools.dev](https://ucptools.dev) - **Learn more:** https://agentmint.net/ucp-vs-acp/ **What good looks like:** A store that wants to sell inside ChatGPT has enrolled in OpenAI's merchant program, ships a feed that sets is_eligible_search=true on every product it wants surfaced, and sets is_eligible_checkout=true only on items whose feed rows also carry the required checkout fields. Common mistakes: - Setting is_eligible_checkout=true on a product whose feed row is missing a field checkout requires, so the item validates for search but fails for buy-in-chat. - Building the feed but never enrolling in the merchant program, so eligible flags have nothing to act on. Steps: 1. Confirm you actually target ChatGPT checkout before starting; if not, skip this item. 2. Build the feed with item_id, price, and availability on every row. 3. Set is_eligible_search and, where you want buy-in-chat, is_eligible_checkout, then run a validator. **For your developer:** is_eligible_checkout requires is_eligible_search=true as a precondition, not an independent flag: a row can be search-eligible without being checkout-eligible, but not the reverse, and the checkout-eligible subset needs the extra return and policy fields the search-only rows can omit. ``` { "item_id": "SKU-1001", "price": "49.99 USD", "availability": "in_stock", "is_eligible_search": true, "is_eligible_checkout": true, "return_policy": "https://example.com/returns" } ``` ### Validate protocol manifests with existing validators; don't build your own. - **Evidence:** spec-fact, [ucptools.dev: UCP/ACP validator](https://ucptools.dev) (2026-07-08) - **Why:** ucptools.dev (4-level), ucpchecker.com, and Rankly already lint the manifest, transports, schema, and readiness. Our lane is deciding whether and when to implement UCP or ACP, not competing on validation depth: run an existing validator rather than building your own. - **How to check:** Green (or triaged) results from at least one validator. - Priority 1/3 · Effort S · Applies to: merchants implementing UCP/ACP · Machine-checkable - **Verify with:** [ucptools.dev](https://ucptools.dev) - **Learn more:** https://agentmint.net/ucp-vs-acp/ **What good looks like:** Before shipping a UCP or ACP manifest, a store runs it through at least one public validator, reads every reported level, and either clears each finding or writes down why a warning was accepted, rather than assuming a manifest that loads is a manifest that passes. Common mistakes: - Treating an HTTP 200 on the manifest URL as proof it validates, when a validator would still flag schema or transport errors inside a file that loads fine. - Writing a homegrown checker and trusting it over the maintained public validators, which track spec changes you won't. Steps: 1. Pick one maintained validator and paste in your manifest URL. 2. Work through every error, then every warning, fixing or consciously triaging each. 3. Re-run the validator after any manifest change, since a small edit can break a field a downstream agent depends on. **For your developer:** Validators check layers you'd otherwise miss by eye (transport, schema, and readiness), so run one on every deploy rather than reimplementing those checks yourself. ### Confirm your payment stack can complete an agent-initiated purchase (AP2 / Visa Trusted Agent / Mastercard Agent Pay). - **Evidence:** reported, [AP2: Agent Payments Protocol](https://ap2-protocol.org) (2026-07-07) - **Why:** Payment-rail attestation is table stakes for an agent to complete a checkout. These rails, AP2, Visa Trusted Agent Protocol, and Mastercard Agent Pay (reported, PYMNTS 2025-04-29), are explicitly agnostic about which merchant is chosen, so they gate selectability, not selection. Visa/Mastercard primaries are still being verified. - **How to check:** Confirm with your PSP which agent-payment rails are supported. - Priority 3/3 · Effort M - **Learn more:** https://agentmint.net/agentic-payment-protocols/ **What good looks like:** A store has asked its payment provider, in writing, which agent-payment rails the account supports today, and has a dated answer on file rather than an assumption that whatever processes card payments will also clear an agent-initiated one. Common mistakes: - Assuming the existing card processor already handles agent-initiated payments without confirming it, then discovering the gap only when a real agent checkout fails. - Treating this as a one-time check, when rail support is still changing and a 'not yet' answer can become 'yes' within a quarter. Steps: 1. Ask your payment provider which agent-payment rails your account supports right now, and record the date of the answer. 2. If a rail you need isn't supported, ask what enabling it requires and note it as a follow-up. 3. Re-confirm periodically, since these rails are new and provider support is still evolving. **For your developer:** Rail support is a property of your specific processor and account configuration, not the card network alone, so verify it with your provider rather than inferring it from the network's public announcements. ## Checkout & operations Whether an agent can complete a purchase and trust the operational data. ### Make guest checkout possible, with no forced account creation. - **Evidence:** hypothesis - **Why:** We expect a forced-signup wall to break or deter a programmatic or agent checkout that has no credentials to create an account, dropping the sale after the agent already chose you. Guest or delegated checkout keeps the path completable. - **How to check:** Attempt a purchase without logging in; confirm it completes. - Priority 2/3 · Effort M - **Learn more:** https://agentmint.net/chatgpt-shopping-optimization/ **What good looks like:** A first-time buyer can go from product page to order confirmation entering only shipping and payment details, never being forced to pick a password or verify an email before the purchase completes. Common mistakes: - Offering a guest option that still emails a verification link the buyer must click before the order is placed, which a programmatic checkout can't act on. - Requiring account creation only at the last step, so the failure appears after the agent already committed to buying. Steps: 1. Open the store in a private window with no saved login. 2. Add an item and try to complete a real purchase without creating an account. 3. Confirm you reach an order confirmation with no forced signup, password step, or mandatory email verification along the way. **For your developer:** An optional post-purchase 'create an account' prompt is fine as long as it comes after the order is placed, not as a required step in the checkout flow itself. - **Shopify:** Customer accounts can be set to optional or required at the store level; set them to optional so the checkout doesn't demand an account. - **WooCommerce:** Guest checkout is a single setting under the accounts and privacy options; confirm it's enabled and that no payment or shipping extension silently re-imposes a login. ### Keep inventory accurate and refreshed at the cadence agents expect. - **Evidence:** hypothesis, [Get started with the Agentic Commerce Protocol](https://developers.openai.com/commerce/guides/get-started) (2026-07-08) - **Why:** We expect stale availability to produce failed agent checkouts and lost trust; the ACP feed supports frequent refreshes (its get-started guide describes a short, minutes-scale update cadence). Validators explicitly do not assess inventory accuracy. This is a merchant discipline, not a lint. - **How to check:** Spot-check feed availability vs. real stock; confirm the sync frequency. - Priority 2/3 · Effort L - **Learn more:** https://agentmint.net/make-product-feed-ai-readable/ **What good looks like:** When the last unit of a product sells, its feed availability flips to out of stock within minutes, so an agent reading the feed never offers a buyer something the warehouse can no longer ship. Common mistakes: - Syncing the feed on a slow daily batch, so a popular item stays listed as available for hours after it sold out. - Updating the storefront's stock display in real time but leaving the outbound feed on a separate, slower schedule, so the two disagree. Steps: 1. Pick a fast-moving product and compare its current feed availability against real warehouse stock. 2. Find out how often the feed regenerates and whether a stock change triggers a refresh or waits for the next scheduled run. 3. Tighten the cadence toward minutes for fast-selling items if the gap is wide enough to oversell. **For your developer:** Prefer an event-driven push on stock change over a fixed polling interval where your platform supports it, since a fixed interval sets a hard floor on how stale the feed can get between runs. ### Enforce price parity across product page, feed, and structured data. - **Evidence:** spec-fact, [Product data specification](https://support.google.com/merchants/answer/7052112) (2026-07-08) - **Why:** Merchant Center requires the price to match the landing page, structured data, and checkout; a mismatch disapproves the product and makes an agent distrust the offer. This is both an eligibility rule and a trust signal, so enforce parity across feed, JSON-LD, and page. - **How to check:** Compare the same SKU's price in feed, JSON-LD, PDP, and checkout. - Priority 3/3 · Effort M · Machine-checkable - **Verify with:** [Google Merchant Center diagnostics](https://support.google.com/merchants/answer/7052112) - **Learn more:** https://agentmint.net/make-product-feed-ai-readable/ **What good looks like:** A single product shows the exact same price in its feed row, its JSON-LD Offer, on the product page, and in the cart total, so an agent comparing any two of those sources never sees a discrepancy that reads as a bait price. Common mistakes: - The feed and page agree, but a sale price applied at the cart level makes the checkout total lower than everything published upstream. - A tax-inclusive page price is compared against a tax-exclusive feed price, so the two look mismatched even though both are technically correct. Steps: 1. Pick one SKU and read its price from the feed, the JSON-LD, the product page, and the final cart total. 2. Confirm all four match, accounting consistently for tax and currency. 3. Trace any mismatch to its source (a sale rule, a rounding step, a stale cache) and align them on one figure. **For your developer:** Drive the feed, JSON-LD, and displayed price from the same pricing source rather than computing each independently, since duplicated price logic is the usual reason the four values drift apart. - **WooCommerce:** Sale prices and tax-display settings are applied at render time; confirm a schema or feed plugin reads the same computed price the customer is charged, not the raw regular price. ### Make order status retrievable after purchase. - **Evidence:** spec-fact, [UCP business profile guide](https://developers.google.com/merchant/ucp/guides/ucp-profile) (2026-07-08) - **Why:** UCP scopes order-management and post-purchase as a declared capability. If an agent completes a checkout but the order state is opaque, the post-sale experience (and your future selection) suffers, so confirm order status is retrievable through your UCP capabilities or merchant-of-record flow. - **How to check:** Confirm your UCP capabilities/order endpoints (or merchant-of-record flow) return status. - Priority 1/3 · Effort L · Applies to: merchants using UCP checkout - **Learn more:** https://agentmint.net/ucp-vs-acp/ **What good looks like:** After an agent completes a purchase, it can come back and ask for that order and get a real state (confirmed, shipped, delivered) in return, rather than hitting a dead end once the checkout call succeeds. Common mistakes: - Building a checkout that returns an order id but exposing no way to look that order up again afterward, so status is a black box once the sale closes. - Returning status only inside a human-facing account page that a programmatic caller can't reach. Steps: 1. Place a test order through your agent checkout path and capture the order identifier. 2. Query your order-status endpoint or merchant-of-record flow with that identifier and confirm it returns a meaningful state. 3. Confirm the status keeps updating as the order moves from confirmed to shipped to delivered. **For your developer:** If you declare order-management as a UCP capability, make sure a retrievable status endpoint actually backs it, since declaring the capability without a working lookup is worse than not declaring it. ### Populate the ACP feed's return fields for checkout-eligible products. - **Evidence:** spec-fact, [ACP product feed specification](https://developers.openai.com/commerce/specs/file-upload/products) (2026-07-08) - **Why:** return_policy (a URL) is required when is_eligible_checkout=true, and accepts_returns plus return_deadline_in_days are the canonical return-window fields. Missing them blocks or degrades buy-in-chat, so populate the ACP feed's return fields for every checkout-eligible product. - **How to check:** Validate the feed; confirm return fields are present for checkout-eligible items. - Priority 2/3 · Effort M · Applies to: ChatGPT-checkout merchants · Machine-checkable - **Verify with:** [ucptools.dev](https://ucptools.dev) - **Learn more:** https://agentmint.net/make-product-feed-ai-readable/ **What good looks like:** Every checkout-eligible product in the ACP feed carries a resolvable return-policy URL and a real return window, so an agent can tell a shopper the return terms before they buy instead of stalling on a missing field. Common mistakes: - Setting a product checkout-eligible but leaving its return-policy field blank, which blocks or degrades buy-in-chat for that item. - Pointing the return-policy field at a page that redirects or 404s, so the URL is present but not actually resolvable. Steps: 1. Filter the feed to products marked checkout-eligible. 2. Confirm each carries a return-policy URL plus the return-window fields, and that the URL returns a live policy page. 3. Run the feed through a validator and fix any product it flags for a missing return field. **For your developer:** The return-policy value is a URL, not free text, and it's required specifically for checkout-eligible rows, so a search-only product can omit it while a checkout-eligible one cannot. ``` { "item_id": "SKU-1001", "is_eligible_checkout": true, "return_policy": "https://example.com/returns", "accepts_returns": true, "return_deadline_in_days": 30 } ``` ## Monitoring Whether you watch that agents reach, read, and buy, and keep readiness current. ### Confirm AI-agent user-agents actually appear in your server logs. - **Evidence:** spec-fact, [Overview of OpenAI Crawlers](https://developers.openai.com/api/docs/bots) (2026-07-08) - **Why:** The user-agent tokens are documented and verifiable (GPTBot/1.3, OAI-SearchBot/1.3, ChatGPT-User/1.0, ClaudeBot, Claude-SearchBot, PerplexityBot). We expect that if none appear in your logs, agents aren't reaching you: a silent failure no external validator surfaces. - **How to check:** Grep access logs for the documented user-agent strings over a recent window. - Priority 2/3 · Effort S - **Learn more:** https://agentmint.net/ai-crawlers-robots-llms-txt/ **What good looks like:** A store's ops team runs a scheduled search of recent access logs for the documented agent user-agent strings and finds real hits returning 200, not zero matches or a wall of blocked requests. Common mistakes: - Checking logs once at launch and never repeating the search, so a later block or misconfiguration goes unnoticed for months. - Treating any line that mentions a bot's name as a successful visit, without checking whether that same line shows a blocked or challenged status. Steps: 1. Pull a recent window of access logs (a week is a reasonable start). 2. Search for the documented user-agent strings for the agents you care about. 3. Confirm the matching requests return 200, not a blocked or challenged status. 4. Repeat this check on a recurring schedule, not only once. **For your developer:** A matching log line isn't proof of success by itself; check the status code and response size on that same line, since a WAF challenge can still log the original user-agent string. - **Shopify:** Merchants don't get direct access to raw server logs on this platform, so this check likely needs a CDN log or a bot-monitoring app in front of the store rather than a grep on your own server. ``` grep -E "GPTBot|OAI-SearchBot|ChatGPT-User|ClaudeBot|Claude-SearchBot|PerplexityBot" access.log \ | awk '{print $9}' | sort | uniq -c ``` ### Segment AI-referred traffic in analytics. - **Evidence:** hypothesis - **Why:** AI-referred retail traffic is rising fast and now converts better (reported: Adobe Analytics via TechCrunch, 2026-04-16). You can't manage what you don't measure. We expect stores that isolate AI-assistant referrers to see the trend and act, while those lumping them into direct/referral stay blind. - **How to check:** Confirm an analytics segment or filter isolates AI-assistant referrers. - Priority 1/3 · Effort S - **Learn more:** https://agentmint.net/research/methodology/ **What good looks like:** A saved analytics segment isolates sessions referred by known AI assistant domains, and someone checks that segment's trend alongside organic and paid channels on a recurring basis, not only when a stakeholder happens to ask. Common mistakes: - AI-assistant referrers get lumped into a generic direct or unassigned traffic bucket, making the trend invisible next to organic and paid. - The segment is built once from today's known assistant domains and never updated as new AI shopping surfaces appear. Steps: 1. List the referrer domains and any URL parameters your analytics tool can detect for AI assistants. 2. Build a saved segment or filter that isolates that traffic. 3. Review that segment's trend on the same cadence you review organic and paid traffic. **For your developer:** Referrer-header matching alone likely undercounts this traffic, since some assistant surfaces omit or strip a referrer; treat a referrer-only count as a floor, not a complete figure. ### Assign a named owner who re-checks agent-readiness monthly. - **Evidence:** hypothesis - **Why:** We expect readiness to silently rot without an owner and cadence: bot tokens, protocol versions, and feed specs change (UCP profile versions are dated; crawler docs were updated in 2026). Assign a named person and a recurring review that re-runs the validators, a habit no tool enforces. - **How to check:** A named person plus a recurring calendar review that re-runs the validators. - Priority 1/3 · Effort S - **Learn more:** https://agentmint.net/research/methodology/ **What good looks like:** One named person, not a team inbox, owns a recurring monthly calendar entry to re-run the readiness validators used at launch and logs the date and result each time. Common mistakes: - No one is named, so the check only happens on the occasions someone happens to remember it. - The review runs once at launch and is never repeated on an actual schedule, so drift accumulates silently. Steps: 1. Name one accountable person for this check, not a shared team inbox. 2. Add a recurring monthly calendar entry, not a someday task in a backlog. 3. Re-run the same validators used at launch and log the date and outcome each time. ### Keep an accessible, current XML sitemap. - **Evidence:** spec-fact, [Rankly UCP/ACP validator](https://tryrankly.com/ucp-validator) (2026-07-08) - **Why:** Search and citation crawlers, and Rankly's discoverability check, use the sitemap to find product URLs; a missing or stale sitemap slows agent discovery. Keep an accessible, current XML sitemap that lists your live product URLs. - **How to check:** Fetch /sitemap.xml; confirm it lists current product URLs. Rankly checks sitemap accessibility. - Priority 2/3 · Effort S · Machine-checkable - **Verify with:** [Rankly UCP/ACP validator](https://tryrankly.com/ucp-validator) - **Learn more:** https://agentmint.net/ai-crawlers-robots-llms-txt/ **What good looks like:** The live sitemap lists a newly published product the same day it goes live and drops a discontinued one within days, rather than reflecting a snapshot from whenever it was last regenerated. Common mistakes: - The sitemap was generated once at launch and never regenerates as products are added or removed. - Discontinued or permanently out-of-stock products linger in the sitemap long after they stop being purchasable. Steps: 1. Fetch the live sitemap URL directly and confirm it loads without error. 2. Spot-check a recently added and a recently discontinued product against it. 3. Confirm the sitemap regenerates on a schedule tied to catalog changes, not a manual export. - **Shopify:** The platform generates and serves this sitemap automatically at a fixed path; check for products excluded by publishing or sales-channel settings instead of trying to edit the file. - **WooCommerce:** WordPress core auto-generates a basic sitemap covering products by default, so one exists even with no plugin. Most SEO plugins replace it with a richer version (images, priority, finer lastmod); confirm whichever one is live is current, not that one exists at all. ### Serve the whole store over HTTPS. - **Evidence:** hypothesis, [ACP product feed specification](https://developers.openai.com/commerce/specs/file-upload/products) (2026-07-08) - **Why:** The ACP feed spec marks product, seller, and policy URLs as "HTTPS preferred," and agentic-commerce security checks flag mixed or insecure content. We expect HTTPS everywhere (no mixed-content warnings) to be table stakes for reliable protocol transactions and trust. - **How to check:** Run ucptools.dev or Rankly security checks; confirm no mixed content. - Priority 3/3 · Effort M · Machine-checkable - **Verify with:** [ucptools.dev](https://ucptools.dev) - **Learn more:** https://agentmint.net/ucp-vs-acp/ **What good looks like:** Every page an agent might fetch, home, category, product, and checkout, loads over HTTPS with zero mixed-content warnings in the browser console, not only the top-level document. Common mistakes: - The page itself is HTTPS, but an old image or script tag still hardcodes an http:// URL, triggering a mixed-content warning. - A secondary subdomain, like a legacy image host, was never migrated to HTTPS when the main site was. Steps: 1. Load key pages and check the browser console for mixed-content warnings. 2. Search for hardcoded http:// asset references and update them to https://. 3. Confirm every subdomain your pages load resources from also serves a valid HTTPS certificate. - **Shopify:** TLS is provisioned and renewed automatically for the primary and any connected custom domain, so this item is mostly about eliminating asset-level mixed content, not certificate management. - **WooCommerce:** TLS depends on your host, not WooCommerce itself; a force-SSL setting is usually still needed to redirect lingering http:// requests, since installing a certificate alone doesn't rewrite existing links. ### Provide high-resolution product images in feed and markup. - **Evidence:** spec-fact, [Product data specification](https://support.google.com/merchants/answer/7052112) (2026-07-08) - **Why:** image_link is a required Merchant Center attribute and merchant-listing requires images (Google notes a minimum resolution); an agent that surfaces a product with a broken or low-res image undercuts your listing. Provide high-resolution images in both feed and markup. - **How to check:** Merchant Center image diagnostics; confirm image is present in markup and feed. - Priority 2/3 · Effort M · Machine-checkable - **Verify with:** [Google Merchant Center diagnostics](https://support.google.com/merchants/answer/7052112) - **Learn more:** https://agentmint.net/make-product-feed-ai-readable/ **What good looks like:** A product's feed row and its JSON-LD point to the exact same high-resolution image file, and that file actually loads and clearly shows the product, not a thumbnail or a broken placeholder. Common mistakes: - The feed references a thumbnail-sized image while the on-page markup points to a different, full-resolution file, so the two disagree. - An image link 404s after a CDN or theme migration, unnoticed because the page still renders the image from a separate, unaffected field. Steps: 1. Pull the image URL from the feed and from the JSON-LD for the same product. 2. Open both directly and confirm they load, match, and show real product detail. 3. Check Merchant Center's image diagnostics and fix the source, feed generation or markup, not just the symptom. **For your developer:** Generate the feed and markup image URLs from the same source field rather than independently, since duplicated logic is the usual reason a low-res or broken image reaches only one of the two. ### Declare itemCondition where the product isn't new. - **Evidence:** spec-fact, [Product data specification](https://support.google.com/merchants/answer/7052112) (2026-07-08) - **Why:** condition is required in Merchant Center for used or refurbished items, and itemCondition is a recommended Offer property; omitting it risks disapproval and mismatched agent expectations. Declare itemCondition in feed and markup wherever the product isn't new. - **How to check:** Confirm condition in feed and markup for non-new items. - Priority 1/3 · Effort S · Applies to: sellers of used/refurbished goods · Machine-checkable - **Verify with:** [Google Merchant Center diagnostics](https://support.google.com/merchants/answer/7052112) - **Learn more:** https://agentmint.net/product-schema-for-ai-shopping/ **What good looks like:** A refurbished or used listing states its condition in both the feed and the JSON-LD, using the same word ("refurbished," "used") the product page shows the shopper. Common mistakes: - Every product defaults to new in the feed, even for a whole category that's actually refurbished or open-box. - The page copy says refurbished, but the structured data and feed condition field are left blank or set to new. Steps: 1. List every product line that isn't sold new. 2. Set the condition field in both the feed and the JSON-LD to match what the page tells the shopper. 3. Re-check after any bulk import, since a default value can silently overwrite a correct one. **For your developer:** Map each internal condition state to its own matching schema.org value rather than collapsing every non-new state into one generic "used" label. ### Publish shipping, returns, and privacy policies as crawlable HTML URLs. - **Evidence:** spec-fact, [ucptools.dev: UCP/ACP validator](https://ucptools.dev) (2026-07-08) - **Why:** ucptools.dev checks for policy-page presence, and the ACP feed's return_policy expects a resolvable URL; a policy hidden in a PDF or a JS-only modal isn't reliably reachable by an agent. Publish shipping, returns, and privacy policies as standalone crawlable HTML URLs. - **How to check:** Confirm each policy is a standalone crawlable HTML URL returning 200. - Priority 2/3 · Effort S · Machine-checkable - **Verify with:** [ucptools.dev](https://ucptools.dev) - **Learn more:** https://agentmint.net/ai-crawlers-robots-llms-txt/ **What good looks like:** Shipping, returns, and privacy policies each live at their own plain HTML URL that returns the full policy text with JavaScript disabled, not a PDF download or a modal that only opens on click. Common mistakes: - The return policy is a PDF linked from the footer instead of a plain HTML page. - The policy text only appears inside a JavaScript-triggered modal or accordion, so it's absent from the raw page source. Steps: 1. Locate the live URL for each policy: shipping, returns, and privacy. 2. Load each with JavaScript disabled and confirm the actual policy text appears, not just a button that opens it. 3. Confirm each URL returns 200 directly, without a required click-through or redirect chain. - **Shopify:** The built-in legal policy pages get their own crawlable URLs once you fill them in under Settings > Policies; the risk is a custom theme rendering the text in a popup instead of linking out to those native pages. - **WooCommerce:** Setup auto-creates a draft Refund and Returns page at its own URL, but it stays unpublished with sample text until finished and published. Shipping and privacy policies have no equivalent page; if either lives inside a general About page, split it onto its own URL. ### Confirm agent IPs aren't caught by aggressive rate-limiting or geoblocking. - **Evidence:** hypothesis, [Overview of OpenAI Crawlers](https://developers.openai.com/api/docs/bots) (2026-07-08) - **Why:** We expect blanket rate rules or country blocks to trip agent fetchers that arrive in bursts or from cloud and edge IPs, producing intermittent invisibility that looks like sometimes we show up. Allow-list the published agent IP ranges and test burst fetches. - **How to check:** Review WAF/CDN rules against published agent IP endpoints; test burst fetches. - Priority 2/3 · Effort M · Applies to: all (esp. sites with strict WAF/geo rules) - **Learn more:** https://agentmint.net/store-not-in-chatgpt-shopping/ **What good looks like:** A store simulates a burst of rapid requests from a published agent IP range, confirms none get throttled or blocked by a rate or country rule, then reruns that same test after any CDN or firewall change. Common mistakes: - A rate limit tuned for human browsing speed treats an agent's rapid sequential fetches as abuse and starts throttling it. - A geoblock aimed at one country of unwanted traffic also catches a cloud region an agent vendor happens to route requests through. Steps: 1. Get the published IP ranges for the agents you care about. 2. Send a short burst of requests from those ranges and watch for throttling, blocks, or CAPTCHAs. 3. Review geoblocking rules for overlap with regions agent vendors route traffic from. 4. Rerun this test after any WAF, CDN, or rate-limit configuration change. - **Shopify:** Bot and rate-limit protections are managed by the platform rather than exposed for merchant configuration; a suspected block is a support-ticket question, not a firewall setting to edit yourself. - **WooCommerce:** Rate-limiting typically lives at the host, CDN, or a security plugin rather than WooCommerce itself, so check each layer separately since allow-listing one doesn't update the others. ``` for i in $(seq 1 20); do curl -A "OAI-SearchBot; +https://openai.com/searchbot" \ -o /dev/null -w "%{http_code}\n" -s https://example.com/products/sample-item done ``` ## Changelog - 2026-07-08 · v1.1: Deepened all 30 items with what-good-looks-like examples, common mistakes, verification steps, developer notes, platform-specific notes, and code snippets where useful. - 2026-07-08 · v1.0: Initial release: 30 readiness items across 5 categories.