sinch.com

CustomScanned 2 hours ago · engine v1.0.1Open in new tab
Rescan

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

Blocked

Shopping agents are blocked or challenged before they can see a product.

Higher than 53% of 216 scanned stores

Pillars

  • Access14/35
  • Catalog legibility4/25
  • Transactability0/25
  • Trust & policy4/15

Capped at 59: No Product structured data was found on the product page

Capped at 79: No agent-native transaction surface was found (UCP, Storefront MCP, or attested ACP)

Partial scan. Some checks hit the time limit, so this score may be lower than a complete scan. Retry the scan to get a full result.

Checks

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

Access

14/35

Catalog legibility

4/25

Transactability

0/25

Trust & policy

4/15

How to fix it

15 fixes for sinch.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.

    Edit the robots.txt served from your web root (or the CDN/edge rule that generates it) and redeploy. Crawlers cache robots.txt for up to 24 hours, so re-scan after a day.

  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
        }
      ]
    }
    

    Serve the file from the same origin as the storefront, with a long cache lifetime, and rotate keys by adding the new one before removing the old.

  3. Add Product structured data

    catalog.product-jsonld · fail

    Your product page has no Product JSON-LD or microdata. This is the most important single fix on the list: without it agents cannot reliably read the name, price, or availability, and your AUR is capped at 59.

    A complete block looks like this (one per product page, in the server-rendered HTML):

    <script type="application/ld+json">
    {
      "@context": "https://schema.org",
      "@type": "Product",
      "name": "Trail Runner 2",
      "image": ["https://www.example.com/images/trail-runner-2.jpg"],
      "description": "Lightweight waterproof trail shoe.",
      "sku": "TR2-BLK-10",
      "gtin13": "0012345678905",
      "brand": { "@type": "Brand", "name": "Example" },
      "offers": {
        "@type": "Offer",
        "url": "https://www.example.com/products/trail-runner-2",
        "price": "129.00",
        "priceCurrency": "USD",
        "availability": "https://schema.org/InStock",
        "itemCondition": "https://schema.org/NewCondition",
        "priceValidUntil": "2026-12-31"
      }
    }
    </script>
    

    For products with variants, use the selected or default variant's price and availability, or a ProductGroup with one Product per variant. Validate with the Schema.org validator or Google's Rich Results Test.

    Render the JSON-LD block server-side in the product page template (not injected by client-side JavaScript), one Product per page, with the price of the default or selected variant.

  4. Add identifiers and brand to product markup

    catalog.identifiers · fail

    Your product markup has neither an identifier nor a 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.

  5. 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).

    Many stores define the return policy once at the Organization level and reference it from each Offer; either is fine as long as the Offer on the product page carries or links to it.

  6. Server-render the product name and price

    catalog.ssr-price · fail

    Agents read the raw HTML. If the product name and price only appear after client-side JavaScript runs, most agents see a blank page or a price-less one.

    • Browser request: no price in server-rendered HTML
    • ChatGPT-User request: no price in server-rendered HTML

    Render the title, price, availability, and the main options into the HTML on the server (SSR or static generation), and let JavaScript enhance rather than create them. Avoid loading the price by a secondary XHR, showing it only as an image, or hiding it behind "add to cart to see price".

    Frameworks: Next.js (server components / getServerSideProps), Nuxt (ssr: true), Remix, SvelteKit, and Astro all render on the server by default; make sure the product route has not opted out.

  7. Add BreadcrumbList and ItemList markup

    catalog.list-markup · partial

    You have BreadcrumbList on the product page but no ItemList on a category or search page. 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 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" }
      ]
    }
    
  8. Offer a Markdown version of product pages

    catalog.markdown-negotiation · fail

    Requesting https://sinch.com/products/chatlayer/ 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.

  9. Publish /llms.txt

    catalog.llms-txt · fail

    No /llms.txt was found (HTTP 404).

    llms.txt (llmstxt.org) is a short Markdown file at the site root that tells language models what the site is and where the important pages are. For a store, point at the catalog, the policies, and any agent endpoints. Serve it as text/plain or text/markdown with a 200 status:

    # Example Outdoor
    
    > Example sells trail-running shoes and apparel, shipping to the US and Canada. Free 30-day returns.
    
    ## Shop
    - [All products](https://www.example.com/collections/all): the full catalog
    - [Product sitemap](https://www.example.com/sitemap_products_1.xml)
    
    ## Policies
    - [Shipping](https://www.example.com/policies/shipping-policy)
    - [Returns](https://www.example.com/policies/refund-policy)
    
    ## For agents
    - [UCP profile](https://www.example.com/.well-known/ucp)
    - [Storefront MCP](https://www.example.com/api/mcp)
    
  10. Publish a UCP business profile

    tx.ucp-profile · fail

    No profile was found at /.well-known/ucp. The Universal Commerce Protocol (ucp.dev) is how an agent discovers, in one request, that your store can be shopped programmatically: which services you expose, over which transports (REST and MCP), and whether checkout is supported. It is the largest single item in the transactability pillar, and without it (or an attested ACP integration) your AUR is capped at 79.

    A complete profile declares a shopping service with an endpoint and a checkout capability:

    {
      "ucp": {
        "version": "2026-01-11",
        "services": {
          "dev.ucp.shopping": {
            "version": "2026-01-11",
            "spec": "https://ucp.dev/specification/overview",
            "rest": {
              "schema": "https://ucp.dev/services/shopping/openapi.json",
              "endpoint": "https://www.example.com/api/ucp"
            },
            "mcp": {
              "schema": "https://ucp.dev/services/shopping/mcp.json",
              "endpoint": "https://www.example.com/api/ucp/mcp"
            }
          }
        },
        "capabilities": [
          {
            "name": "dev.ucp.shopping.checkout",
            "version": "2026-01-11",
            "spec": "https://ucp.dev/specification/checkout",
            "schema": "https://ucp.dev/schemas/shopping/checkout.json"
          },
          {
            "name": "dev.ucp.shopping.order",
            "version": "2026-01-11",
            "spec": "https://ucp.dev/specification/order",
            "schema": "https://ucp.dev/schemas/shopping/order.json"
          }
        ],
        "payment_handlers": []
      }
    }
    

    Serve it as application/json from the storefront origin. The endpoints must exist and speak the protocol; the MCP one is tested by the next check. Check ucp.dev for the current version string and schema URLs.

    Serve the profile from the storefront origin and implement the shopping service behind it; most of the work is the checkout capability, which maps onto your existing cart and checkout APIs.

  11. Serve a Storefront MCP server at /api/mcp

    tx.storefront-mcp · fail

    No MCP server answered tools/list at /api/mcp (HTTP 301). This is the conventional storefront endpoint (Shopify's Storefront MCP lives here) where an agent can search the catalog, read policies, and manage a cart without scraping.

    Expose an MCP server over Streamable HTTP at that path with tools such as search_shop_catalog, get_product_details, search_shop_policies_and_faqs, get_cart, and update_cart. tools/list must be callable without authentication.

    If you already run the UCP MCP endpoint, mounting the same server at /api/mcp is enough.

  12. 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.

  13. 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"
    
  14. 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.

  15. 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.

History

First scan — rescan later to see history.