AgenticWebScore
Scan

Learn

UCP manifest: what to publish at /.well-known/ucp, with an annotated example

What a Universal Commerce Protocol profile at /.well-known/ucp contains, an annotated example, the hosting rules, and what the scanner reads.

8 min read 1457 words

  • UCP
  • well-known
  • agentic commerce
  • Shopify

A UCP manifest is a JSON file at /.well-known/ucp that declares what a business supports under the Universal Commerce Protocol. The specification calls it a business profile. Release 2026-08-25 requires ucp.version, ucp.services and ucp.payment_handlers. The scanner's ucp-manifest check reads a smaller subset.

What is the Universal Commerce Protocol?

UCP is an open protocol for the commerce lifecycle: catalog search, cart, identity linking, checkout and orders. Its home page lists Google, Shopify, Etsy, Wayfair, Target, Walmart and others as co-developers for shopping. Google's overview names AI Mode in Google Search and Gemini as the places where UCP enables agentic actions.

The protocol moves in dated releases. The versions file lists 4 of them between 11 January and 25 August 2026, plus a draft. The latest is 2026-08-25.

The specification calls the party that reads a profile the platform, and this article follows that term. The comparison of AP2, ACP, UCP, x402 and MPP shows where UCP sits next to the others.

How does an agent use a UCP manifest?

A platform fetches /.well-known/ucp and picks a release that both profiles declare. It then intersects the capabilities. A capability is active when both sides list it at the same version, and an extension is dropped when its parent is not active.

Every later request carries the platform's own profile URL. Over HTTP that is a UCP-Agent header, and over MCP it is meta.ucp-agent.profile. The business returns the negotiated version in each response.

Where does the manifest live, and how must it be served?

The path is /.well-known/ucp, with no extension, at the origin of the business. Google's guide says the file must be publicly accessible and require no authentication. The scanner also reads /.well-known/ucp.json and takes the first valid answer. The specification names only the first path, so publish there.

The specification sets 4 hosting rules.

  • HTTPS only. A platform rejects a profile served over plain HTTP.
  • No redirects. A profile endpoint must not answer 3xx, and a platform must not follow one.
  • Cacheable. Cache-Control must be public with a max-age of at least 60 seconds. It must not carry private, no-store or no-cache.
  • A validator. An ETag or Last-Modified header is recommended, so that a platform can revalidate its copy.

Firewall and bot management rules can hide the file. Google's network guide says profile discovery is a plain GET with Accept: application/json and a Request-Id, with no UCP-Agent header. It asks you to exempt /.well-known/ucp from JavaScript challenges, CAPTCHAs, browser telemetry cookies and TLS fingerprint matching.

Test your file with curl. The output below is Google's own agent profile, read on 1 November 2026. It is a platform profile, not a merchant's, but its top level has the same shape.

curl -sS https://ucp.goog/.well-known/ucp.json \
  | jq '.ucp | {version, services: (.services | keys), capabilities: (.capabilities | keys), payment_handlers: (.payment_handlers | keys)}'
{
  "version": "2026-04-08",
  "services": ["dev.ucp.shopping"],
  "capabilities": [
    "dev.ucp.common.identity_linking",
    "dev.ucp.common.loyalty",
    "dev.ucp.shopping.cart",
    "dev.ucp.shopping.catalog.lookup",
    "dev.ucp.shopping.checkout",
    "dev.ucp.shopping.discount",
    "dev.ucp.shopping.fulfillment",
    "dev.ucp.shopping.order"
  ],
  "payment_handlers": ["com.google.pay"]
}

Check the headers as well. curl -sSI https://shop.example.com/.well-known/ucp should show a 200, a JSON content-type and a public cache-control, with no redirect.

Which fields does a UCP manifest need?

The table follows release 2026-08-25.

Which fields does a UCP manifest need? — Field, Required, What it holds
Field Required What it holds
ucp.version Yes The protocol release, written YYYY-MM-DD. A value such as draft must not appear in public discovery
ucp.services Yes, may be {} A map from a reverse-domain service name to an array of transport bindings. Each binding needs version, spec and transport: rest, mcp, a2a or embedded. REST, MCP and embedded also need schema
ucp.capabilities No A map from a capability name to an array of entries, one per version. Each entry needs version, spec and schema. An extension adds extends
ucp.payment_handlers Yes, may be {} A map from a handler name, such as com.google.pay or dev.shopify.shop_pay, to an array of entries
ucp.supported_versions No A map from an older release to the URI of a complete profile for that release
keys No A JWK Set of public signing keys. The 2026-04-08 release called this array signing_keys

Names follow {reverse-domain}.{service}.{capability}. The dev.ucp.* namespace belongs to the UCP governing body, and a vendor uses its own, such as com.example.*. A schema URL must sit on the domain the name claims, so dev.ucp.shopping.checkout can point at ucp.dev but not at another domain.

What does an annotated UCP manifest look like?

This example is built from the specification's own business profile, cut to one REST service, 2 capabilities and one payment handler. The host names are placeholders.

{
  "ucp": {
    "version": "2026-08-25",
    "supported_versions": {
      "2026-04-08": "https://shop.example.com/.well-known/ucp/2026-04-08"
    },
    "services": {
      "dev.ucp.shopping": [
        {
          "version": "2026-08-25",
          "spec": "https://ucp.dev/2026-08-25/specification/overview/",
          "transport": "rest",
          "endpoint": "https://shop.example.com/ucp/v1",
          "schema": "https://ucp.dev/2026-08-25/services/shopping/rest.openapi.json"
        }
      ]
    },
    "capabilities": {
      "dev.ucp.shopping.checkout": [
        {
          "version": "2026-08-25",
          "spec": "https://ucp.dev/2026-08-25/specification/shopping/checkout",
          "schema": "https://ucp.dev/2026-08-25/schemas/shopping/checkout.json"
        }
      ],
      "dev.ucp.shopping.fulfillment": [
        {
          "version": "2026-08-25",
          "spec": "https://ucp.dev/2026-08-25/specification/shopping/extensions/fulfillment",
          "schema": "https://ucp.dev/2026-08-25/schemas/shopping/fulfillment.json",
          "extends": "dev.ucp.shopping.checkout"
        }
      ]
    },
    "payment_handlers": {
      "com.example.processor_tokenizer": [
        {
          "id": "processor_tokenizer",
          "version": "2026-08-25",
          "spec": "https://example.com/specs/payments/processor_tokenizer",
          "schema": "https://example.com/specs/payments/merchant_tokenizer.json"
        }
      ]
    }
  }
}
  1. version is the release the profile describes. It must be a date, because platforms select a release by exact match.
  2. supported_versions links older releases. Each URI must serve a complete profile whose own version equals the key, and that profile must not repeat supported_versions.
  3. services says where to send requests. endpoint is a base URL with a scheme. The paths of the linked OpenAPI file are appended to it.
  4. capabilities lists what the business supports. fulfillment extends checkout, and an extension is ignored when its parent is not in the negotiated set.
  5. payment_handlers names the payment specifications the business accepts. The registry must be present even when it is empty. The config of a handler follows that handler's own schema, so this example omits it.
  6. keys is left out here. Add it only when you sign messages or webhooks.

The release to publish depends on the platform you want to reach. On 1 November 2026 Google's own profile declares 2026-04-08, and Google's publish guides cover 2026-04-08 and 2026-01-23.

The specification says a business answers version_unsupported when the platform's version is neither its version nor a key of supported_versions. That is why the example lists 2026-04-08. This is our reading of two sources, so confirm it in Google's guide before you rely on it.

What does the ucp-manifest check read?

ucp-manifest is an unscored draft check in the commerce module. The scan asks it only when the homepage shows a commercial signal: Product markup, a priced Offer, an add-to-cart control or a cart link. A site on the publisher, services or institution site profile is out of scope for it.

It reads /.well-known/ucp, then /.well-known/ucp.json, and sorts the answer.

  • Present. A JSON object with a ucp member that states a version and at least one services or capabilities entry. A map or an array counts.
  • Defective. A 2xx answer that is not JSON, JSON without ucp, no version, or neither services nor capabilities.
  • Not served. No 2xx answer at either path, or only an HTML page, a markdown page, a redirect to the homepage or a copy of it.
  • Not measured. A request was refused, answered with a server error or timed out. A 406 to the scan's Accept header counts as a refusal.

On 1 November 2026 we ran the check on the example above. It reported "/.well-known/ucp serves a UCP profile: version 2026-08-25, 1 service, 2 capabilities."

A present result does not mean the file conforms. The check does not read payment_handlers, which the specification requires. It follows a redirect and does not read Cache-Control. It does not fetch the schema URLs or test the namespace rule.

payment-protocols reads the same 2 paths, so a valid profile makes both present.

None of our 6 stored v0.9 records, measured on 20 and 25 October 2026, shows a commercial signal. The check was out of scope on each, and the scan did not request /.well-known/ucp from those sites. The methodology explains how scope is decided.

How does Shopify use the manifest?

Shopify's profile page places a storefront's business profile at {shop}.myshopify.com/.well-known/ucp. Shopify negotiates against the agent profile that arrives with each request. The page describes no file for the merchant to write.

On 16 October 2026 Shopify's changelog said Checkout MCP and Cart MCP support the buyer consent extension, dev.ucp.shopping.buyer_consent, from UCP 2026-08-25. Storefronts list it in the profile. An agent that declares the extension must show each consent option to the buyer and send the buyer's choices.

The Global Catalog REST API stops serving traffic on 2 November 2026. Shopify names Global Catalog MCP, which implements UCP, as the replacement.

Should you publish one?

Publish a manifest only if you implement what it declares. A profile that lists a checkout the business cannot complete makes a claim you cannot back, and platforms negotiate on what the profile says. If you run Shopify, check the URL above before you write anything.

Product data comes first. An agent that cannot read your price, stock and return terms gains nothing from a manifest, as the comparison of protocols argues. Check product-schema before you build a UCP endpoint. Then scan your domain to see whether the ucp-manifest check is asked of it.