Sichta · Guides
What a UCP manifest is, and when publishing one is the wrong move
Published August 19, 2026
A UCP manifest is a JSON file at /.well-known/ucp that tells AI shopping agents what your store can do and where to call it. It is not a marketing file and not a token gesture — it declares live API endpoints and the public keys used to verify your signed messages. This guide covers what the file contains, what it does not, how to serve it from Shopify, and when publishing one is the wrong move.
What UCP is
The Universal Commerce Protocol is an open standard, published by Google under Apache 2.0, for machine-readable merchant discovery. Where llms.txt and agents.md describe a business in prose an assistant can quote, UCP describes an interface: the services an agent can call to browse, check out, and track an order without a human in the loop.
The discovery entry point is a single well-known URL. An agent fetches https://your-store.example/.well-known/ucp, reads the JSON, and learns which protocol version you speak, which endpoints to talk to, and how to verify that messages claiming to come from you actually did.
What the file must contain
Two required top-level keys: ucp and signing_keys.
ucp.version— the protocol version, as a date:"2026-04-08". UCP versions are dates, not semver.ucp.services— a map from a service identifier such asdev.ucp.shoppingto its transport bindings: version, spec URL, transport (rest,mcp,a2a, orembedded), schema URL, and theendpointan agent should call.ucp.capabilities— a map of features within those services, such asdev.ucp.shopping.checkout, each with its own version and schema. Extensions declare their parent capability.signing_keys— public keys in JWK format, used to verify webhooks and authenticated messages you sign (RFC 9421 HTTP Message Signatures). The specification lists this at the top level, but note that Shopify's own generated manifests omit it entirely — so treat its absence as normal rather than as a defect you need to fix.
ucp.payment_handlers is optional. If you support more than one protocol version, a supported_versions map points at version-specific profile URLs.
A minimal valid manifest
{
"ucp": {
"version": "2026-04-08",
"services": {
"dev.ucp.shopping": [{
"version": "2026-04-08",
"spec": "https://ucp.dev/2026-04-08/specification/overview",
"transport": "rest",
"endpoint": "https://business.example.com/ucp/v1",
"schema": "https://ucp.dev/2026-04-08/services/shopping/rest.openapi.json"
}]
},
"capabilities": {
"dev.ucp.shopping.checkout": [{
"version": "2026-04-08",
"spec": "https://ucp.dev/2026-04-08/specification/checkout",
"schema": "https://ucp.dev/2026-04-08/schemas/shopping/checkout.json"
}]
}
},
"signing_keys": [{
"kid": "business_2026",
"kty": "EC", "crv": "P-256", "use": "sig", "alg": "ES256",
"x": "…", "y": "…"
}]
}
Note what that endpoint implies. It is a live URL an agent will call. A manifest is a promise about infrastructure that has to exist.
On Shopify, you already have one
This is the part most guides get wrong. Shopify co-developed UCP with Google and turns it on for stores by default, so your storefront already serves a manifest at /.well-known/ucp without you configuring anything. Check your own:
curl -sSL https://your-store.example/.well-known/ucp | jq .
A live Shopify manifest declares an mcp transport pointing at https://your-store.myshopify.com/api/ucp/mcp, a supported_versions map, capabilities including checkout, cart, fulfillment, discount, order and catalog search and lookup, and payment handlers such as Google Pay and Shop Pay. You do not write any of that, and you should not try to replace it.
So on Shopify the work is verification, not authoring: confirm the file resolves on your live domain, that it survives whatever sits in front of your store, and that nothing you added is blocking it. The cases where you do author one yourself are headless builds and custom front ends, where you control the web server and the platform is not serving the path for you. There, a URL redirect or an app proxy is the usual route, and everything above about declaring only endpoints that answer applies.
When not to publish one
An empty or invented manifest is worse than no manifest. If services lists an endpoint that does not answer, an agent discovers you, calls it, and fails — a worse outcome than a clean 404, which tells it immediately to fall back to reading your pages.
This applies to sites that are not storefronts at all. Our own marketing site returns 404 at /.well-known/ucp and that is deliberate: it sells nothing, so there is no endpoint to declare, and the specification has no way to say "I am not a merchant". A stub that exists only to make a checker go green is a checkbox, not readiness.
How to check yours
Three things, in order: the file returns 200 to an unauthenticated client, its body parses as JSON, and every URL in services resolves. Sichta's Pillar A checks the first two as check A1 and reports the result separately from your other agent-readiness findings, so a missing manifest is a specific line item rather than a number to interpret.
The specification is still moving — versions are dates and the schema is evolving — so treat the manifest as something you regenerate, not something you write once and forget.
The short version
Publish a UCP manifest when you have a commerce endpoint an agent can actually call. Serve it at /.well-known/ucp as unauthenticated JSON, declare a real endpoint and real signing_keys, and verify it with a plain HTTP client rather than a browser. If you do not have that infrastructure yet, a 404 is the honest answer, and llms.txt plus agents.md are where your effort pays off today.
One scan from now, you'll know.
Run the free scan and see exactly how ready your store is for AI shopping agents.
Scan my store — free