kyliecosmetics.com

ShopifybeautyScanned yesterday · engine v1.0.1Open in new tab
Rescan

Work at kyliecosmetics.com?Verify your @kyliecosmetics.com email to rescan on demand.

Legible

Agents can get in and understand products, but can't yet shop the store end to end.

Higher than 91% of 192 scanned stores

Pillars

  • Access32/35
  • Catalog legibility17.5/25
  • Transactability19/25
  • Trust & policy7/15

Checks

15 of 27 scored checks passed. Expand a row for the evidence behind it.

Access

32/35

Catalog legibility

17.5/25

Transactability

19/25

Trust & policy

7/15

How to fix it

12 fixes for kyliecosmetics.com, ready to paste into a ticket or hand to a coding agent.

  1. Add a Content-Signal directive

    access.content-signal · partial

    Your robots.txt has no Content-Signal directive. Content Signals (contentsignals.org) is a robots.txt extension that states, separately, whether your content may be used for search, as real-time AI input (which is what shopping agents do), and for training. An explicit signal scores fully; silence scores half.

    You can welcome shopping agents while still declining training. Add to the * group (or to each group you care about):

    User-agent: *
    Content-Signal: search=yes, ai-input=yes, ai-train=no
    Allow: /
    

    Keep ai-input=yes; set ai-train however you like. If Cloudflare manages your robots.txt, the equivalent setting lives in AI Crawl Control → Content Signals.

    On Shopify, robots.txt is generated from the theme. In Online Store → Themes → Edit code, add a robots.txt.liquid template (Add a new template → robots.txt) if you do not have one, keep the default groups, and append your rules after the loop. SEO apps that "manage" robots.txt for you are a common source of AI-bot blocks; check their settings too.

  2. Publish a Web Bot Auth key directory

    access.web-bot-auth · fail

    Nothing usable was found at /.well-known/http-message-signatures-directory (HTTP 404). Web Bot Auth is the IETF draft that lets agents sign requests with HTTP Message Signatures; parties that sign publish their Ed25519 public keys in this directory, and verifiers fetch it to check the Signature and Signature-Input headers. Visa's Trusted Agent Protocol, Mastercard's Agent Pay, and Cloudflare's signed-agent verification are all built on it.

    Two steps matter for a storefront:

    • Verify signatures at your edge so signed agents are let through bot management instead of challenged. On Cloudflare this is the Verified Bots / signed agents setting; other WAFs are adding the same.
    • Publish your own directory for any requests you sign (your own agent, service-to-service calls, or a verifier that expects one to exist). Serve it with Content-Type: application/http-message-signatures-directory+json:
    {
      "keys": [
        {
          "kty": "OKP",
          "crv": "Ed25519",
          "kid": "2026-01",
          "x": "<base64url-encoded public key>",
          "nbf": 1767225600,
          "exp": 1798761600
        }
      ]
    }
    

    On Shopify, themes cannot serve files under /.well-known/, so treat this as out of scope unless you run a proxy (Shopify Plus with Cloudflare) that can answer the path. It is worth 2 points.

  3. Add identifiers and brand to product markup

    catalog.identifiers · partial

    Your product markup has sku but no brand. Agents use a GTIN, MPN, or SKU to recognise the same item across retailers (for price comparison and reviews) and the brand to answer "is this the real thing".

    Add to the Product node:

    "sku": "TR2-BLK-10",
    "gtin13": "0012345678905",
    "mpn": "TR2-BLK",
    "brand": { "@type": "Brand", "name": "Example" }
    

    Use gtin13/gtin12/gtin14 for barcodes (EAN/UPC), mpn for the manufacturer part number, and sku for your own code. One identifier is enough for the check; a GTIN is the most useful.

    On Shopify, map {{ variant.barcode }} to gtin13, {{ variant.sku }} to sku, and {{ product.vendor }} to the brand name in the theme's JSON-LD block. Fill in barcodes on the variant (Products → variant → Inventory → Barcode).

  4. Add shipping, returns, and price validity to the Offer

    catalog.offer-details · fail

    Your Offer is missing shippingDetails, hasMerchantReturnPolicy, and priceValidUntil. Agents rank options by delivery time, delivery cost, return risk, and how confident they are in the price; these three fields are where they look.

    Add to the offers object:

    "priceValidUntil": "2026-12-31",
    "shippingDetails": {
      "@type": "OfferShippingDetails",
      "shippingRate": { "@type": "MonetaryAmount", "value": "0", "currency": "USD" },
      "shippingDestination": { "@type": "DefinedRegion", "addressCountry": "US" },
      "deliveryTime": {
        "@type": "ShippingDeliveryTime",
        "handlingTime": { "@type": "QuantitativeValue", "minValue": 0, "maxValue": 1, "unitCode": "DAY" },
        "transitTime": { "@type": "QuantitativeValue", "minValue": 2, "maxValue": 5, "unitCode": "DAY" }
      }
    },
    "hasMerchantReturnPolicy": {
      "@type": "MerchantReturnPolicy",
      "applicableCountry": "US",
      "returnPolicyCategory": "https://schema.org/MerchantReturnFiniteReturnWindow",
      "merchantReturnDays": 30,
      "returnMethod": "https://schema.org/ReturnByMail",
      "returnFees": "https://schema.org/FreeReturn"
    }
    

    Use your real values; one representative shipping rate and destination is enough. Set priceValidUntil to a date you can honour (the end of the current season or year, regenerated as it passes).

    On Shopify, add these to the theme's JSON-LD block, driving the values from theme settings (return window, free-shipping threshold) so merchandisers can change them without touching Liquid. Shopify's own agentic surfaces read policies from Settings → Policies, so keep both in sync.

  5. Add BreadcrumbList and ItemList markup

    catalog.list-markup · fail

    Neither BreadcrumbList (product page) nor ItemList (category or search page) was found. Breadcrumbs tell an agent where a product sits in the catalog; an ItemList lets it read a whole category or result set in one pass.

    On the product page:

    {
      "@context": "https://schema.org",
      "@type": "BreadcrumbList",
      "itemListElement": [
        { "@type": "ListItem", "position": 1, "name": "Home", "item": "https://www.example.com/" },
        { "@type": "ListItem", "position": 2, "name": "Footwear", "item": "https://www.example.com/collections/footwear" },
        { "@type": "ListItem", "position": 3, "name": "Trail Runner 2" }
      ]
    }
    

    On category and search result pages:

    {
      "@context": "https://schema.org",
      "@type": "ItemList",
      "itemListElement": [
        { "@type": "ListItem", "position": 1, "url": "https://www.example.com/products/trail-runner-2" },
        { "@type": "ListItem", "position": 2, "url": "https://www.example.com/products/ridge-hiker" }
      ]
    }
    

    On Shopify, Dawn does not emit either by default. Add the BreadcrumbList to the product section using collection and product, and loop collection.products in sections/main-collection-product-grid.liquid (and search.results in the search section) for the ItemList. Several SEO apps add both.

  6. Offer a Markdown version of product pages

    catalog.markdown-negotiation · fail

    Requesting https://kyliecosmetics.com/products/winter-kissed-collection-key-chain with Accept: text/markdown returned HTML. Agents that support content negotiation get a page that is a tenth of the size and needs no parsing. This is worth one point and is a nice-to-have.

    When the Accept header prefers text/markdown, respond with a Markdown body and Vary: Accept:

    GET /products/trail-runner-2 HTTP/1.1
    Accept: text/markdown
    
    HTTP/1.1 200 OK
    Content-Type: text/markdown; charset=utf-8
    Vary: Accept
    
    # Trail Runner 2
    **$129.00** · In stock · SKU TR2-BLK-10
    
    Lightweight waterproof trail shoe. Sizes 6–13. Free shipping over $75, 30-day returns.
    

    The simplest place to do this is edge middleware (a Cloudflare Worker, Vercel or Netlify middleware, or a Next.js route) that converts the rendered HTML or renders a dedicated template. If you are on Cloudflare, the "Markdown for Agents" option in AI Crawl Control does the conversion for you.

    On Shopify, themes cannot vary the response on Accept, so this is only possible behind a proxy (Shopify Plus). Skip it otherwise.

  7. Publish an MCP server card

    tx.mcp-server-card · fail

    Nothing was found at /.well-known/mcp/server-card.json. The server card is the MCP discovery document that lets an agent find your server, its transport endpoint, and how to authenticate, without reading documentation.

    Publish a JSON document describing the server (field names follow the current MCP server-card draft; adjust to the version you target):

    {
      "serverInfo": { "name": "example-storefront", "title": "Example Storefront", "version": "1.0.0" },
      "description": "Search the Example catalog, read policies, and manage a cart.",
      "transport": { "type": "streamable-http", "endpoint": "https://www.example.com/api/mcp" },
      "capabilities": { "tools": {} },
      "authentication": { "required": false }
    }
    

    Serve it as application/json with CORS enabled, and keep the endpoint in sync with the one your UCP profile names.

  8. Publish an API catalog (RFC 9727)

    tx.api-catalog · fail

    No API catalog was found. RFC 9727 defines /.well-known/api-catalog, a linkset that points agents at your APIs and their descriptions (OpenAPI, MCP, UCP) in one place.

    Serve this as application/linkset+json:

    {
      "linkset": [
        {
          "anchor": "https://www.example.com/",
          "service-desc": [
            { "href": "https://www.example.com/api/openapi.json", "type": "application/vnd.oai.openapi+json" }
          ],
          "service-doc": [
            { "href": "https://www.example.com/developers", "type": "text/html" }
          ],
          "service-meta": [
            { "href": "https://www.example.com/.well-known/ucp", "type": "application/json" },
            { "href": "https://www.example.com/.well-known/mcp/server-card.json", "type": "application/json" }
          ]
        }
      ]
    }
    

    Also advertise it from the homepage with a Link header, which we accept on its own:

    Link: </.well-known/api-catalog>; rel="api-catalog"
    
  9. Publish an agent card or skills index

    tx.agent-cards · fail

    None of /.well-known/agent-card.json, /.well-known/agent.json, and /.well-known/agent-skills/index.json was found. An A2A agent card tells other agents that your store has an agent of its own and what it can do; an Agent Skills index lists reusable skill files. Either satisfies this one-point check.

    A minimal A2A agent card at /.well-known/agent-card.json:

    {
      "name": "Example Shopping Assistant",
      "description": "Find, compare, and buy Example products.",
      "url": "https://www.example.com/a2a",
      "version": "1.0.0",
      "protocolVersion": "0.3.0",
      "capabilities": { "streaming": true },
      "defaultInputModes": ["text/plain"],
      "defaultOutputModes": ["text/plain", "application/json"],
      "skills": [
        {
          "id": "find-products",
          "name": "Find products",
          "description": "Search the catalog by query, size, colour, and price.",
          "tags": ["shopping", "search"]
        }
      ]
    }
    

    Or, if you publish skills rather than an agent, serve /.well-known/agent-skills/index.json listing each skill's name, description, and the URL of its SKILL.md. Only publish a card for an endpoint that actually answers.

  10. Add Organization structured data to the homepage

    trust.org-jsonld · fail

    Your homepage has no Organization (or OnlineStore) JSON-LD. Agents look for it to confirm who is behind the store before recommending it; it is also where many of them pick up your logo and support contact.

    Add to the homepage (an OnlineStore is an Organization, and is the better fit for a shop):

    {
      "@context": "https://schema.org",
      "@type": "OnlineStore",
      "name": "Example Outdoor",
      "url": "https://www.example.com/",
      "logo": "https://www.example.com/images/logo.png",
      "sameAs": [
        "https://www.instagram.com/example",
        "https://www.facebook.com/example",
        "https://en.wikipedia.org/wiki/Example_Outdoor"
      ],
      "contactPoint": { "@type": "ContactPoint", "contactType": "customer service", "email": "help@example.com" }
    }
    

    On Shopify, Dawn emits Organization JSON-LD from layout/theme.liquid on the index page, pulling the logo from the header section settings and sameAs from the social links in Theme settings → Social media. Set those and the fields appear; if your theme lacks the block, add the one above with shop.name, shop.url, and settings.logo.

  11. Add MerchantReturnPolicy markup

    trust.return-policy-markup · fail

    No MerchantReturnPolicy structured data was found on the product offer, the homepage, or the organization. A written policy page is good; machine-readable terms let agents compare return windows and fees across stores without reading prose.

    Attach it to the product Offer (preferred, since that is where agents are when deciding) or to the Organization/OnlineStore on the homepage:

    "hasMerchantReturnPolicy": {
      "@type": "MerchantReturnPolicy",
      "applicableCountry": "US",
      "returnPolicyCategory": "https://schema.org/MerchantReturnFiniteReturnWindow",
      "merchantReturnDays": 30,
      "returnMethod": "https://schema.org/ReturnByMail",
      "returnFees": "https://schema.org/FreeReturn",
      "refundType": "https://schema.org/FullRefund",
      "merchantReturnLink": "https://www.example.com/policies/refund-policy"
    }
    

    Use MerchantReturnNotPermitted for final-sale items and MerchantReturnUnlimitedWindow if you accept returns indefinitely. Keep it consistent with the written policy page.

    On Shopify, add the object to the theme's product JSON-LD block, with the window and fees as theme settings, and link merchantReturnLink to {{ shop.refund_policy.url }}.

  12. Add aggregateRating to product markup

    trust.reviews · fail

    Your product markup has no aggregateRating. Agents weigh review scores heavily when choosing between similar products, and they only trust ratings they can read from structured data.

    Add to the Product node, with real numbers from reviews shown on the page:

    "aggregateRating": {
      "@type": "AggregateRating",
      "ratingValue": "4.6",
      "reviewCount": "128",
      "bestRating": "5"
    }
    

    Only emit it for products that actually have reviews, and keep it server-rendered: markup injected by a review widget's JavaScript is invisible to agents.

    On Shopify, review apps (Judge.me, Yotpo, Okendo, Loox, Stamped) each have a "rich snippets" or "SEO/JSON-LD" setting that renders the rating in Liquid rather than injecting it client-side; turn it on. Alternatively merge product.metafields.reviews.rating.value and product.metafields.reviews.rating_count into the theme's product JSON-LD.

History

Oct 20, 2026: 66 (Legible)Oct 20, 2026: 66 (Legible)
DateAURLevelEngine
Oct 20, 202666Legiblev1.0.1
Oct 20, 202666Legiblev1.0.1