<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Peter</title>
    <description>The latest articles on DEV Community by Peter (@ucptools).</description>
    <link>https://dev.to/ucptools</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3737432%2F036b6d50-5faf-4939-ac76-c7f56e7a6382.jpeg</url>
      <title>DEV Community: Peter</title>
      <link>https://dev.to/ucptools</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ucptools"/>
    <language>en</language>
    <item>
      <title>ChatGPT Can Shop Now. Is Your Store Ready to Sell to It?</title>
      <dc:creator>Peter</dc:creator>
      <pubDate>Mon, 20 Jul 2026 10:05:06 +0000</pubDate>
      <link>https://dev.to/ucptools/chatgpt-can-shop-now-is-your-store-ready-to-sell-to-it-17o4</link>
      <guid>https://dev.to/ucptools/chatgpt-can-shop-now-is-your-store-ready-to-sell-to-it-17o4</guid>
      <description>&lt;h1&gt;
  
  
  ChatGPT Can Shop Now. Is Your Store Ready to Sell to It?
&lt;/h1&gt;

&lt;p&gt;OpenAI shipped the Agentic Commerce Protocol (ACP) and ChatGPT's shopping agent is live. Target, Sephora, Nordstrom, Best Buy, and Home Depot are already integrated. When a user asks ChatGPT to find them a product, those stores show up.&lt;/p&gt;

&lt;p&gt;If your store isn't ACP-visible, ChatGPT users can't find you. Period.&lt;/p&gt;

&lt;p&gt;Here's the thing most e-commerce developers don't realize: your store might already be ACP-compatible and you just haven't checked. If you're on Shopify with Stripe, HTTPS, and proper policy pages, you could be one product feed away from ChatGPT discoverability.&lt;/p&gt;

&lt;h2&gt;
  
  
  What ACP Actually Checks
&lt;/h2&gt;

&lt;p&gt;ACP is the open standard (Apache 2.0) that OpenAI and Stripe built for AI commerce. It's not proprietary and it's not Stripe-only - Adyen shipped "Adyen Agentic" and PayPal announced ACP support for 2026.&lt;/p&gt;

&lt;p&gt;The protocol checks four things on your store:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Platform&lt;/strong&gt; (25 pts) - Shopify/Etsy auto-eligible path, or custom integration needed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Payment infrastructure&lt;/strong&gt; (30 pts) - Stripe is the easiest path (Shared Payment Token), but seller-backed instruments (gift cards, store credit) also work&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Policy pages&lt;/strong&gt; (25 pts) - Terms, privacy, and return policy are required by spec. Agents need these.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security&lt;/strong&gt; (20 pts) - HTTPS with modern TLS. Hard requirement.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You get a 0-100 score with letter grades (A through F) and finding codes for every failure - not "you failed," but exactly what to fix.&lt;/p&gt;

&lt;h2&gt;
  
  
  ACP vs UCP: Don't Confuse Them
&lt;/h2&gt;

&lt;p&gt;Two protocols, two AI agent ecosystems:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Protocol&lt;/th&gt;
&lt;th&gt;ACP (OpenAI + Stripe)&lt;/th&gt;
&lt;th&gt;UCP (Google + Shopify)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Primary agents&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;ChatGPT&lt;/td&gt;
&lt;td&gt;Google AI Mode, Gemini, Copilot&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Discovery&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;/.well-known/acp.json&lt;/code&gt; + product feed&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;/.well-known/ucp&lt;/code&gt; manifest&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Checkout&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Stripe delegated tokens or merchant app&lt;/td&gt;
&lt;td&gt;Merchant-hosted endpoints&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Focus&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Payment + discovery&lt;/td&gt;
&lt;td&gt;Full commerce (browse, cart, checkout)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Microsoft Copilot already consumes both. checkout.com data shows dual-protocol stores capture 40% more agentic traffic. The recommendation for 2026: implement both if you can. But start by checking what you already have.&lt;/p&gt;

&lt;h2&gt;
  
  
  The March 2026 Pivot (And Why ACP Matters More, Not Less)
&lt;/h2&gt;

&lt;p&gt;OpenAI deprioritized in-ChatGPT checkout in March 2026. Users browsed but didn't buy in-chat. Purchases moved to merchant storefronts.&lt;/p&gt;

&lt;p&gt;But here's what most people missed: the ACP spec had its &lt;em&gt;biggest release&lt;/em&gt; after that pivot. April 17, 2026 brought public product feeds, Cart capability, delegate authentication with 3DS2, and mandatory idempotency keys.&lt;/p&gt;

&lt;p&gt;The takeaway: ACP now governs &lt;em&gt;discovery&lt;/em&gt; inside ChatGPT. If your products aren't ACP-surfaced, ChatGPT users never see them. The purchase completes on your site, but the discovery happens inside the agent. And discovery requires ACP readiness.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Numbers
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;McKinsey: up to $1T in US agentic commerce by 2030&lt;/li&gt;
&lt;li&gt;Morgan Stanley: 126M AI shopping-agent users by 2030&lt;/li&gt;
&lt;li&gt;Shopify: 13x YoY growth in AI search orders&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The retailers showing up today didn't wait. They integrated early. Every week your store isn't checked is a week ChatGPT users buy from someone else.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test It in 30 Seconds
&lt;/h2&gt;

&lt;p&gt;I built a free ACP Readiness Checker that scans your domain and gives you a 0-100 score across all four categories. No account required.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ucptools.dev/acp-checker?utm_source=devto&amp;amp;utm_medium=referral&amp;amp;utm_campaign=acp-checker-promo-202607" rel="noopener noreferrer"&gt;Run the ACP check on your store →&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you score A, you're ChatGPT-ready. If not, you get specific finding codes and fix recommendations for every failing category.&lt;/p&gt;

&lt;p&gt;Your products should show up wherever customers shop. In 2026, that includes ChatGPT.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Also published on &lt;a href="https://ucptools.dev/blog/acp-checker-chatgpt-readiness?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=202607" rel="noopener noreferrer"&gt;ucptools.dev&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>acp</category>
      <category>agenticcommerce</category>
      <category>chatgpt</category>
      <category>ecommerce</category>
    </item>
    <item>
      <title>Run UCP + ACP Validation in Your CI/CD Pipeline</title>
      <dc:creator>Peter</dc:creator>
      <pubDate>Fri, 10 Jul 2026 05:26:39 +0000</pubDate>
      <link>https://dev.to/ucptools/run-ucp-acp-validation-in-your-cicd-pipeline-590d</link>
      <guid>https://dev.to/ucptools/run-ucp-acp-validation-in-your-cicd-pipeline-590d</guid>
      <description>&lt;p&gt;You deploy a change to your storefront. The JSON still parses. The linter is happy. Tests pass.&lt;/p&gt;

&lt;p&gt;Two weeks later you notice AI agents have been silently skipping your store, because a capability schema endpoint started returning a 404 and nothing anywhere told you.&lt;/p&gt;

&lt;p&gt;This is the failure mode of agentic commerce readiness: it degrades quietly. There is no 500 page, no error rate spike, no angry customer email. Agents just move on to a merchant whose profile resolves.&lt;/p&gt;

&lt;p&gt;The fix is the same as for every other class of quality problem in software. Stop checking it by hand. Put it in CI.&lt;/p&gt;

&lt;h2&gt;
  
  
  What actually breaks
&lt;/h2&gt;

&lt;p&gt;UCP profiles are not simple documents. They carry namespace bindings, HTTPS requirements, signing keys, and extension chains that reference capabilities elsewhere in the file. A profile can be perfectly valid JSON and still be broken in ways that matter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;UCP_NS_ORIGIN_MISMATCH&lt;/code&gt; - your declared namespace does not match the origin serving it&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;UCP_ENDPOINT_NOT_HTTPS&lt;/code&gt; - agents require HTTPS, without exception&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;UCP_MISSING_SIGNING_KEYS&lt;/code&gt; - required before order and fulfillment capabilities will be trusted&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;UCP_SCHEMA_FETCH_FAILED&lt;/code&gt; - a capability schema URL returns an error&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;UCP_ORPHANED_EXTENSION&lt;/code&gt; - an extension points at a capability that no longer exists&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every one of these survives &lt;code&gt;JSON.parse()&lt;/code&gt;. Every one of these makes you invisible to some agent. And the last two are exactly the kind of thing a refactor breaks without touching the profile file at all, because the breakage lives at the other end of a URL.&lt;/p&gt;

&lt;p&gt;That is the argument for CI. Not "validate once at launch" - validate on every push, against the environment you are about to ship.&lt;/p&gt;

&lt;h2&gt;
  
  
  The GitHub Action
&lt;/h2&gt;

&lt;p&gt;If you are on GitHub, this is four lines of YAML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Nolpak14/ucp-validate-action@v1&lt;/span&gt;
  &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;domain&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;yourstore.com'&lt;/span&gt;
    &lt;span class="na"&gt;fail-on-grade&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;C'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The action runs four-level validation (structural, rules, network, SDK compliance) against the live domain and scores AI readiness. &lt;code&gt;fail-on-grade&lt;/code&gt; fails the build at that grade or worse; &lt;code&gt;fail-on-score&lt;/code&gt; does the same against a 0-100 number. Use whichever matches how your team talks about quality.&lt;/p&gt;

&lt;p&gt;It exposes &lt;code&gt;score&lt;/code&gt;, &lt;code&gt;grade&lt;/code&gt;, &lt;code&gt;ucp-found&lt;/code&gt;, &lt;code&gt;passed&lt;/code&gt;, and &lt;code&gt;result-json&lt;/code&gt; as outputs, so you can branch on the result rather than just pass or fail:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Nolpak14/ucp-validate-action@v1&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ucp&lt;/span&gt;
  &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;domain&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;yourstore.com'&lt;/span&gt;

&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;echo "UCP score&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ steps.ucp.outputs.score }}"&lt;/span&gt;

&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;steps.ucp.outputs.ucp-found == 'false'&lt;/span&gt;
  &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;echo "::warning::No UCP profile at /.well-known/ucp"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On pull requests it posts a comment with the score, a category breakdown, and any validation issues with their error codes, updating in place rather than piling up duplicates. Set &lt;code&gt;comment: 'false'&lt;/code&gt; if you would rather have step summaries only.&lt;/p&gt;

&lt;h2&gt;
  
  
  The pattern that actually pays: gate the deploy
&lt;/h2&gt;

&lt;p&gt;Validating on push is useful. Gating the deploy on it is what stops a broken profile reaching production:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;validate-ucp&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Nolpak14/ucp-validate-action@v1&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;domain&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;staging.yourstore.com'&lt;/span&gt;
          &lt;span class="na"&gt;fail-on-grade&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;C'&lt;/span&gt;

  &lt;span class="na"&gt;deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;needs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;validate-ucp&lt;/span&gt;   &lt;span class="c1"&gt;# deploy only runs if validation passed&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;echo "Deploying to production..."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Point it at staging. If staging's profile does not clear your bar, the &lt;code&gt;deploy&lt;/code&gt; job never runs. You catch the regression before customers see it, and before agents quietly reroute around you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Not on GitHub? Use the CLI
&lt;/h2&gt;

&lt;p&gt;The validator ships as an npm package, so it drops into any runner with Node.js 20+. It exits non-zero when validation fails, which is all a CI system needs.&lt;/p&gt;

&lt;p&gt;GitLab CI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;ucp-validation&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;node:20-alpine&lt;/span&gt;
  &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;npx -p @ucptools/validator ucp-validate validate --remote yourstore.com&lt;/span&gt;
  &lt;span class="na"&gt;rules&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;$CI_COMMIT_BRANCH == "main"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;CircleCI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;ucp-validation&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;docker&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cimg/node:20.11&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Validate UCP profile&lt;/span&gt;
          &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npx -p @ucptools/validator ucp-validate validate --remote yourstore.com&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or wire it into your test suite so it runs wherever your tests already run - Jenkins, Bitbucket Pipelines, a Makefile, a pre-commit hook:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save-dev&lt;/span&gt; @ucptools/validator
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"test:ucp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ucp-validate validate --remote yourstore.com"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also validate the file before it ever ships, which is faster and catches structural errors without a network round trip:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx &lt;span class="nt"&gt;-p&lt;/span&gt; @ucptools/validator ucp-validate validate &lt;span class="nt"&gt;--file&lt;/span&gt; ./public/.well-known/ucp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The other protocol: ACP readiness
&lt;/h2&gt;

&lt;p&gt;UCP is not the only spec agents care about. The Agentic Commerce Protocol - OpenAI and Stripe's standard, the one behind checkout inside ChatGPT - has its own readiness surface: platform detection, payment integration, policy endpoints, security posture.&lt;/p&gt;

&lt;p&gt;Worth being precise about how this runs, because it is different: &lt;strong&gt;the GitHub Action and the CLI check UCP.&lt;/strong&gt; ACP readiness is a public REST endpoint. No key, no install, so it works in any CI that has &lt;code&gt;curl&lt;/code&gt; and &lt;code&gt;jq&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-sX&lt;/span&gt; POST https://ucptools.dev/api/acp-check &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"domain":"yourstore.com"}'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; acp.json

&lt;span class="nv"&gt;SCORE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.score'&lt;/span&gt; acp.json&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;GRADE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.grade'&lt;/span&gt; acp.json&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"ACP readiness: &lt;/span&gt;&lt;span class="nv"&gt;$GRADE&lt;/span&gt;&lt;span class="s2"&gt; (&lt;/span&gt;&lt;span class="nv"&gt;$SCORE&lt;/span&gt;&lt;span class="s2"&gt;/100)"&lt;/span&gt;

&lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SCORE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-ge&lt;/span&gt; 70 &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.recommendations[]? | "[\(.priority)] \(.title) - \(.action)"'&lt;/span&gt; acp.json
  &lt;span class="nb"&gt;exit &lt;/span&gt;1
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One trap worth knowing: the endpoint answers &lt;code&gt;200 OK&lt;/code&gt; even when a domain fails, with &lt;code&gt;"ok": false&lt;/code&gt; in the body. A reflexive &lt;code&gt;curl --fail&lt;/code&gt; gate would pass every grade, including an F. Read &lt;code&gt;.score&lt;/code&gt; or &lt;code&gt;.grade&lt;/code&gt; from the response, not the HTTP status.&lt;/p&gt;

&lt;p&gt;The response also carries &lt;code&gt;score_breakdown&lt;/code&gt; across platform, payment, policies, and security, plus &lt;code&gt;recommendations&lt;/code&gt; as structured objects with &lt;code&gt;priority&lt;/code&gt;, &lt;code&gt;title&lt;/code&gt;, &lt;code&gt;description&lt;/code&gt;, and &lt;code&gt;action&lt;/code&gt; - which is why the snippet above prints something a developer can act on rather than a wall of JSON.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to set the bar
&lt;/h2&gt;

&lt;p&gt;Resist the urge to start at &lt;code&gt;fail-on-grade: 'A'&lt;/code&gt;. You will spend a week fighting your own pipeline and then disable the check, which is worse than never adding it.&lt;/p&gt;

&lt;p&gt;Start where you are. Run the validator once, take the grade it gives you, and set the threshold one notch below. Now the build fails only on regression, which is the thing you actually care about. Ratchet the bar upward as you fix the backlog. A gate that fires on real regressions and stays quiet otherwise is a gate people keep.&lt;/p&gt;

&lt;p&gt;For ACP, 70 is a reasonable opening threshold. For UCP, &lt;code&gt;fail-on-grade: 'C'&lt;/code&gt; catches the profile-level breakage without blocking on Schema.org polish.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Add the action, or the &lt;code&gt;npx&lt;/code&gt; one-liner, to a workflow you already run&lt;/li&gt;
&lt;li&gt;Point it at staging, not production&lt;/li&gt;
&lt;li&gt;Set a threshold one notch below your current grade&lt;/li&gt;
&lt;li&gt;Add the ACP curl step if you care about ChatGPT checkout&lt;/li&gt;
&lt;li&gt;Make the deploy job &lt;code&gt;needs:&lt;/code&gt; the validation job&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Copy-paste recipes for GitHub Actions, GitLab CI, CircleCI, npx, and the ACP endpoint live at &lt;a href="https://ucptools.dev/ci" rel="noopener noreferrer"&gt;ucptools.dev/ci&lt;/a&gt;. If you would rather call validation from your own code than from a CI step, the &lt;a href="https://ucptools.dev/api-docs" rel="noopener noreferrer"&gt;API and npm reference&lt;/a&gt; covers the public REST endpoints and the typed package.&lt;/p&gt;

&lt;p&gt;The point is not the score. The point is that a profile which silently stopped resolving should break your build, not your revenue.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;UCPtools is an independent community tool. UCP is an open standard by Google and Shopify; ACP is an open standard by OpenAI and Stripe. We are not affiliated with any of them.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>githubactions</category>
      <category>ecommerce</category>
      <category>webdev</category>
    </item>
    <item>
      <title>The Agentic Commerce Stack Is Complete - Here's Your July 2026 Implementation Checklist</title>
      <dc:creator>Peter</dc:creator>
      <pubDate>Mon, 06 Jul 2026 10:07:25 +0000</pubDate>
      <link>https://dev.to/ucptools/the-agentic-commerce-stack-is-complete-heres-your-july-2026-implementation-checklist-1f3l</link>
      <guid>https://dev.to/ucptools/the-agentic-commerce-stack-is-complete-heres-your-july-2026-implementation-checklist-1f3l</guid>
      <description>&lt;h1&gt;
  
  
  The Agentic Commerce Stack Is Complete - Here's Your July 2026 Implementation Checklist
&lt;/h1&gt;

&lt;p&gt;Three infrastructure changes in the last 30 days turned agentic commerce from a spec to a live channel:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Mastercard backed UCP.&lt;/strong&gt; Their Agent Pay network now runs on Google's Universal Commerce Protocol. The payment layer converged on the discovery layer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shopify shipped Agentic Storefronts in Summer '26 Editions.&lt;/strong&gt; Every Shopify merchant now has an AI shopping channel, active by default, manageable from the admin.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Google AI Mode is in production.&lt;/strong&gt; Gemini browses stores via UCP. ChatGPT shops through Shopify's agentic storefronts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The stack is live: &lt;strong&gt;Discovery&lt;/strong&gt; (Google AI Mode, Gemini, ChatGPT) + &lt;strong&gt;Storefront&lt;/strong&gt; (Shopify, BigCommerce) + &lt;strong&gt;Payment&lt;/strong&gt; (Mastercard Agent Pay, Visa Intelligent Commerce, Adyen Agentic).&lt;/p&gt;

&lt;p&gt;If your store doesn't have a valid UCP profile, you are invisible to every layer. Not "less visible." Invisible. The agents read protocols, not websites.&lt;/p&gt;

&lt;p&gt;Here's the 5-item checklist to fix that. Each step takes 10-30 minutes.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Validate at All 4 Levels
&lt;/h2&gt;

&lt;p&gt;A structural JSON check tells you the manifest parses. It doesn't tell you whether an AI agent can actually shop.&lt;/p&gt;

&lt;p&gt;You need all four:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Structural&lt;/strong&gt; - valid JSON, required fields, schema compliance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rules&lt;/strong&gt; - capability consistency, namespace/origin match, business logic&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network&lt;/strong&gt; - HTTPS on all endpoints, live response codes, reachability&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SDK/Simulation&lt;/strong&gt; - end-to-end agent interaction (browse, cart, checkout, pay)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most free checkers stop at Level 1. The failures that make your store invisible live at Levels 3 and 4.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ucptools.dev/validator?utm_source=devto&amp;amp;utm_medium=referral&amp;amp;utm_campaign=stack-checklist-202607" rel="noopener noreferrer"&gt;Run a free 4-level validation&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Run the AI Agent Simulator
&lt;/h2&gt;

&lt;p&gt;Validation says your manifest is correct. Simulation says whether an agent can actually use it.&lt;/p&gt;

&lt;p&gt;The simulator sends real agent-style requests: browse catalog, add to cart, initiate checkout. Failures it catches that validators miss:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Payment handlers declared but unreachable (302 redirect, CORS block)&lt;/li&gt;
&lt;li&gt;Identity Linking endpoints that return 200 but fail cross-domain&lt;/li&gt;
&lt;li&gt;Cart where add works but remove doesn't&lt;/li&gt;
&lt;li&gt;Signing keys present but cryptographically invalid&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://ucptools.dev/tools/simulator?utm_source=devto&amp;amp;utm_medium=referral&amp;amp;utm_campaign=stack-checklist-202607" rel="noopener noreferrer"&gt;Run the AI agent simulator&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Fix the Top 3 Failures
&lt;/h2&gt;

&lt;p&gt;Production scan data shows three issues cause most agent-visible failures:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Missing &lt;code&gt;signing_keys&lt;/code&gt;&lt;/strong&gt; - Without them, agents can't verify your manifest. They walk. This is the single most common failure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Namespace/origin mismatch&lt;/strong&gt; - Your manifest says &lt;code&gt;origin: "store.example.com"&lt;/code&gt; but the agent requested from &lt;code&gt;www.store.example.com&lt;/code&gt;. The agent sees a contradiction and aborts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Broken &lt;code&gt;payment_handlers&lt;/code&gt;&lt;/strong&gt; - The manifest declares checkout but doesn't tell agents what payment methods exist, or lists handlers that don't work. Cart fills, purchase fails.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Set Up Monitoring
&lt;/h2&gt;

&lt;p&gt;Your UCP profile will break. Not because you made a mistake - because infrastructure changes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;TLS certs rotate and the new CA isn't trusted&lt;/li&gt;
&lt;li&gt;Your platform ships an update that changes the manifest shape&lt;/li&gt;
&lt;li&gt;Payment gateway config drifts from what the manifest declares&lt;/li&gt;
&lt;li&gt;A caching plugin starts serving &lt;code&gt;/.well-known/ucp&lt;/code&gt; as &lt;code&gt;text/html&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When this happens, you won't get an error. You'll just stop appearing in AI shopping results. Silent, invisible failure.&lt;/p&gt;

&lt;p&gt;Monitoring re-validates on a schedule, compares to baseline, and alerts on regression. Same principle as uptime monitoring - but for AI agent discoverability.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ucptools.dev/tools/monitoring?utm_source=devto&amp;amp;utm_medium=referral&amp;amp;utm_campaign=stack-checklist-202607" rel="noopener noreferrer"&gt;Set up monitoring&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Test All Three Layers
&lt;/h2&gt;

&lt;p&gt;The stack works as a chain. Break any link and it fails:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Discovery&lt;/strong&gt; - Can Google AI Mode find your store? Search your products in AI Mode.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Storefront&lt;/strong&gt; - Is your Shopify Agentic Storefront active? Check admin under Sales Channels.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Payment&lt;/strong&gt; - Can Mastercard Agent Pay process a payment through your store? Test the handler endpoints.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Why This Matters
&lt;/h2&gt;

&lt;p&gt;Shopify reported 13x year-over-year growth in AI search orders &lt;em&gt;before&lt;/em&gt; Agentic Storefronts shipped. Cloudflare reports bots have surpassed human traffic. McKinsey projects up to $1T in US agentic commerce by 2030.&lt;/p&gt;

&lt;p&gt;The protocol war is effectively settled. UCP has the discovery layer, the storefront layer, and now the payment layer. Implementing it isn't a competitive advantage - it's table stakes.&lt;/p&gt;

&lt;p&gt;Five steps. One afternoon. The difference between being visible to the agentic commerce stack and being invisible to it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ucptools.dev?utm_source=devto&amp;amp;utm_medium=referral&amp;amp;utm_campaign=stack-checklist-202607" rel="noopener noreferrer"&gt;Start your free validation&lt;/a&gt; - no account required.&lt;/p&gt;

</description>
      <category>ucp</category>
      <category>ecommerce</category>
      <category>webdev</category>
      <category>ai</category>
    </item>
    <item>
      <title>Building a Dual-Protocol Checkout with Agorio SDK: Support UCP and ACP in Your AI Commerce Agent</title>
      <dc:creator>Peter</dc:creator>
      <pubDate>Fri, 26 Jun 2026 15:53:12 +0000</pubDate>
      <link>https://dev.to/ucptools/building-a-dual-protocol-checkout-with-agorio-sdk-support-ucp-and-acp-in-your-ai-commerce-agent-3ob7</link>
      <guid>https://dev.to/ucptools/building-a-dual-protocol-checkout-with-agorio-sdk-support-ucp-and-acp-in-your-ai-commerce-agent-3ob7</guid>
      <description>&lt;h1&gt;
  
  
  Building a Dual-Protocol Checkout with Agorio SDK: Support UCP and ACP in Your AI Commerce Agent
&lt;/h1&gt;

&lt;p&gt;The AI commerce landscape is rapidly standardizing around two open protocols: &lt;strong&gt;Google's Universal Commerce Protocol (UCP)&lt;/strong&gt; and &lt;strong&gt;OpenAI's Agentic Commerce Protocol (ACP)&lt;/strong&gt;. By holiday 2026, Visa and Mastercard will enable all US cardholders for agent transactions, while Shopify's 4.8M merchants are discoverable via UCP and Stripe's 1.5M merchants can accept ACP payments with one line of code.&lt;/p&gt;

&lt;p&gt;For developers building AI shopping agents, this creates a critical challenge: &lt;strong&gt;should you implement UCP, ACP, or both?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this step-by-step tutorial, you'll learn how to build a dual-protocol checkout system using the &lt;a href="https://agorio.dev?utm_source=devto&amp;amp;utm_medium=tutorial&amp;amp;utm_campaign=202606" rel="noopener noreferrer"&gt;Agorio SDK&lt;/a&gt; — the only open-source toolkit that supports both UCP and ACP with auto-detection. We'll walk through setting up a TypeScript project, discovering merchants via UCP, managing checkout sessions via ACP, and assembling a full-featured shopping agent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Dual-Protocol Support Matters
&lt;/h2&gt;

&lt;p&gt;UCP and ACP solve different problems:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Protocol&lt;/th&gt;
&lt;th&gt;Lead Developers&lt;/th&gt;
&lt;th&gt;Primary Use Case&lt;/th&gt;
&lt;th&gt;Discovery Method&lt;/th&gt;
&lt;th&gt;Payment Model&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;UCP&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Google, Shopify, 25+ partners&lt;/td&gt;
&lt;td&gt;Full commerce lifecycle (discovery, cart, checkout, order tracking)&lt;/td&gt;
&lt;td&gt;Decentralized (&lt;code&gt;/.well-known/ucp&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Multiple handlers (Google Pay, Shop Pay, tokenization)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;ACP&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;OpenAI, Stripe&lt;/td&gt;
&lt;td&gt;Checkout-focused, delegated payment&lt;/td&gt;
&lt;td&gt;Centralized (merchant application)&lt;/td&gt;
&lt;td&gt;Any PSP via delegated payment (Stripe first)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Merchants are adopting both. If your agent only supports one protocol, you'll miss transactions on the other. The smart solution: &lt;strong&gt;support both, but avoid writing twice the code&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Agorio Provides
&lt;/h2&gt;

&lt;p&gt;Agorio abstracts the protocol differences behind a unified API:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;UcpClient&lt;/code&gt;&lt;/strong&gt; – Discovers merchants via &lt;code&gt;/.well-known/ucp&lt;/code&gt;, normalizes capability formats, handles REST/MCP/A2A transports.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;AcpClient&lt;/code&gt;&lt;/strong&gt; – Manages ACP checkout sessions (create, get, update, complete, cancel) with Bearer auth and request tracing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;ShoppingAgent&lt;/code&gt;&lt;/strong&gt; – 17 built‑in tools that work across both protocols via automatic detection.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;MockMerchant&lt;/code&gt;&lt;/strong&gt; – A full UCP‑compliant test server, plus ACP‑only and MCP‑only variants.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LLM adapters&lt;/strong&gt; – Gemini, Claude, OpenAI, Ollama — swap without changing your agent logic.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With Agorio, you write commerce logic once; the SDK adapts to the merchant's supported protocol.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Project Setup
&lt;/h2&gt;

&lt;p&gt;Start a new TypeScript project and install Agorio:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm init &lt;span class="nt"&gt;-y&lt;/span&gt;
npm &lt;span class="nb"&gt;install &lt;/span&gt;typescript ts-node @types/node &lt;span class="nt"&gt;--save-dev&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; @agorio/sdk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a &lt;code&gt;tsconfig.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"compilerOptions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"target"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ES2022"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"module"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"NodeNext"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"moduleResolution"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"NodeNext"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"esModuleInterop"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"outDir"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./dist"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"strict"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2: Discover a Merchant via UCP
&lt;/h2&gt;

&lt;p&gt;First, let's discover a merchant's capabilities using the &lt;code&gt;UcpClient&lt;/code&gt;. The client automatically fetches the &lt;code&gt;/.well-known/ucp&lt;/code&gt; manifest and normalizes the capability format.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;UcpClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@agorio/sdk&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;UcpClient&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;discoverMerchant&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;discover&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Merchant &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; supports:`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;capabilities&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cap&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`  - &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;cap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; (&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;cap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;version&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;)`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Discovery failed:`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Example: discover a UCP-enabled merchant&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;discoverMerchant&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;shop.example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;result&lt;/code&gt; object contains normalized services, payment handlers, and transport bindings. You can now invoke any UCP capability (catalog, cart, checkout) using the client's REST or MCP transport.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Create an ACP Checkout Session
&lt;/h2&gt;

&lt;p&gt;For merchants that support ACP (like Stripe‑enabled stores), you'll manage checkout sessions via the &lt;code&gt;AcpClient&lt;/code&gt;. ACP uses delegated payment: the user's payment method stays with their PSP (Stripe, PayPal), and the agent acts as an operator.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AcpClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@agorio/sdk&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;acp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AcpClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;baseUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.stripe.com/acp/v1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Replace with merchant's ACP endpoint&lt;/span&gt;
  &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;STRIPE_API_KEY&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;createAcpCheckout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;productId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;acp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createCheckout&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;lineItems&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
      &lt;span class="nx"&gt;productId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2999&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// $29.99 in minor units (cents)&lt;/span&gt;
        &lt;span class="na"&gt;currency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;USD&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}],&lt;/span&gt;
    &lt;span class="na"&gt;merchantDomain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;shop.example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`ACP checkout session &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; created`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Status: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// "not_ready_for_payment"&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;session&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;createAcpCheckout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;prod_123&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SB_1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;AcpClient&lt;/code&gt; handles all required headers (Authorization, API‑Version, Idempotency‑Key, Request‑Id) and validates responses against the ACP schema.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Build a Dual-Protocol Shopping Agent
&lt;/h2&gt;

&lt;p&gt;Now combine both clients into a single &lt;code&gt;ShoppingAgent&lt;/code&gt;. The agent automatically detects whether a merchant speaks UCP or ACP and uses the appropriate client.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ShoppingAgent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;GeminiAdapter&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@agorio/sdk&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ShoppingAgent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;GeminiAdapter&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;GEMINI_API_KEY&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="na"&gt;verbose&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="c1"&gt;// ShoppingAgent automatically instantiates UcpClient and AcpClient&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;runShoppingTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;answer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;           &lt;span class="c1"&gt;// Natural language summary&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;checkout&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;orderId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Order ID if purchase completed&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;usage&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;totalTokens&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// LLM token usage&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// This single command works for both UCP and ACP merchants:&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;runShoppingTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Go to shop.example.com and buy wireless headphones&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent's 17 built‑in tools handle the entire flow: merchant discovery, product search, adding to cart, submitting shipping and payment, and order tracking. You can extend with custom tools via plugins.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Test with Mock Merchants
&lt;/h2&gt;

&lt;p&gt;Before hitting real merchants, test with Agorio's mock servers. &lt;code&gt;MockMerchant&lt;/code&gt; provides a full UCP‑compliant server; &lt;code&gt;MockAcpMerchant&lt;/code&gt; provides an ACP‑only server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;MockMerchant&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;MockAcpMerchant&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@agorio/sdk&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Start a UCP merchant&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ucpMerchant&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;MockMerchant&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ucpMerchant&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`UCP mock merchant running at &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;ucpMerchant&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Start an ACP merchant&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;acpMerchant&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;MockAcpMerchant&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;acpMerchant&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`ACP mock merchant running at &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;acpMerchant&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Test your agent against the mock&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Go to &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;ucpMerchant&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; and buy a laptop`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Order placed:`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;checkout&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;orderId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Clean up&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ucpMerchant&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stop&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;acpMerchant&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stop&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both mocks simulate realistic latency, support configurable error rates for chaos testing, and provide structured product catalogs (10 products by default).&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6: Deployment Considerations
&lt;/h2&gt;

&lt;p&gt;When moving to production, keep these points in mind:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;LLM cost control&lt;/strong&gt; – Set &lt;code&gt;maxIterations&lt;/code&gt; in &lt;code&gt;AgentOptions&lt;/code&gt; to limit agent loops.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Observability&lt;/strong&gt; – Use the &lt;code&gt;onLog&lt;/code&gt; callback to stream logs to your monitoring system, or integrate with Agorio Cloud for full tracing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Session storage&lt;/strong&gt; – Swap &lt;code&gt;MemorySessionStorage&lt;/code&gt; for &lt;code&gt;FileSessionStorage&lt;/code&gt; or &lt;code&gt;@agorio/session-redis&lt;/code&gt; in multi‑process deployments.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Idempotency&lt;/strong&gt; – Always pass &lt;code&gt;idempotencyKey&lt;/code&gt; on &lt;code&gt;completeCheckout&lt;/code&gt; to prevent duplicate charges.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compliance&lt;/strong&gt; – If you handle EU users, enable the built‑in EU AI Act compliance export (&lt;code&gt;GET /api/compliance/export&lt;/code&gt;).&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion: Why Agorio is the Right Choice
&lt;/h2&gt;

&lt;p&gt;Building dual‑protocol AI commerce agents from scratch requires deep knowledge of both UCP and ACP specs, plus months of implementation work. Agorio gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Protocol agnosticism&lt;/strong&gt; – Write once, run on UCP, ACP, or both.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Production‑ready tooling&lt;/strong&gt; – Mock merchants, LLM adapters, observability, CLI.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enterprise hardening&lt;/strong&gt; – RBAC, audit logs, compliance exports, security posture.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The SDK is open‑source (MIT), has zero runtime fees, and already powers agents handling real purchases.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Get started today:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;npm&lt;/strong&gt;: &lt;code&gt;npm install @agorio/sdk&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/Nolpak14/agorio?utm_source=devto&amp;amp;utm_medium=tutorial&amp;amp;utm_campaign=202606" rel="noopener noreferrer"&gt;github.com/Nolpak14/agorio&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Docs&lt;/strong&gt;: &lt;a href="https://agorio.dev/docs?utm_source=devto&amp;amp;utm_medium=tutorial&amp;amp;utm_campaign=202606" rel="noopener noreferrer"&gt;agorio.dev/docs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Playground&lt;/strong&gt;: &lt;a href="https://agorio.dev/playground?utm_source=devto&amp;amp;utm_medium=tutorial&amp;amp;utm_campaign=202606" rel="noopener noreferrer"&gt;agorio.dev/playground&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're building AI commerce agents, join the 10+ GitHub stars and 46+ weekly npm downloaders who've chosen Agorio as their foundation. Ship your agent in 20 lines, not 20 weeks.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>typescript</category>
      <category>commerce</category>
      <category>ecommerce</category>
    </item>
    <item>
      <title>We Tracked Every AI Agent That Visited Our Site. 5 Different Agents Found Us This Month.</title>
      <dc:creator>Peter</dc:creator>
      <pubDate>Mon, 22 Jun 2026 10:04:50 +0000</pubDate>
      <link>https://dev.to/ucptools/we-tracked-every-ai-agent-that-visited-our-site-5-different-agents-found-us-this-month-544d</link>
      <guid>https://dev.to/ucptools/we-tracked-every-ai-agent-that-visited-our-site-5-different-agents-found-us-this-month-544d</guid>
      <description>&lt;h1&gt;
  
  
  We Tracked Every AI Agent That Visited Our Site. 5 Different Agents Found Us This Month.
&lt;/h1&gt;

&lt;p&gt;Three weeks ago, I noticed something strange in our referrer logs.&lt;/p&gt;

&lt;p&gt;A user from &lt;code&gt;chatgpt.com&lt;/code&gt; had landed on our validator page, browsed our documentation, and — crucially — triggered tool events. Not a human clicking around. An AI agent. ChatGPT had crawled our site, loaded our tool, and used it.&lt;/p&gt;

&lt;p&gt;That was one agent. One week. A curiosity.&lt;/p&gt;

&lt;p&gt;This week: &lt;strong&gt;five.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What showed up (and what they did)
&lt;/h2&gt;

&lt;p&gt;The full lineup of AI agents that visited ucptools.dev in the last month:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ChatGPT (chatgpt.com)&lt;/strong&gt; — 4 visits this week alone. Most active of the bunch. Browsed documentation pages and the free UCP validator. Triggered actual tool events — someone asked ChatGPT about UCP validation, and it came to us to answer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gemini (gemini.google.com)&lt;/strong&gt; — 1 visit this week. First time we've seen Gemini in our logs. Shorter session than ChatGPT, but it hit the same pages: validator, compare page, docs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Perplexity (perplexity.ai)&lt;/strong&gt; — First spotted in May. Here's the wild part: every Perplexity-referred session in May resulted in a tool user. 100% conversion rate. Someone asked Perplexity "how do I validate my UCP profile?" and Perplexity sent them straight to our tool, already knowing what to do.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Claude (claude.ai)&lt;/strong&gt; — Returned June 14 after a multi-week gap. Browsed our UCP protocol documentation and the agent simulator page. Not using tools yet — but it's building a map.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NotebookLM (notebooklm.google.com)&lt;/strong&gt; — Newcomer. Discovered us June 7. Google's research assistant found our site and ingested content. We don't know what question triggered it, but something in our content matched a user's research query.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Trend line: 1 → 1 → 5.&lt;/strong&gt; Not a spike. A ramp.&lt;/p&gt;




&lt;h2&gt;
  
  
  This isn't about SEO as you know it
&lt;/h2&gt;

&lt;p&gt;If you work in developer tools or e-commerce infrastructure, you've probably spent the last 6 months hearing about UCP, ACP, AI shopping agents, and "agentic commerce readiness." The conversation has been about protocols — can an AI agent parse your UCP manifest? Can it call your payment handlers? Can it add items to a cart?&lt;/p&gt;

&lt;p&gt;That's the protocol layer. And it matters.&lt;/p&gt;

&lt;p&gt;But here's what the referral data shows: &lt;strong&gt;AI agents are indexing your entire web presence, not just your UCP endpoint.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When ChatGPT crawled our validator tool, it wasn't reading a &lt;code&gt;.well-known/ucp&lt;/code&gt; manifest. It was reading our documentation, our compare page, our blog posts. It was building a knowledge graph of "what tool exists for checking UCP profiles" that it can retrieve when a user asks.&lt;/p&gt;

&lt;p&gt;When Perplexity sent us a user with a 100% tool completion rate, it had already decided — before the human ever saw our site — that UCPtools was the right answer to their question.&lt;/p&gt;

&lt;p&gt;This is a new kind of discoverability. Not search ranking. &lt;strong&gt;Knowledge base ranking.&lt;/strong&gt; The question isn't "do I rank #1 for 'UCP validator'?" — it's "when an AI agent needs to answer a UCP question, does it know I exist?"&lt;/p&gt;




&lt;h2&gt;
  
  
  What this means for developer tools and e-commerce platforms
&lt;/h2&gt;

&lt;p&gt;Five different agents found us without us doing anything to attract them. No agent-specific SEO. No structured data markup for AI crawlers. Just a website with clear, specific content about a niche protocol.&lt;/p&gt;

&lt;p&gt;The implication: &lt;strong&gt;AI agents are actively hunting for authoritative sources in specialized domains.&lt;/strong&gt; If you build something in the UCP/ACP/agentic commerce space, the agents will find you — but only if your content is in their corpus.&lt;/p&gt;

&lt;p&gt;Three patterns we can already see:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Agents prefer documentation over marketing.&lt;/strong&gt; Every agent that visited us hit our docs and tools. None touched our pricing page. None visited our blog homepage. They went straight for substance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Tool usage is the strongest signal.&lt;/strong&gt; Perplexity's 100% tool-user rate tells us the agent pre-qualified the user — it already knew our tool was the answer. The human didn't browse; they executed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Multi-agent coverage compounds.&lt;/strong&gt; One agent finding you is luck. Five agents finding you means your content is propagating across knowledge bases. ChatGPT, Gemini, Perplexity, Claude, and NotebookLM use different indexes and different retrieval strategies. If you're in all five, you're discoverable regardless of which agent a user chooses.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  The protocol layer matters too — here's how they connect
&lt;/h2&gt;

&lt;p&gt;We built UCPtools to validate UCP profiles. The core insight was: an AI shopping agent needs a valid UCP manifest to buy from your store. But the protocol layer and the knowledge layer are connected in ways that aren't obvious yet.&lt;/p&gt;

&lt;p&gt;Consider this sequence:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A developer asks ChatGPT: "How do I set up UCP for my Shopify store?"&lt;/li&gt;
&lt;li&gt;ChatGPT searches its knowledge base, finds our documentation (because we're in its corpus), and recommends our validator.&lt;/li&gt;
&lt;li&gt;The developer uses the free validator, finds 3 broken endpoints, and fixes them.&lt;/li&gt;
&lt;li&gt;Now their store is both &lt;strong&gt;UCP-valid&lt;/strong&gt; (protocol layer) AND &lt;strong&gt;indexed by the agents that will send them customers&lt;/strong&gt; (knowledge layer).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Without step 2, the developer might never find the validator. Without step 3, their UCP profile stays broken and AI shopping agents can't transact.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You need both.&lt;/strong&gt; A valid UCP profile that no AI agent knows about is useless. And an AI agent that knows about your store but can't transact because your payment handlers are broken is equally useless.&lt;/p&gt;




&lt;h2&gt;
  
  
  How to check if AI agents can find you (and transact with you)
&lt;/h2&gt;

&lt;p&gt;There's no all-in-one dashboard for this yet. But here's what you can do right now:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Check your referrer logs&lt;/strong&gt; for these domains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;chatgpt.com&lt;/code&gt; / &lt;code&gt;chat.openai.com&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gemini.google.com&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;perplexity.ai&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;claude.ai&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;notebooklm.google.com&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you see any of them, AI agents are already building knowledge about your site.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Check your UCP profile&lt;/strong&gt; — because being discoverable is pointless if agents can't transact. Our free validator runs 4 levels of checks: structural, rules, network, and an AI agent simulator that actually tests whether an agent can complete a purchase flow.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ucptools.dev/?utm_source=devto&amp;amp;utm_medium=referral&amp;amp;utm_campaign=ai-agent-traffic-202606" rel="noopener noreferrer"&gt;Run the free UCP validator →&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Check your robots.txt.&lt;/strong&gt; Most AI crawlers respect &lt;code&gt;robots.txt&lt;/code&gt;. If you're blocking &lt;code&gt;GPTBot&lt;/code&gt;, &lt;code&gt;ClaudeBot&lt;/code&gt;, or &lt;code&gt;Google-Extended&lt;/code&gt;, you're opting out of AI discoverability. That might be intentional — but it's worth knowing what you're blocking.&lt;/p&gt;




&lt;h2&gt;
  
  
  One thing I'm still figuring out
&lt;/h2&gt;

&lt;p&gt;The data is real but the sample is small. Five agents, a handful of visits, one site. This isn't a research paper — it's an observation from our referrer logs that I think matters for anyone building in this space.&lt;/p&gt;

&lt;p&gt;What I don't know yet:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How frequently agents re-crawl and refresh their knowledge&lt;/li&gt;
&lt;li&gt;Whether agent referral traffic converts differently than organic search&lt;/li&gt;
&lt;li&gt;Whether NotebookLM ingestion leads to downstream discoverability in other Google products&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're seeing AI agents in your own referrer logs, I'd love to compare notes. Drop a comment — especially if you're seeing patterns I haven't mentioned.&lt;/p&gt;

&lt;p&gt;The one thing I'm confident about: &lt;strong&gt;the agents are here, they're indexing, and they're already making decisions about which tools and services to recommend.&lt;/strong&gt; The question isn't whether to care about AI discoverability. It's whether you're already invisible.&lt;/p&gt;

</description>
      <category>ucp</category>
      <category>ai</category>
      <category>webdev</category>
      <category>ecommerce</category>
    </item>
    <item>
      <title>Google's Universal Cart Is Live. Here's the Checklist to Make Sure Agents Can Actually Check Out on Your Store</title>
      <dc:creator>Peter</dc:creator>
      <pubDate>Sat, 13 Jun 2026 13:35:37 +0000</pubDate>
      <link>https://dev.to/ucptools/googles-universal-cart-is-live-heres-the-checklist-to-make-sure-agents-can-actually-check-out-on-2n80</link>
      <guid>https://dev.to/ucptools/googles-universal-cart-is-live-heres-the-checklist-to-make-sure-agents-can-actually-check-out-on-2n80</guid>
      <description>&lt;p&gt;At Google Marketing Live on May 20, 2026, Universal Cart stopped being a demo. Google announced that shoppers can now save products across retailers and check out - with Google Pay or the retailer's own flow - directly inside Search, AI Mode, the Gemini app, and YouTube shopping ads. The launch list is not a pilot: Nike, Sephora, Target, Walmart, Wayfair, and Shopify merchants like Fenty and Steve Madden, with Affirm and Klarna wired in for financing and hotels and food delivery slated next.&lt;/p&gt;

&lt;p&gt;The plumbing under all of it is UCP (Universal Commerce Protocol) - the open standard that gives an AI agent a machine-readable entry point to a store at &lt;code&gt;/.well-known/ucp&lt;/code&gt;. &lt;em&gt;(Quick disclaimer: UCP is owned and maintained by Google and Shopify. UCPtools, which I work on, is an independent community tool - not affiliated with either.)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Here is the part that matters for everyone not named in that launch list: the agent decides in milliseconds whether your store can transact. There is no "almost." Either your UCP profile answers the questions the agent asks, or the agent moves on to a merchant whose profile does. No bounce shows up in your analytics. You just quietly stop existing in the one shopping surface that is about to matter most.&lt;/p&gt;

&lt;p&gt;So this is the readiness checklist. It maps to the four things a validator actually checks, in the order an agent hits them.&lt;/p&gt;




&lt;h2&gt;
  
  
  Level 1: Structure - does the profile parse at all?
&lt;/h2&gt;

&lt;p&gt;Before anything semantic, the profile has to be a well-formed UCP document served correctly. This is where most "it's there but it doesn't work" failures live.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] &lt;code&gt;/.well-known/ucp&lt;/code&gt; returns &lt;code&gt;200&lt;/code&gt; with &lt;code&gt;Content-Type: application/json&lt;/code&gt; - not &lt;code&gt;text/html&lt;/code&gt;, not a redirect to a marketing page.&lt;/li&gt;
&lt;li&gt;[ ] The root &lt;code&gt;ucp&lt;/code&gt; object exists. Missing it is &lt;code&gt;UCP_MISSING_ROOT&lt;/code&gt; and the agent has nothing to read.&lt;/li&gt;
&lt;li&gt;[ ] A &lt;code&gt;version&lt;/code&gt; field is present and formatted &lt;code&gt;YYYY-MM-DD&lt;/code&gt;. A stray semver string trips &lt;code&gt;UCP_INVALID_VERSION_FORMAT&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;[ ] The JSON is valid - no trailing commas, no CDN error page wrapped around it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sounds trivial. It is the single most common break, because the file is served by a platform or a CDN that nobody is watching, and a caching plugin or a security challenge can turn a clean profile into an HTML error page overnight.&lt;/p&gt;




&lt;h2&gt;
  
  
  Level 2: Rules - is it actually UCP-compliant?
&lt;/h2&gt;

&lt;p&gt;A parseable profile can still be semantically wrong in ways that make an agent distrust it. Level 2 is the UCP compliance layer.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] &lt;strong&gt;Namespace and origin match.&lt;/strong&gt; The namespace your capabilities declare has to bind to the origin serving the profile. A mismatch is &lt;code&gt;UCP_NS_ORIGIN_MISMATCH&lt;/code&gt; - a classic copy-paste-from-staging bug.&lt;/li&gt;
&lt;li&gt;[ ] &lt;strong&gt;Every endpoint is HTTPS, no trailing slash.&lt;/strong&gt; &lt;code&gt;UCP_ENDPOINT_NOT_HTTPS&lt;/code&gt; and &lt;code&gt;UCP_ENDPOINT_TRAILING_SLASH&lt;/code&gt; are both hard stops; agents will not POST a payment intent over &lt;code&gt;http://&lt;/code&gt; or to a sloppy URL.&lt;/li&gt;
&lt;li&gt;[ ] &lt;strong&gt;No orphaned extensions.&lt;/strong&gt; Every extension has to chain back to a capability that declares it. A dangling one is &lt;code&gt;UCP_ORPHANED_EXTENSION&lt;/code&gt; and signals a profile that was hand-edited and never re-validated.&lt;/li&gt;
&lt;li&gt;[ ] &lt;strong&gt;Signing keys are present.&lt;/strong&gt; &lt;code&gt;UCP_MISSING_SIGNING_KEYS&lt;/code&gt; is the one that quietly kills checkout: without published keys, the agent cannot verify that the offer and the payment handler are really yours. It will browse and then refuse to transact.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That last one is the difference between showing up in Universal Cart's discovery layer and actually completing a purchase in it. Discovery without signing keys gets you window-shopped, not bought.&lt;/p&gt;




&lt;h2&gt;
  
  
  Level 3: Network - do your references actually resolve?
&lt;/h2&gt;

&lt;p&gt;Your profile points outward - to capability schemas and handler endpoints. Level 3 fetches them, the way an agent would, from outside your network.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Every referenced capability schema is reachable and self-describing. A schema host that 404s or times out is &lt;code&gt;UCP_SCHEMA_FETCH_FAILED&lt;/code&gt;, and it is &lt;em&gt;someone else's outage becoming your broken profile&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;[ ] Handler endpoints respond from the public internet, not just from inside your VPC. A check that runs on your own infra can hit a warm cache and report healthy while real agents get a connection error.&lt;/li&gt;
&lt;li&gt;[ ] TLS is valid across every edge, not just your origin. Certs renew and propagate unevenly; one stale CDN edge is enough to fail the agent that lands on it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You cannot fully test Level 3 from a unit test, because the failures are environmental and external. This is the level that needs to be checked against your &lt;em&gt;live&lt;/em&gt; domain, from outside.&lt;/p&gt;




&lt;h2&gt;
  
  
  Level 4: SDK - does it pass the official compliance pass?
&lt;/h2&gt;

&lt;p&gt;The top level runs your profile through &lt;code&gt;@ucp-js/sdk&lt;/code&gt;, the official UCP compliance kit. This is the closest a check gets to "would Google's own agent accept this?" - the same library the ecosystem builds against, applied to your live profile. Passing Levels 1 through 3 and failing here usually means a subtle shape mismatch the schema rules did not catch. If you only automate one gate, make it this one, because it is the one that tracks the spec as it evolves.&lt;/p&gt;




&lt;h2&gt;
  
  
  Run the whole checklist in one call
&lt;/h2&gt;

&lt;p&gt;You do not have to eyeball any of this. UCPtools exposes a remote endpoint that fetches your live profile and runs all four levels server-side, the way an agent sees it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-sS&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://ucptools.dev/v1/profiles/validate-remote &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"domain":"mystore.com"}'&lt;/span&gt; | jq
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ok"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"profile_url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://mystore.com/.well-known/ucp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"score"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;72&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"grade"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"C"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"issues"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"severity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"UCP_MISSING_SIGNING_KEYS"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"$.ucp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"No signing keys published"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"hint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Publish your Ed25519/ES256 public keys so agents can verify offers."&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"validated_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-06-13T10:00:00Z"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wire that same check into CI with the &lt;a href="https://github.com/Nolpak14/ucp-validate-action" rel="noopener noreferrer"&gt;&lt;code&gt;ucp-validate-action&lt;/code&gt;&lt;/a&gt; so a regression fails the build before it ships:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Nolpak14/ucp-validate-action@v1&lt;/span&gt;
  &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;domain&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;mystore.com'&lt;/span&gt;
    &lt;span class="na"&gt;min-score&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;90&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Where each stack tends to break
&lt;/h2&gt;

&lt;p&gt;The checklist is platform-agnostic - it reads the open standard, not platform internals - but the failure that actually bites you tends to cluster by stack:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Shopify:&lt;/strong&gt; you are largely along for the ride on what the platform serves at the well-known path, which is good until a platform change shifts the manifest shape under you. Validate after every theme or app change, because you do not control that surface directly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WooCommerce:&lt;/strong&gt; the usual culprit is a caching or security plugin that starts serving &lt;code&gt;/.well-known/ucp&lt;/code&gt; from cache, behind a challenge, or as &lt;code&gt;text/html&lt;/code&gt;. That is a Level 1 break (&lt;code&gt;Content-Type&lt;/code&gt;) hiding behind a green admin dashboard.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;BigCommerce / headless:&lt;/strong&gt; a frontend deploy moves a handler endpoint the profile still advertises, and Level 3 starts failing while the storefront looks perfect to a human. Storefront-scope mismatches show up here too.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom / self-hosted:&lt;/strong&gt; signing-key drift. The key rotates in your infra but not in the published profile, and &lt;code&gt;UCP_MISSING_SIGNING_KEYS&lt;/code&gt; or a verification failure silently downgrades you from "can transact" to "can only be browsed."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In every case the break is invisible to a human visitor and only shows up when something fetches the live profile from outside and runs the checks. That is the entire argument for validating continuously instead of once.&lt;/p&gt;

&lt;h2&gt;
  
  
  The thing the launch list quietly proves
&lt;/h2&gt;

&lt;p&gt;The brands Google named did not get into Universal Cart by accident. Someone on each of those teams treated the UCP profile as production infrastructure - versioned, validated, and monitored - not as a one-time SEO chore. That is the whole gap. The standard is open and the endpoint is a static file; nothing stops a mid-sized Shopify or WooCommerce store from being exactly as agent-ready as Nike. What stops most of them is that nobody ever validated past "the file exists."&lt;/p&gt;

&lt;p&gt;Universal Cart going live is the forcing function. Agents are transacting now, in surfaces real shoppers already use every day. Run the checklist against your store - &lt;a href="https://ucptools.dev" rel="noopener noreferrer"&gt;validate it free at ucptools.dev&lt;/a&gt; - and if it passes, set up monitoring so it &lt;em&gt;stays&lt;/em&gt; passing at 3am when a cert renews and no one shipped a thing. The merchants who win this transition treat their UCP profile like uptime, because for agentic checkout, that is exactly what it is.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;UCP is an open standard by Google and Shopify. UCPtools is an independent community tool.&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Built by Peter at &lt;a href="https://ucptools.dev" rel="noopener noreferrer"&gt;UCPtools&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ecommerce</category>
      <category>ai</category>
      <category>webdev</category>
      <category>googlecloud</category>
    </item>
    <item>
      <title>UCP vs ACP: The Battle of AI Commerce Protocols and How to Build for Both</title>
      <dc:creator>Peter</dc:creator>
      <pubDate>Thu, 11 Jun 2026 18:49:04 +0000</pubDate>
      <link>https://dev.to/ucptools/ucp-vs-acp-the-battle-of-ai-commerce-protocols-and-how-to-build-for-both-18ao</link>
      <guid>https://dev.to/ucptools/ucp-vs-acp-the-battle-of-ai-commerce-protocols-and-how-to-build-for-both-18ao</guid>
      <description>&lt;p&gt;The AI commerce agent landscape exploded in early 2026 when both Google's &lt;strong&gt;Universal Commerce Protocol (UCP)&lt;/strong&gt; and OpenAI's &lt;strong&gt;Agentic Commerce Protocol (ACP)&lt;/strong&gt; launched within weeks of each other. If you're building an AI shopping agent, you now face a critical choice: which protocol should you implement? Or should you support both?&lt;/p&gt;

&lt;p&gt;In this deep-dive, we'll compare UCP and ACP from an implementer's perspective, examine their architectural trade-offs, and show you how to get started with &lt;strong&gt;Agorio&lt;/strong&gt; - the only open-source SDK that implements both with automatic detection.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Rise of Agentic Commerce
&lt;/h2&gt;

&lt;p&gt;AI agents that can shop on your behalf are no longer science fiction. With 4.8M Shopify merchants discoverable via UCP and 1.5M Stripe merchants ready for ACP, the infrastructure for autonomous commerce is already in place. Visa and Mastercard are enabling all US cardholders for agent transactions by holiday 2026.&lt;/p&gt;

&lt;p&gt;But to tap into this ecosystem, your agent needs to speak the right protocol. Let's look at the two contenders.&lt;/p&gt;

&lt;h2&gt;
  
  
  UCP: Google &amp;amp; Shopify's Decentralized Approach
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;Universal Commerce Protocol&lt;/strong&gt; is an open standard co-developed by Google, Shopify, Etsy, Wayfair, Target, Walmart and endorsed by Stripe, PayPal, Visa, Mastercard.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Architecture
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Discovery&lt;/strong&gt;: Merchants publish a JSON manifest at &lt;code&gt;/.well-known/ucp&lt;/code&gt; that tells agents what they support - capabilities, endpoints, payment handlers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Capabilities&lt;/strong&gt;: Modular capabilities like &lt;code&gt;dev.ucp.shopping.checkout&lt;/code&gt; (cart, tax, session handling), &lt;code&gt;dev.ucp.shopping.order&lt;/code&gt; (post-purchase), and extensions for fulfillment, discounts, buyer consent.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Payment Architecture&lt;/strong&gt;: The "trust triangle" separates business, payment credential provider, and platform. Multiple handler types: Google Pay, Shop Pay, Direct Tokenization, AP2 (autonomous agent mandates).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transport Bindings&lt;/strong&gt;: REST (OpenAPI), MCP (OpenRPC for LLM tools), and Agent Card (A2A).
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Example&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;.well-known/ucp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;manifest&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ucpVersion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-01-11"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"capabilities"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dev.ucp.shopping.checkout"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-01-11"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"restEndpoint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://api.example.com/ucp/checkout"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"paymentHandlers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"google_pay"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  When to Choose UCP
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;You need &lt;strong&gt;decentralized discovery&lt;/strong&gt; (any merchant can self-host)&lt;/li&gt;
&lt;li&gt;Your agents need &lt;strong&gt;rich shopping workflows&lt;/strong&gt; (cart, catalog, order tracking)&lt;/li&gt;
&lt;li&gt;You're building for &lt;strong&gt;Google's AI Mode&lt;/strong&gt; or &lt;strong&gt;Gemini&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;You need &lt;strong&gt;multiple payment handler types&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ACP: OpenAI &amp;amp; Stripe's Delegated Payment Model
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;Agentic Commerce Protocol&lt;/strong&gt; is an open standard (Apache 2.0) by OpenAI and Stripe, primarily powering ChatGPT Instant Checkout.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Architecture
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Discovery&lt;/strong&gt;: Centralized - merchants apply at chatgpt.com/merchants and provide product feeds&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Payment Model&lt;/strong&gt;: Delegated payment - any PSP can implement the spec (Stripe first, PayPal second)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Endpoints&lt;/strong&gt;: 5 REST endpoints for the full checkout lifecycle: create, get, update, complete, cancel&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;States&lt;/strong&gt;: &lt;code&gt;not_ready_for_payment&lt;/code&gt; → &lt;code&gt;ready_for_payment&lt;/code&gt; → &lt;code&gt;completed&lt;/code&gt; (with optional authentication steps)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Example ACP checkout session flow&lt;/span&gt;
&lt;span class="nx"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;checkout_sessions&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;line_items&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;product_id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;prod_123&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;amount&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2999&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// $29.99 in cents&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;quantity&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;return_url&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://example.com/return&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;success_url&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://example.com/success&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  When to Choose ACP
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;You're building for &lt;strong&gt;ChatGPT&lt;/strong&gt; or other OpenAI-agent ecosystems&lt;/li&gt;
&lt;li&gt;You prefer a &lt;strong&gt;centralized, vetted merchant pool&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Your transactions are &lt;strong&gt;single-item purchases&lt;/strong&gt; (current limitation)&lt;/li&gt;
&lt;li&gt;You want &lt;strong&gt;delegated payment&lt;/strong&gt; through any PSP&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Head-to-Head Comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;UCP&lt;/th&gt;
&lt;th&gt;ACP&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Developers&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Google, Shopify, 25+ partners&lt;/td&gt;
&lt;td&gt;OpenAI, Stripe&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Discovery&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Decentralized (&lt;code&gt;/.well-known/ucp&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Centralized (merchant application)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Payment&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Multiple handlers (Google Pay, Shop Pay, etc.)&lt;/td&gt;
&lt;td&gt;Delegated via any PSP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Extensibility&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Namespace-based extensions&lt;/td&gt;
&lt;td&gt;RFC-based extensions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Transport&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;REST, MCP, A2A&lt;/td&gt;
&lt;td&gt;REST only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Merchant Footprint&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;4.8M Shopify merchants + any self-hosted&lt;/td&gt;
&lt;td&gt;1.5M Stripe merchants + 35M PayPal (coming)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;License&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Open spec&lt;/td&gt;
&lt;td&gt;Apache 2.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Current Limitations&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Complex capability negotiation&lt;/td&gt;
&lt;td&gt;US-only, single-item only&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Why Choose? Build Both with Agorio
&lt;/h2&gt;

&lt;p&gt;The reality is that &lt;strong&gt;most serious commerce agents will need to support both protocols&lt;/strong&gt; to reach the maximum number of merchants. That's where &lt;a href="https://agorio.dev?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=202606" rel="noopener noreferrer"&gt;Agorio&lt;/a&gt; comes in.&lt;/p&gt;

&lt;p&gt;Agorio is an open-source TypeScript SDK that implements both UCP and ACP with automatic protocol detection. Here's how you can use it:&lt;/p&gt;

&lt;h3&gt;
  
  
  Example: UCP Client
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;UcpClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@agorio/sdk&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Discover merchant capabilities&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ucp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;UcpClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;profile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ucp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;discover&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Check if they support checkout&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;supportsCheckout&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ucp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createCheckoutSession&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;cartId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cart_123&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;paymentHandler&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;google_pay&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example: ACP Client
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AcpClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@agorio/sdk&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;acp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AcpClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;your_stripe_key&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;merchantId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;merch_123&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;acp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createCheckoutSession&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;lineItems&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;productId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;prod_123&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2999&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The ShoppingAgent: Auto-Detection Magic
&lt;/h3&gt;

&lt;p&gt;Agorio's &lt;code&gt;ShoppingAgent&lt;/code&gt; automatically detects which protocol a merchant supports and uses the appropriate client:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ShoppingAgent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;GeminiAdapter&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@agorio/sdk&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ShoppingAgent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;GeminiAdapter&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;GEMINI_API_KEY&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="na"&gt;verbose&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Agent automatically handles protocol detection&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Go to store.example.com and buy me wireless headphones&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Works with both UCP and ACP merchants&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Order placed: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;checkout&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;orderId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Implementation Complexity Analysis
&lt;/h2&gt;

&lt;p&gt;Implementing UCP from scratch requires:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JSON-LD manifest parsing&lt;/li&gt;
&lt;li&gt;Capability intersection algorithm&lt;/li&gt;
&lt;li&gt;Payment handler abstraction&lt;/li&gt;
&lt;li&gt;Multiple transport bindings&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Implementing ACP from scratch requires:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Bearer auth with API versioning&lt;/li&gt;
&lt;li&gt;Payment token delegation&lt;/li&gt;
&lt;li&gt;Product feed management&lt;/li&gt;
&lt;li&gt;Strict state machine adherence&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Agorio handles all of this for you&lt;/strong&gt;, providing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;UcpClient&lt;/code&gt; with discovery + REST/MCP auto-transport&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;AcpClient&lt;/code&gt; with full session lifecycle management&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ShoppingAgent&lt;/code&gt; with 12 built-in tools for commerce workflows&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;MockMerchant&lt;/code&gt; for testing (UCP, ACP, and MCP variants)&lt;/li&gt;
&lt;li&gt;LLM adapters for Gemini, Claude, OpenAI, Ollama&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Practical Recommendations
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Start with ACP if&lt;/strong&gt; you're building for ChatGPT or want the simplest integration with Stripe/PayPal.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Start with UCP if&lt;/strong&gt; you need decentralized discovery, multi-item carts, or Google AI Mode integration.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use Agorio if&lt;/strong&gt; you want to support both protocols from day one (recommended).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Remember: &lt;strong&gt;merchants should support both protocols&lt;/strong&gt; for maximum AI agent coverage, and so should your agent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It Yourself
&lt;/h2&gt;

&lt;p&gt;The fastest way to experiment is Agorio's interactive playground:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://agorio.dev/playground?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=202606" rel="noopener noreferrer"&gt;Agorio Playground&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Or install the SDK:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @agorio/sdk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check out the &lt;a href="https://github.com/Nolpak14/agorio" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt; (MIT licensed) and star it if you find it useful.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Future of Agentic Commerce
&lt;/h2&gt;

&lt;p&gt;Both UCP and ACP are evolving rapidly. UCP's AP2 mandates will enable cryptographic payment authorization for autonomous agents, while ACP is expanding to multi-item purchases and international markets.&lt;/p&gt;

&lt;p&gt;The key takeaway: &lt;strong&gt;protocol literacy is your moat&lt;/strong&gt;. Understanding these standards will make you a more effective agent builder, whether you're working on a personal shopping assistant or an enterprise procurement agent.&lt;/p&gt;

&lt;p&gt;Have you started building with UCP or ACP? Share your experiences in the comments below!&lt;/p&gt;

</description>
      <category>ai</category>
      <category>typescript</category>
      <category>commerce</category>
      <category>ucp</category>
    </item>
    <item>
      <title>Build a UCP Watchdog: Catch the Production Breaks Your CI Never Will</title>
      <dc:creator>Peter</dc:creator>
      <pubDate>Fri, 05 Jun 2026 14:50:32 +0000</pubDate>
      <link>https://dev.to/ucptools/build-a-ucp-watchdog-catch-the-production-breaks-your-ci-never-will-18jh</link>
      <guid>https://dev.to/ucptools/build-a-ucp-watchdog-catch-the-production-breaks-your-ci-never-will-18jh</guid>
      <description>&lt;p&gt;You wired UCP validation into CI. Every push runs the checks, every PR gets a score, and a bad profile fails the build before it merges. Good - that is the right baseline.&lt;/p&gt;

&lt;p&gt;Here is what it does not catch: the break that happens when nobody touches the code.&lt;/p&gt;

&lt;p&gt;The standard here is UCP (Universal Commerce Protocol) - an open standard that gives AI shopping agents a machine-readable entry point to a store at &lt;code&gt;/.well-known/ucp&lt;/code&gt;. &lt;em&gt;(Quick disclaimer: UCP is owned and maintained by Google and Shopify. UCPtools, which I work on, is an independent community tool - not affiliated with either.)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A CI gate is triggered by &lt;em&gt;your&lt;/em&gt; commits. But a UCP profile is a live production surface, and most of the things that break it are not commits at all:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;TLS certificate renews&lt;/strong&gt; and propagates to your origin but not to every CDN edge.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;capability schema host&lt;/strong&gt; your profile references goes down - someone else's outage, your broken profile.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;CDN or DNS change&lt;/strong&gt; starts serving a cache page or a redirect at &lt;code&gt;/.well-known/ucp&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Your &lt;strong&gt;platform&lt;/strong&gt; (Shopify, BigCommerce, a WooCommerce plugin update) quietly changes the served manifest or strips the &lt;code&gt;Content-Type: application/json&lt;/code&gt; header.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;signing key rotates&lt;/strong&gt; in your infra but not in the published profile.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of these trips a build, because there is no build. Your CI is green. Your store works fine for human browsers. The only thing that regressed is the machine-readable layer that no human ever visits - and the AI agent that hits it does not file a bug. It just leaves for the next merchant whose profile answers.&lt;/p&gt;

&lt;p&gt;CI catches what you break on merge. A watchdog catches what breaks itself. You need both.&lt;/p&gt;




&lt;h2&gt;
  
  
  What a Watchdog Actually Watches
&lt;/h2&gt;

&lt;p&gt;A pre-merge gate asks "is the profile I'm about to ship valid?" A watchdog asks a different question on a schedule: "is the profile that is live &lt;em&gt;right now&lt;/em&gt; still valid, from outside, the way an agent sees it?"&lt;/p&gt;

&lt;p&gt;Two design rules make the difference:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Check from outside your network.&lt;/strong&gt; A check that runs inside your own infra can hit a warm cache or an internal route and report healthy while external agents get errors. Fetch your public URL over the public internet.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compare against a baseline, not just against pass/fail.&lt;/strong&gt; A profile can stay technically valid while its score quietly slides from A to C. Alert on regression from a known-good baseline, not only on hard failures.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's build it two ways: a dependency-free cron version, and a GitHub Action with Slack alerts.&lt;/p&gt;




&lt;h2&gt;
  
  
  The 10-Line Version: cron + curl
&lt;/h2&gt;

&lt;p&gt;UCPtools exposes a public remote-validation endpoint that fetches a live domain's profile and runs the checks server-side. You can hit it from anything that runs &lt;code&gt;curl&lt;/code&gt; and &lt;code&gt;jq&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/usr/bin/env bash&lt;/span&gt;
&lt;span class="c"&gt;# ucp-watch.sh - alert if the live UCP profile is broken&lt;/span&gt;
&lt;span class="nv"&gt;DOMAIN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"mystore.com"&lt;/span&gt;

&lt;span class="nv"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-sS&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://ucptools.dev/v1/profiles/validate-remote &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"{&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;domain&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="nv"&gt;$DOMAIN&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;}"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="nv"&gt;ok&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$resp&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;     | jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.ok'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$resp&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'[.issues[] | select(.severity=="error")] | length'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ok&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s2"&gt;"true"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$errors&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-gt&lt;/span&gt; 0 &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nv"&gt;codes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$resp&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'[.issues[] | select(.severity=="error") | .code] | join(", ")'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
  curl &lt;span class="nt"&gt;-sS&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SLACK_WEBHOOK_URL&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'Content-type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"{&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:rotating_light: UCP profile for &lt;/span&gt;&lt;span class="nv"&gt;$DOMAIN&lt;/span&gt;&lt;span class="s2"&gt; is broken: &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;codes&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;}"&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The endpoint returns the live result, shaped like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ok"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"profile_url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://mystore.com/.well-known/ucp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"issues"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"severity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"UCP_SCHEMA_FETCH_FAILED"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"$.ucp.capabilities[0]"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"hint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"validated_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-06-05T14:33:57Z"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Schedule it and you have a watchdog:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;*/15 * * * * SLACK_WEBHOOK_URL=https://hooks.slack.com/... /opt/ucp-watch.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now &lt;code&gt;UCP_SCHEMA_FETCH_FAILED&lt;/code&gt; or &lt;code&gt;UCP_ENDPOINT_NOT_HTTPS&lt;/code&gt; showing up at 3am - hours after a cert renewal, with no deploy in sight - pages you instead of silently costing you agent traffic.&lt;/p&gt;




&lt;h2&gt;
  
  
  The GitHub Action Version: scheduled, with a baseline
&lt;/h2&gt;

&lt;p&gt;If your store already lives in GitHub, you can run the same idea on a &lt;code&gt;schedule:&lt;/code&gt; trigger and reuse the existing &lt;a href="https://github.com/Nolpak14/ucp-validate-action" rel="noopener noreferrer"&gt;&lt;code&gt;ucp-validate-action&lt;/code&gt;&lt;/a&gt; - the same action people put in CI - but pointed at your &lt;strong&gt;live production domain&lt;/strong&gt; and run on a clock instead of on push. The difference is entirely in the trigger and what you do with the result.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;UCP Watchdog&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;schedule&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;cron&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;*/30&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;*&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;*&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;*&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;*'&lt;/span&gt;   &lt;span class="c1"&gt;# every 30 minutes&lt;/span&gt;
  &lt;span class="na"&gt;workflow_dispatch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;          &lt;span class="c1"&gt;# let me run it by hand too&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;watch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ucp&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Nolpak14/ucp-validate-action@v1&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;domain&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;mystore.com'&lt;/span&gt;   &lt;span class="c1"&gt;# your LIVE domain, not staging&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Alert on regression&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;SLACK_WEBHOOK_URL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.SLACK_WEBHOOK_URL }}&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;score="${{ steps.ucp.outputs.score }}"&lt;/span&gt;
          &lt;span class="s"&gt;grade="${{ steps.ucp.outputs.grade }}"&lt;/span&gt;
          &lt;span class="s"&gt;found="${{ steps.ucp.outputs.ucp-found }}"&lt;/span&gt;
          &lt;span class="s"&gt;baseline=$(cat .ucp-baseline 2&amp;gt;/dev/null || echo 0)&lt;/span&gt;

          &lt;span class="s"&gt;echo "Live: score=$score grade=$grade found=$found | baseline=$baseline"&lt;/span&gt;

          &lt;span class="s"&gt;if [ "$found" = "false" ] || [ "$score" -lt "$baseline" ]; then&lt;/span&gt;
            &lt;span class="s"&gt;curl -sS -X POST "$SLACK_WEBHOOK_URL" -H 'Content-type: application/json' \&lt;/span&gt;
              &lt;span class="s"&gt;-d "{\"text\":\":rotating_light: UCP regression on mystore.com - score ${score} (grade ${grade}), baseline ${baseline}\"}"&lt;/span&gt;
            &lt;span class="s"&gt;exit 1&lt;/span&gt;
          &lt;span class="s"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Commit a one-line baseline file the first time you go green:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo &lt;/span&gt;90 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; .ucp-baseline   &lt;span class="c"&gt;# your known-good score&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The action exposes &lt;code&gt;score&lt;/code&gt;, &lt;code&gt;grade&lt;/code&gt;, &lt;code&gt;ucp-found&lt;/code&gt;, &lt;code&gt;passed&lt;/code&gt;, and &lt;code&gt;result-json&lt;/code&gt;, so you can build whatever alerting logic you want on top. The point is that the trigger is a clock, the target is production, and the comparison is against your last known-good state.&lt;/p&gt;




&lt;h2&gt;
  
  
  Alert Hygiene (so you don't train yourself to ignore it)
&lt;/h2&gt;

&lt;p&gt;A watchdog that cries wolf gets muted, and a muted watchdog is worse than none. Three things keep it honest:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Baseline, don't just pass/fail.&lt;/strong&gt; A slow slide from grade A to grade C is the regression you most want to know about, and a binary "still valid?" check will miss it entirely. Diff the score.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Debounce flaps.&lt;/strong&gt; A single failed fetch can be a transient network blip. Require two consecutive bad checks before paging, or alert on a sustained drop rather than one data point.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bump the baseline when you improve.&lt;/strong&gt; When you legitimately raise your score, update &lt;code&gt;.ucp-baseline&lt;/code&gt; in the same PR. The baseline is a ratchet - it should only move up on purpose.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Platform Notes
&lt;/h2&gt;

&lt;p&gt;The watchdog is platform-agnostic - it reads the open &lt;code&gt;/.well-known/ucp&lt;/code&gt; standard, not platform internals - but the regression that pages you tends to differ by stack:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;WooCommerce:&lt;/strong&gt; a caching or security plugin update that starts serving &lt;code&gt;/.well-known/ucp&lt;/code&gt; from cache, behind a challenge, or as &lt;code&gt;text/html&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;BigCommerce / headless:&lt;/strong&gt; a frontend deploy or app change that moves an endpoint the profile still advertises, or a storefront-scope mismatch.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shopify:&lt;/strong&gt; the platform changing what it serves at the well-known path out from under you.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In every case the failure is invisible until something fetches the live profile from outside and compares it to what you expect. That is the whole job of the watchdog.&lt;/p&gt;




&lt;p&gt;CI proves the profile you wrote is correct. A watchdog proves the profile your customers' agents actually hit is still correct - at 3am, after a cert renewal, when no one shipped a thing. Both are a few lines of YAML. The merchants who win the agentic-commerce transition will treat the second one like uptime, because that is exactly what it is.&lt;/p&gt;

&lt;p&gt;If you would rather not run your own, UCPtools does hosted monitoring with break-alerts across all four validation levels - &lt;a href="https://ucptools.dev/signup" rel="noopener noreferrer"&gt;start here&lt;/a&gt;. Either way: watch the live profile, not just the build.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;UCP is an open standard by Google and Shopify. UCPtools is an independent community tool.&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Built by Peter at &lt;a href="https://ucptools.dev" rel="noopener noreferrer"&gt;UCPtools&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>githubactions</category>
      <category>devops</category>
      <category>ecommerce</category>
      <category>ai</category>
    </item>
    <item>
      <title>How AI Shopping Agents Read Your Magento Store (and 4 UCP Checks That Fail in Production)</title>
      <dc:creator>Peter</dc:creator>
      <pubDate>Thu, 21 May 2026 15:52:52 +0000</pubDate>
      <link>https://dev.to/ucptools/how-ai-shopping-agents-read-your-magento-store-and-4-ucp-checks-that-fail-in-production-1lkj</link>
      <guid>https://dev.to/ucptools/how-ai-shopping-agents-read-your-magento-store-and-4-ucp-checks-that-fail-in-production-1lkj</guid>
      <description>&lt;p&gt;If you run a Magento or Adobe Commerce store, you have probably started getting the question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Can ChatGPT or Google's AI find my products? Are we 'AI-ready'?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The standard that answers it is UCP (Universal Commerce Protocol) - an open standard from Google and Shopify that gives AI shopping agents a machine-readable entry point to a store, served at &lt;code&gt;/.well-known/ucp&lt;/code&gt;. &lt;em&gt;(Quick disclaimer: UCP is owned and maintained by Google and Shopify. UCPtools, which I work on, is an independent community tool - not affiliated with either.)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Here is the catch for Magento specifically: a UCP profile that validates perfectly on your laptop can still be broken for every real AI agent in production. Magento's enterprise stack - GraphQL plus REST, Varnish full-page cache, multi-store scopes, CDN edges - breaks UCP discovery in ways a single-tenant Shopify store simply never encounters.&lt;/p&gt;

&lt;p&gt;This post walks through the four levels of UCP validation and, for each, the Magento-specific failure mode that bites in production.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Magento Is a Different Animal
&lt;/h2&gt;

&lt;p&gt;On Shopify, the platform owns the edge. Your UCP surface is largely handled for you and the failure modes are narrow.&lt;/p&gt;

&lt;p&gt;On Magento/Adobe Commerce, &lt;em&gt;you&lt;/em&gt; own the edge - and that is exactly where UCP lives:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;/.well-known/ucp&lt;/code&gt; is a static-looking path served by a very dynamic system.&lt;/strong&gt; Varnish, Fastly, or your CDN decides whether agents see a fresh profile or a stale one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Two API surfaces.&lt;/strong&gt; Magento exposes both GraphQL and REST. A UCP profile that points agents at endpoints has to point at ones that actually answer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multiple store views and websites.&lt;/strong&gt; A profile bound to the wrong scope describes the wrong catalog, currency, or domain.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Self-managed TLS and CDN.&lt;/strong&gt; Certificate renewals and cache propagation are your problem, and agents are unforgiving about both.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;UCP validation is not a one-time setup step here. It is a production concern, like uptime.&lt;/p&gt;




&lt;h2&gt;
  
  
  Level 1: Structural - Does the Profile Parse?
&lt;/h2&gt;

&lt;p&gt;The first level is the cheap one: is &lt;code&gt;/.well-known/ucp&lt;/code&gt; valid JSON, are the required fields present, and is the version string a valid &lt;code&gt;YYYY-MM-DD&lt;/code&gt; date?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Magento failure mode: Varnish serves HTML, not JSON.&lt;/strong&gt; The single most common Magento issue is that the full-page cache or a misconfigured rewrite intercepts &lt;code&gt;/.well-known/ucp&lt;/code&gt; and returns an HTML error page (or the homepage) with a &lt;code&gt;200&lt;/code&gt;. Structurally, an agent receives HTML where it expected JSON, and discovery dies at step one.&lt;/p&gt;

&lt;p&gt;The fix is a cache-bypass rule for the &lt;code&gt;.well-known&lt;/code&gt; path. If you are on Varnish, exclude it from the full-page cache so the profile is always served fresh and as &lt;code&gt;application/json&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Level 2: Rules - Is the Profile Internally Consistent?
&lt;/h2&gt;

&lt;p&gt;Structural validity is not compliance. Level 2 checks the UCP rules: namespace and origin binding, extension chains, HTTPS-only endpoints, and the presence of signing keys.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Magento failure mode: origin/scope mismatch.&lt;/strong&gt; Multi-store Magento installs serve several domains and store views from one backend. It is easy to publish a profile whose declared origin does not match the host actually serving it, or whose capability endpoints point at a different store view's domain. To an agent, that is a profile that does not trust its own host - and it will not transact against it.&lt;/p&gt;

&lt;p&gt;A close second: declaring capability endpoints over &lt;code&gt;http://&lt;/code&gt; or with trailing slashes that your rewrites then bounce. Agents follow the spec literally; "close enough" URLs are not close enough.&lt;/p&gt;




&lt;h2&gt;
  
  
  Level 3: Network - Do the Endpoints Actually Answer?
&lt;/h2&gt;

&lt;p&gt;Level 3 leaves the profile behind and goes to the wire. It fetches the schemas and endpoints the profile advertises and verifies they resolve, over HTTPS, with a valid certificate chain.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Magento failure mode: the deploy that quietly breaks an endpoint.&lt;/strong&gt; This is the one that makes UCP a recurring concern rather than a checklist item. A &lt;code&gt;setup:upgrade&lt;/code&gt;, a module update, or a routing change can move or 500 the very endpoint your profile promised. The profile still validates structurally - it is the live endpoint that regressed.&lt;/p&gt;

&lt;p&gt;The other classic: a certificate renewal that propagated to your origin but not to every CDN edge, so agents hitting one POP get a valid chain and agents hitting another get a handshake error. You will not see it in a browser; an agent will.&lt;/p&gt;




&lt;h2&gt;
  
  
  Level 4: SDK / Spec - Does It Pass Official Compliance?
&lt;/h2&gt;

&lt;p&gt;The final level runs the profile against the official UCP SDK to confirm it complies with the current published spec, not just a plausible-looking shape. Specs move; a profile written against an older draft can drift out of compliance without anyone touching it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Magento failure mode: pinned-and-forgotten.&lt;/strong&gt; Enterprise Magento changes slowly and deliberately - which is a virtue everywhere except here. A profile authored months ago against an earlier UCP version keeps validating against its own assumptions while the spec advances around it. Level 4 is what catches that drift.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Part Most Magento Teams Miss: Discovery Is Not Checkout
&lt;/h2&gt;

&lt;p&gt;A page can be perfectly structured - Schema.org markup, FAQs, breadcrumbs - and an agent can still be unable to &lt;em&gt;buy&lt;/em&gt;. Structured data helps agents understand your catalog. UCP is the actionable layer that lets them complete a purchase: the capabilities, endpoints, and payment handlers a profile declares.&lt;/p&gt;

&lt;p&gt;Passing a structural "AI readiness" check means you are discoverable. Passing all four UCP levels - in production, on every CDN edge, after every deploy - means you are transactable. Those are different bars, and only the second one earns the order.&lt;/p&gt;




&lt;h2&gt;
  
  
  How to Check Your Store
&lt;/h2&gt;

&lt;p&gt;If you want to see where your Magento store actually stands:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Run your domain through a UCP validator that does all four levels, not just a JSON parse. (UCPtools does this for free; it works on Magento, Adobe Commerce, and any other platform, since it reads the open &lt;code&gt;/.well-known/ucp&lt;/code&gt; standard rather than platform internals.)&lt;/li&gt;
&lt;li&gt;Pay special attention to the &lt;strong&gt;Network&lt;/strong&gt; level - that is where Magento's Varnish/CDN/deploy issues surface.&lt;/li&gt;
&lt;li&gt;Re-run it after every deploy and certificate renewal. Treat a UCP regression like a failed health check.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I wrote a deeper, Magento-specific walkthrough - including the GraphQL + REST endpoint setup and the Varnish bypass rule - in the &lt;a href="https://ucptools.dev/guides/magento" rel="noopener noreferrer"&gt;Magento &amp;amp; Adobe Commerce UCP guide&lt;/a&gt;. If you want to compare structural "readiness" checks against full UCP validation, &lt;a href="https://ucptools.dev/compare/ucptools-vs-shopify-agentic-readiness" rel="noopener noreferrer"&gt;this comparison&lt;/a&gt; lays out the difference.&lt;/p&gt;




&lt;p&gt;The merchants who win the agentic-commerce transition will not be the ones with the prettiest product pages. They will be the ones whose checkout an agent can actually complete - reliably, in production, on Magento's genuinely complicated stack. The good news is that it is all measurable now. Measure it.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;UCP is an open standard by Google and Shopify. UCPtools is an independent community tool.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ucp</category>
      <category>ecommerce</category>
      <category>magento</category>
      <category>ai</category>
    </item>
    <item>
      <title>ACP Pivoted from Checkout to Discovery. UCP Wins by Default - Here's the Protocol Convergence.</title>
      <dc:creator>Peter</dc:creator>
      <pubDate>Wed, 06 May 2026 10:21:17 +0000</pubDate>
      <link>https://dev.to/ucptools/acp-pivoted-from-checkout-to-discovery-ucp-wins-by-default-heres-the-protocol-convergence-374e</link>
      <guid>https://dev.to/ucptools/acp-pivoted-from-checkout-to-discovery-ucp-wins-by-default-heres-the-protocol-convergence-374e</guid>
      <description>&lt;h1&gt;
  
  
  ACP Pivoted from Checkout to Discovery. UCP Wins by Default - Here's the Protocol Convergence.
&lt;/h1&gt;

&lt;p&gt;OpenAI just made the biggest strategic retreat in agentic commerce, and most developers missed what it means for their stack.&lt;/p&gt;

&lt;p&gt;In March 2026, OpenAI quietly pivoted ACP (Agentic Commerce Protocol) away from its original premise: completing purchases inside ChatGPT. The "Instant Checkout" button that was supposed to revolutionize shopping? Gone. Replaced by a merchant app model where purchases complete on the retailer's own storefront.&lt;/p&gt;

&lt;p&gt;This isn't a bug. It's an admission that full-stack commerce is harder than discovery. And it hands the complete commerce stack to UCP by default.&lt;/p&gt;

&lt;h2&gt;
  
  
  What actually happened
&lt;/h2&gt;

&lt;p&gt;OpenAI's ACP launched with an ambitious vision: users would discover products, compare options, and complete purchases entirely within ChatGPT. Stripe provided the payment rails. The promise was a seamless, one-tap checkout experience inside an AI conversation.&lt;/p&gt;

&lt;p&gt;It didn't work.&lt;/p&gt;

&lt;p&gt;CNBC reported on March 20 that "OpenAI's first try at agentic shopping stumbled." Users browsed products in ChatGPT but abandoned purchases before completing them. The in-chat checkout experience lacked sales tax infrastructure, return policy visibility, and the trust signals that mature e-commerce storefronts provide.&lt;/p&gt;

&lt;p&gt;The pivot, detailed by Digital Commerce 360 on March 24, shifts ACP to a merchant app model:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dedicated retailer apps inside ChatGPT (Instacart, Etsy, Shopify, Walmart)&lt;/li&gt;
&lt;li&gt;Product discovery and comparison happens in-chat&lt;/li&gt;
&lt;li&gt;Purchase completion happens on the merchant's own storefront (in-app browser on mobile, separate tab on desktop)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As Roger Dunn wrote in his analysis: "ACP's role shifts from universal long-tail merchant connector to plumbing for deep, bespoke retailer partnerships."&lt;/p&gt;

&lt;h2&gt;
  
  
  The protocol math just changed
&lt;/h2&gt;

&lt;p&gt;Here's what this means for the two competing protocols:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before the pivot (January - February 2026):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;UCP: Discovery + browsing + cart + checkout (full commerce)&lt;/li&gt;
&lt;li&gt;ACP: Discovery + Instant Checkout inside ChatGPT (full commerce)&lt;/li&gt;
&lt;li&gt;They competed for the same stack&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;After the pivot (March 2026 onward):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;UCP: Discovery + browsing + cart + checkout (full commerce) &lt;/li&gt;
&lt;li&gt;ACP: Discovery + handoff to merchant storefront (discovery only)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The protocols aren't competing anymore. They're converging into different layers of the same stack. UCP owns commerce. ACP owns discovery within ChatGPT's walled garden.&lt;/p&gt;

&lt;p&gt;As Ken Huang put it on his Substack: "Google's UCP Just Won Agentic Commerce."&lt;/p&gt;

&lt;h2&gt;
  
  
  What this means for developers building today
&lt;/h2&gt;

&lt;p&gt;If you're an e-commerce developer deciding where to invest protocol implementation time, the math is now straightforward:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Implement UCP now.&lt;/strong&gt; It's the only protocol that gives AI agents the full commerce capability: product catalog browsing, cart management, identity linking, and payment processing. It's co-created by Google and Shopify with 25+ partners. It's what Google AI Mode, Gemini, and an expanding ecosystem of agents use to discover and transact with stores.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ACP is becoming a discovery layer.&lt;/strong&gt; If you want your products surfaced inside ChatGPT conversations, ACP integration matters - but as a discovery mechanism that hands off to your storefront, not as a transaction protocol.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The real implementation gap isn't protocol choice.&lt;/strong&gt; It's quality. Most deployed UCP profiles fail at basic validation levels:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Missing &lt;code&gt;signing_keys&lt;/code&gt; means agents can't verify your manifest&lt;/li&gt;
&lt;li&gt;Namespace/origin mismatches break discovery before it starts&lt;/li&gt;
&lt;li&gt;Incomplete Cart capability definitions create failed add-to-cart experiences&lt;/li&gt;
&lt;li&gt;Identity Linking (the stable spec) is the least-implemented capability despite being the most valuable for cross-domain user recognition&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At UCPtools, we scan thousands of profiles. The average score sits well below what AI agents consider reliable. Being "detected" is not the same as being "buyable."&lt;/p&gt;

&lt;h2&gt;
  
  
  What to build
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Implement UCP on your primary store domain first.&lt;/strong&gt; The &lt;code&gt;.well-known/ucp&lt;/code&gt; manifest is table stakes. Make sure it validates at all four levels: structural JSON validity, business rules consistency, network reachability, and SDK-level agent simulation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Don't skip Identity Linking.&lt;/strong&gt; It's the stable spec that enables cross-domain user recognition. When a user browses your store on one device and returns via an AI agent on another, Identity Linking is what connects those sessions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Add ACP as a discovery channel, not a transaction channel.&lt;/strong&gt; The merchant app model means your ChatGPT presence should focus on product discovery and comparison, with a clean handoff to your UCP-enabled storefront where the actual purchase happens.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Monitor continuously.&lt;/strong&gt; Protocols evolve. Specs change. Your profile that validated perfectly in April might fail in June when a capability gets promoted from draft to stable. Continuous validation catches regressions before they cost you AI agent traffic.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The bottom line
&lt;/h2&gt;

&lt;p&gt;The protocol war is over before it really started. ACP pivoted to discovery. UCP owns the commerce stack by default.&lt;/p&gt;

&lt;p&gt;The question for e-commerce developers isn't which protocol to bet on - it's whether your UCP implementation is good enough for AI agents to actually complete a purchase.&lt;/p&gt;

&lt;p&gt;Most aren't.&lt;/p&gt;

&lt;p&gt;Validate your UCP profile at &lt;a href="https://ucptools.dev?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=202605" rel="noopener noreferrer"&gt;https://ucptools.dev?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=202605&lt;/a&gt; - the free tier runs all four validation levels and simulates a real AI agent interaction against your store. If an AI agent can't buy from you, your customers can't either.&lt;/p&gt;

</description>
      <category>agenticcommerce</category>
      <category>ucp</category>
      <category>acp</category>
      <category>ecommerce</category>
    </item>
    <item>
      <title>What Your UCP Trial Unlocks: From Grade C to Grade A in 15 Minutes</title>
      <dc:creator>Peter</dc:creator>
      <pubDate>Fri, 01 May 2026 10:26:52 +0000</pubDate>
      <link>https://dev.to/ucptools/what-your-ucp-trial-unlocks-from-grade-c-to-grade-a-in-15-minutes-38i3</link>
      <guid>https://dev.to/ucptools/what-your-ucp-trial-unlocks-from-grade-c-to-grade-a-in-15-minutes-38i3</guid>
      <description>&lt;h1&gt;
  
  
  What Your UCP Trial Unlocks: From Grade C to Grade A in 15 Minutes
&lt;/h1&gt;

&lt;p&gt;Most stores with a UCP profile are stuck at Grade C. Their manifest loads. Agents can see them. But they cannot buy a single thing. Here is what changes when you fix the three fields every Grade C store is missing - and how a 7-day trial makes it a 15-minute job.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Grade C trap: visible, but not transactable
&lt;/h2&gt;

&lt;p&gt;A Grade C UCP profile means structural validity. Your &lt;code&gt;/.well-known/ucp&lt;/code&gt; returns valid JSON. An AI shopping agent can discover your store. That feels like progress.&lt;/p&gt;

&lt;p&gt;But Grade C also means the agent hits a wall the moment it tries to do anything commercial. No payment handlers configured. No signing keys for verification. No return policy for the agent to communicate to the buyer. The agent walks away, and your store never knows it happened.&lt;/p&gt;

&lt;p&gt;We see this pattern constantly. In the last 7 days, 59 UCP profiles were validated on UCPtools. Eleven of those stores ran the AI Agent Simulator - a real end-to-end agent interaction test. None of them completed a purchase. Zero.&lt;/p&gt;

&lt;p&gt;Grade C means "detected." That is not the same as "can transact."&lt;/p&gt;




&lt;h2&gt;
  
  
  The three fields keeping you at Grade C
&lt;/h2&gt;

&lt;p&gt;After scanning dozens of e-commerce domains, three failures appear on nearly every Grade C profile:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. &lt;code&gt;signing_keys&lt;/code&gt; - the trust layer agents require&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Without a public key in your manifest, AI agents cannot cryptographically verify that your UCP responses are authentic. This is not optional. Agents check this before they take any commercial action. A missing &lt;code&gt;signing_keys&lt;/code&gt; field is an instant trust failure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. &lt;code&gt;payment_handlers&lt;/code&gt; - the "how do I pay?" gap&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Agents need to know which payment methods your store accepts before they can initiate a checkout. No &lt;code&gt;payment_handlers&lt;/code&gt; array means the agent has no path to complete a purchase. The store is technically "discoverable" but functionally invisible for any transaction.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Return policy schema - the confidence gap&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AI agents are designed to communicate return terms to buyers before purchase. If your manifest does not include return policy information, the agent cannot answer basic buyer questions like "what happens if I need to return this?" That missing confidence costs conversions - both for the agent and for you.&lt;/p&gt;

&lt;p&gt;These are not exotic edge cases. They are the baseline requirements that separate "the agent found your store" from "the agent bought from your store."&lt;/p&gt;




&lt;h2&gt;
  
  
  What the free tools tell you vs. what the trial shows you
&lt;/h2&gt;

&lt;p&gt;Free UCP checkers give you a binary answer: detected or not detected. They run structural validation. They might catch a missing JSON field. But they stop there.&lt;/p&gt;

&lt;p&gt;A UCPtools Starter trial ($9/mo, 7 days free, no credit card) gives you four layers the free tools skip:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Level 1 - Structural validation:&lt;/strong&gt; Yes, free tools do this. Valid JSON, required fields present. This is where every Grade C store already passes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Level 2 - Rules validation:&lt;/strong&gt; Business logic checks. Do your namespace and origin match? Are your capability declarations internally consistent? This is where most Grade C stores start failing - but free checkers do not run these tests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Level 3 - Network validation:&lt;/strong&gt; Live endpoint testing. Are your UCP endpoints actually reachable over HTTPS? Do they return the correct response codes? A manifest can be structurally valid and still serve 404s to agents.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Level 4 - SDK validation (AI Agent Simulator):&lt;/strong&gt; This is the one that matters. The simulator behaves like a real AI shopping agent - it discovers your store, reads your manifest, and attempts to complete a purchase. It shows you exactly where the agent fails and why. Eleven stores ran this in the last 7 days. All eleven hit failures that structural validation alone would never catch.&lt;/p&gt;




&lt;h2&gt;
  
  
  From Grade C to Grade A: the 15-minute path
&lt;/h2&gt;

&lt;p&gt;Here is what the upgrade looks like in practice:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Run the full scan (2 minutes)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Start your trial and point UCPtools at your domain. The 4-level scan completes in under 90 seconds. You get a report that looks nothing like a "detected/not detected" badge - it is a prioritized list of failures ranked by severity, with exact fix recommendations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Generate your signing keys (3 minutes)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;UCPtools generates a key pair for you through the hosted profile generator. Copy the public key into your manifest. The tool validates the placement so you know it is right before you deploy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Configure payment handlers (5 minutes)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Map your existing payment stack (Stripe, Shopify Payments, PayPal) to the UCP payment handler format. The trial shows you the exact JSON structure your manifest needs based on what your store already supports.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Add return policy schema (3 minutes)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Structured return policy data that agents can parse and communicate. The trial's hosted profile builder includes a template you fill in once and deploy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5: Re-scan and simulate (2 minutes)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Run validation again. Run the AI Agent Simulator. Watch the agent discover your store, verify your keys, read your payment handlers, and complete a purchase simulation. Grade A means the agent can do everything a human shopper can do - find you, browse, and buy.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why the trial matters (and why it is free)
&lt;/h2&gt;

&lt;p&gt;Nobody pays $9 to see a validation report. They pay $9 because the report tells them something the free tools never will: whether AI agents can actually buy from their store, and exactly how to fix it if they cannot.&lt;/p&gt;

&lt;p&gt;The 7-day trial exists because this is not something you evaluate from a marketing page. You need to see your own domain's results. You need to run the simulator against your own store. The trial gives you full access to do exactly that, with no credit card required.&lt;/p&gt;

&lt;p&gt;If your store passes structural validation but you have never run the simulator, you do not know if your UCP profile works. You just know it loads.&lt;/p&gt;




&lt;h2&gt;
  
  
  Scan your store free
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Start your 7-day free trial at &lt;a href="https://ucptools.dev/?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=202605" rel="noopener noreferrer"&gt;ucptools.dev&lt;/a&gt; - no credit card required. Run a full 4-level validation against your domain and see exactly where your store stands with AI shopping agents.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;em&gt;Written by the team at UCPtools - the only toolkit that validates, monitors, and optimizes your UCP business profile for AI agent discoverability. Questions? Find us on &lt;a href="https://twitter.com/ucptoolsdev" rel="noopener noreferrer"&gt;X @ucptoolsdev&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ucp</category>
      <category>ecommerce</category>
      <category>webdev</category>
      <category>ai</category>
    </item>
    <item>
      <title>UCP Validation for Agencies: How to Audit AI Readiness Across Every Client Domain</title>
      <dc:creator>Peter</dc:creator>
      <pubDate>Wed, 29 Apr 2026 11:02:37 +0000</pubDate>
      <link>https://dev.to/ucptools/ucp-validation-for-agencies-how-to-audit-ai-readiness-across-every-client-domain-1da0</link>
      <guid>https://dev.to/ucptools/ucp-validation-for-agencies-how-to-audit-ai-readiness-across-every-client-domain-1da0</guid>
      <description>&lt;p&gt;If you're a GEO consultant or agency managing ecommerce clients, you've probably been asked some version of this question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Can AI agents find my store? How do I know?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The honest answer, until recently, was: you don't. There was no standardized way to measure AI agent discoverability. That changed with UCP (Universal Commerce Protocol) - the open standard from Google and Shopify that gives AI shopping agents a machine-readable entry point to any store.&lt;/p&gt;

&lt;p&gt;Now there &lt;em&gt;is&lt;/em&gt; something measurable. And if you're the one measuring it for your clients, that's a service worth charging for.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Agencies Should Care About UCP Audits
&lt;/h2&gt;

&lt;p&gt;Google AI Mode, Microsoft Copilot, ChatGPT, and Perplexity are all building agentic commerce capabilities. &lt;a href="https://blogs.bing.com/webmaster/2026/04/21/ucp-feeds-general-availability" rel="noopener noreferrer"&gt;Microsoft announced GA of UCP feeds in Merchant Center&lt;/a&gt; on April 21, 2026. Over 12,000 merchants have published UCP profiles as of Q1 2026.&lt;/p&gt;

&lt;p&gt;Your clients are going to ask about this. Some already have. The agencies that can answer with data - not hand-waving - will win those conversations.&lt;/p&gt;

&lt;p&gt;Here's what makes UCP audits a natural fit for agencies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;It's per-domain.&lt;/strong&gt; Each client's hosting stack, CDN, and certificate chain breaks differently. A profile that works on Shopify fails on WooCommerce for entirely different reasons.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It's recurring.&lt;/strong&gt; UCP validation isn't a one-time setup. Deploys break endpoints. CDN caches serve stale schemas. Certificate renewals don't propagate. The profile that passed last month can silently fail this month.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It's reportable.&lt;/strong&gt; UCP validation produces a numerical AI readiness score (0-100) with specific, fixable issues. That's the kind of deliverable clients understand.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Agency Audit Framework
&lt;/h2&gt;

&lt;p&gt;Here's a repeatable process for running UCP audits across a client portfolio. It works whether you manage 3 domains or 300.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Baseline Scan: Does the Profile Exist?
&lt;/h3&gt;

&lt;p&gt;Before anything else, check whether each client domain serves a UCP manifest at &lt;code&gt;/.well-known/ucp&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://client-store.com/.well-known/ucp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three outcomes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;404 / No manifest&lt;/strong&gt; - The store is invisible to AI agents. Full stop. This is your biggest finding and your clearest upsell.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Manifest exists but invalid JSON&lt;/strong&gt; - Broken deployment or misconfigured server. Quick fix, high impact.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Valid manifest&lt;/strong&gt; - Move to deeper validation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In our experience, roughly 70% of ecommerce stores don't serve a UCP manifest at all. For the ones that do, about 60% have issues at deeper validation levels.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Four-Level Validation
&lt;/h3&gt;

&lt;p&gt;UCP validation isn't binary (pass/fail). There are four distinct levels, and each catches different categories of issues:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Level&lt;/th&gt;
&lt;th&gt;What It Checks&lt;/th&gt;
&lt;th&gt;Common Failures&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;1. Structural&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;JSON syntax, required fields, version format&lt;/td&gt;
&lt;td&gt;Missing &lt;code&gt;ucp&lt;/code&gt; root, wrong version format&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;2. Compliance&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Protocol rules: namespaces, HTTPS, signing keys&lt;/td&gt;
&lt;td&gt;Namespace mismatches, missing signing keys (42% of L2 failures), HTTP endpoints&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;3. Network&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Do declared URLs actually resolve?&lt;/td&gt;
&lt;td&gt;CDN 404s, stale schemas, malformed JWK keys&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;4. Agent Simulation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Full checkout lifecycle test&lt;/td&gt;
&lt;td&gt;Backend returns 500 on cart creation, state machine failures&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Most validators - including the free ones your clients might have tried - only check Level 1. That gives false confidence. A Level 1 pass with Level 3 failures means the profile looks correct but agents can't actually use it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For agencies, Level 3 is the most valuable finding.&lt;/strong&gt; These are infrastructure-drift issues that only surface after deploys, CDN changes, or certificate renewals. They're invisible to the developer who wrote the profile but obvious to an auditor running regular checks.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Score and Categorize
&lt;/h3&gt;

&lt;p&gt;After running validation, each domain gets an AI readiness score (0-100) and a letter grade:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Grade&lt;/th&gt;
&lt;th&gt;Score&lt;/th&gt;
&lt;th&gt;What It Means&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;90-100&lt;/td&gt;
&lt;td&gt;AI agents can discover, browse, and transact&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;B&lt;/td&gt;
&lt;td&gt;70-89&lt;/td&gt;
&lt;td&gt;Discoverable with minor issues&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C&lt;/td&gt;
&lt;td&gt;50-69&lt;/td&gt;
&lt;td&gt;Detected but can't complete transactions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;D&lt;/td&gt;
&lt;td&gt;20-49&lt;/td&gt;
&lt;td&gt;Major issues blocking agent interaction&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;F&lt;/td&gt;
&lt;td&gt;0-19&lt;/td&gt;
&lt;td&gt;Effectively invisible&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The Grade C trap is the most common: the profile exists and passes basic checks, but missing signing keys or broken endpoints prevent any actual transaction. Your client thinks they're "UCP ready" because they have a manifest file. They're not.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Build the Client Report
&lt;/h3&gt;

&lt;p&gt;A useful client report contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Score and grade&lt;/strong&gt; for each domain&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Issue breakdown&lt;/strong&gt; by validation level (structural, compliance, network, simulation)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Specific fixes&lt;/strong&gt; with estimated effort (most Level 2 fixes take minutes)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Comparison to previous audit&lt;/strong&gt; if this is a recurring engagement&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Competitive context&lt;/strong&gt; - how do they compare to others in their vertical?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The key metric clients care about: &lt;strong&gt;"Can AI agents buy from my store?"&lt;/strong&gt; Frame everything around that question. A score of 62 means "AI agents can find you but can't complete a purchase." That's concrete enough to drive action.&lt;/p&gt;




&lt;h2&gt;
  
  
  What to Check Per Platform
&lt;/h2&gt;

&lt;p&gt;UCP issues cluster differently by ecommerce platform. Knowing the common patterns saves audit time:&lt;/p&gt;

&lt;h3&gt;
  
  
  Shopify
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;UCP profile served via app proxy (path configuration matters)&lt;/li&gt;
&lt;li&gt;Payment handler configuration usually correct (Shopify handles this)&lt;/li&gt;
&lt;li&gt;Watch for: signing key rotation gaps, custom app conflicts&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  WooCommerce
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Profile typically served via WordPress plugin or &lt;code&gt;.htaccess&lt;/code&gt; rewrite&lt;/li&gt;
&lt;li&gt;Watch for: HTTP endpoints (mixed content from plugin misconfiguration), schema URL 404s after plugin updates&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  BigCommerce
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Common issue: &lt;code&gt;dev.ucp.shopping&lt;/code&gt; service missing required &lt;code&gt;spec&lt;/code&gt; field (&lt;code&gt;UCP_INVALID_SERVICE&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Watch for: trailing slashes on API endpoints&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Magento / Adobe Commerce
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Custom module required for &lt;code&gt;/.well-known/ucp&lt;/code&gt; routing&lt;/li&gt;
&lt;li&gt;Watch for: namespace mismatches when using third-party extensions, GraphQL endpoint schema drift&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Custom / Headless
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Most flexibility, most failure modes&lt;/li&gt;
&lt;li&gt;Watch for: CORS blocking agent preflight requests, endpoint URLs changing between environments&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Automating Portfolio Audits
&lt;/h2&gt;

&lt;p&gt;Running manual checks across 10+ domains doesn't scale. Two automation approaches:&lt;/p&gt;

&lt;h3&gt;
  
  
  CI/CD Integration (Per Client)
&lt;/h3&gt;

&lt;p&gt;If you have access to client repos, the &lt;a href="https://github.com/marketplace/actions/ucp-profile-validator" rel="noopener noreferrer"&gt;ucp-validate GitHub Action&lt;/a&gt; fails the build when the AI readiness score drops below a threshold:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Nolpak14/ucp-validate-action@v1&lt;/span&gt;
  &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;domain&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;client-store.com'&lt;/span&gt;
    &lt;span class="na"&gt;min-score&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;70&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This catches regressions at deploy time - before they affect agent traffic.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scheduled Monitoring (Portfolio-Wide)
&lt;/h3&gt;

&lt;p&gt;For ongoing monitoring without repo access, run validation against each client domain on a schedule. The &lt;a href="https://ucptools.dev?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=agency-audit" rel="noopener noreferrer"&gt;UCPtools validator&lt;/a&gt; supports domain-level validation via URL - no code access needed.&lt;/p&gt;

&lt;p&gt;Track scores over time. A domain that drops from 85 to 62 between audits means something broke in production, and you're the one catching it before the client's AI-driven traffic disappears.&lt;/p&gt;




&lt;h2&gt;
  
  
  Positioning This as a Service
&lt;/h2&gt;

&lt;p&gt;UCP auditing fits naturally into existing GEO/SEO service packages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;One-time audit&lt;/strong&gt; - Baseline scan across all client domains with a findings report. Natural entry point.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monthly monitoring&lt;/strong&gt; - Recurring validation with score tracking and regression alerts. Retainer model.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Implementation support&lt;/strong&gt; - Fix the issues the audit found. Scope varies by platform (Shopify is usually hours, custom builds are days).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The pitch to clients: "Your SEO drives traffic to your store. UCP drives AI agent traffic. We monitor both."&lt;/p&gt;

&lt;p&gt;What makes this defensible: UCP validation requires understanding the spec, the four validation levels, and platform-specific patterns. A generic SEO tool can't do this. You can.&lt;/p&gt;




&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Run a free validation&lt;/strong&gt; against one of your client domains at &lt;a href="https://ucptools.dev?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=agency-audit" rel="noopener noreferrer"&gt;ucptools.dev&lt;/a&gt;. See the score, the issues, and which level caught them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Repeat for your portfolio.&lt;/strong&gt; Note which clients have no manifest at all vs. which have broken ones.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build the report.&lt;/strong&gt; Score, grade, issues, fixes. Send it to the client.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Set up monitoring.&lt;/strong&gt; Catch regressions before they cost AI traffic.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The agencies that can quantify AI discoverability will own this conversation. The ones that can't will be explaining why they didn't notice their client's store disappeared from ChatGPT.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;UCPtools is an independent community tool - not affiliated with Google, Shopify, or the UCP consortium.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ucp</category>
      <category>ecommerce</category>
      <category>webdev</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
