On January 11, 2026, Google announced UCP (Universal Commerce Protocol), an open-source standard aimed at fostering interoperability between AI agents and various retail systems.
Without immediately diving into technical details, the protocol enables AI agents to search for products and complete related purchases using natural language.
The protocol was developed by Google in collaboration with major industry leaders such as Shopify, with the support of over 20 global partners including American Express, Mastercard, Stripe, Visa, Zalando, and many others:

Only a few days have passed and several articles have followed on the topic, clearly describing the context and the promise of an unprecedentedly seamless shopping experience, but they did not delve into two particular points that remained unclear to me:
- The discovery mechanism: how does an AI agent “discover” which merchants support UCP? What is the technical flow that connects the user’s request (“buy a suitcase”) to the servers of the various merchants?
- The degree of autonomy: is the purchase truly fully autonomous, or does it require human intervention? And if so, at which stages?
Part 1: Understanding UCP
Before UCP, any AI platform that wanted to enable purchases had to build custom integrations with each merchant.
This resulted in N×N complexity: N agents interacting with N merchants, each with different APIs, checkout flows, and payment method handling, even when considering reusable “standard” system families.
The new protocol, instead, introduces a common language.
A merchant implements UCP once, and any compatible agent can interact with them; similarly, an agent implements UCP once and can communicate with any compatible merchant.

UCP is designed as a layered protocol, inspired by the TCP/IP philosophy:
- Shopping Service: basic primitives (checkout session, line items, totals, messages, status)
- Capabilities: main functionalities such as Checkout and Order
- Extensions: optional modules that extend the capabilities (discounts, loyalty)
This separation allows the protocol to evolve without breaking existing implementations.
A merchant can support only what they actually need (e.g., no loyalty), and the agent dynamically negotiates what both support.
The discovery mechanism: the missing piece
And here we come to the first point I wanted to clarify.
UCP does not define how an agent discovers merchants, only what happens after the merchant has been identified.
This is a crucial point: implementing UCP on your site is not enough to be “discovered” by agents; an external discovery layer is required. In Google’s case, this is the Merchant Center; in Shopify’s case, it’s their Catalog.
For independent merchants, how this aspect will evolve is still undefined, but presumably GEO (Generative Engine Optimization) will become increasingly relevant.
In the Google ecosystem, effectively the first to implement UCP, discovery occurs through the Merchant Center, with a flow as shown in the example video below:
It is already possible today to join the waitlist to be among the first to implement this technology, provided, however (as of January 18), that you are a seller fulfilling orders from the United States and have a bank account in the United States.
Shopify (co-developer of the UCP initiative) has solved the discovery problem differently through Agentic Storefronts, a layer that automatically exposes Shopify merchants to ChatGPT, Microsoft Copilot, Perplexity, and soon Google AI Mode.
The degree of autonomy
And now we can answer (at least partially) the second question: what is the degree of autonomy of the procedure?
The UCP standard allows for fully autonomous purchases, explicitly defining a “Scenario C: Autonomous Agent” where the agent completes the entire checkout without human intervention, using pre-authorized cryptographic mandates (AP2 protocol, Agent Payments Protocol).
Google’s implementation, however, requires manual intervention, as clearly stated in the Google documentation:
Manual checkout: The user now interacts only with the Google UI to fill in sensitive fulfillment and payment details and submit the order.
The Agent is not involved in this part, ensuring determinism.
So the agent takes you up to the checkout threshold, then hands over the process: it’s not an autonomous purchase but an assisted one, at least for now, which is probably the wisest choice to manage the entire process with greater trust.
Now let’s see concretely how the protocol works, diving a bit deeper into the details.
Part 2: Technical deep dive
Let’s go a bit deeper by cross-referencing the official documentation and the GitHub page with the reference implementation.
This part of the article is intended for tech professionals or those more interested in these detailed aspects. It assumes that a Python development environment is already available, as we will adapt the official server behavior example, simulating the interface and the response that a merchant’s website must expose.
Let’s start by cloning the official repository:
mkdir sdk
git clone https://github.com/Universal-Commerce-Protocol/python-sdk.git sdk/python
pushd sdk/python
uv sync
popd
git clone https://github.com/Universal-Commerce-Protocol/samples.git
cd samples/rest/python/server
uv syncThis will set up both the Python SDK and the FastAPI-based environment with the examples.
If you want to customize some products before importing them into the local database, you can do so now by editing the contents of the CSV files in the samples/rest/python/test_data/flower_shop folder. In our example, we will modify the product titles in the products.csv file.
Let’s now start the creation of the local databases:
mkdir /tmp/ucp_test
uv run import_csv.py \
--products_db_path=/tmp/ucp_test/products.db \
--transactions_db_path=/tmp/ucp_test/transactions.db \
--data_dir=../test_data/flower_shopNote how the /tmp/ucp_test folder is now hosting the DB files temporarily; consider using a different folder if you require persistence.
Let’s now start the local server:
uv run server.py \
--products_db_path=/tmp/ucp_test/products.db \
--transactions_db_path=/tmp/ucp_test/transactions.db \
--port=8182 & SERVER_PID=$!
Which will respond with something like:
[1] 1532
% INFO: Started server process [1533]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:8182 (Press CTRL+C to quit)Now our server is running and we can simulate a client using the 🔗 attached Postman project, which for readability reasons is more convenient than invoking the services from the command line.
Discovery
Sites that support UCP define it through a standard JSON manifest exposed at the /.well-known/ucp path.
This URL allows agents to dynamically discover features, endpoints, and payment configurations without hard-coded integrations, BUT as already seen in the section “The discovery mechanism: the missing piece”, they must know the website URL in advance.
We can query the capabilities of our server by executing the “1. Discovery” request in the Postman project.
The response is a JSON that fully describes the server’s capabilities. The structure is quite articulated, so let’s focus only on two elements in particular to understand the flow: services and capabilities.
Services: where and how to communicate
"services": {
"dev.ucp.shopping": {
"version": "2026-01-11",
"spec": "https://ucp.dev/specification/reference",
"rest": {
"schema": "https://ucp.dev/services/shopping/openapi.json",
"endpoint": "http://localhost:8182/"
},
"mcp": null,
"a2a": null,
"embedded": null
}
}This section declares the available communication channels:
| Field | Meaning |
|---|---|
rest.schema | OpenAPI spec to validate requests/responses |
rest.endpoint | Base URL for REST API calls |
mcp | Model Context Protocol endpoint (if supported) |
a2a | Agent2Agent endpoint (if supported) |
embedded | Support for Embedded Checkout Protocol (if supported) |
In this example, the merchant supports only REST.
A more advanced merchant could expose the same service over multiple transports, leaving the agent to choose the preferred channel.
Capabilities: what the merchant can do
"capabilities": [
{
"name": "dev.ucp.shopping.checkout",
"version": "2026-01-11",
"spec": "https://ucp.dev/specification/checkout",
"schema": "https://ucp.dev/schemas/shopping/checkout.json",
"extends": null,
"config": null
},
{
"name": "dev.ucp.shopping.order",
"version": "2026-01-11",
"spec": "https://ucp.dev/specification/order",
"schema": "https://ucp.dev/schemas/shopping/order.json",
"extends": null,
"config": null
},
{
"name": "dev.ucp.shopping.discount",
"version": "2026-01-11",
"spec": "https://ucp.dev/specification/discount",
"schema": "https://ucp.dev/schemas/shopping/discount.json",
"extends": "dev.ucp.shopping.checkout",
"config": null
},
... OMISSIS ...
]Capabilities are the functional building blocks of UCP; the extends field determines whether it is a standalone feature or an extension:
Standalone capabilities (extends: null, do not extend anything, are root and exist on their own):
dev.ucp.shopping.checkout: manages checkout sessionsdev.ucp.shopping.order: manages order lifecycle
Extensions (extends points to a parent capability on which it depends):
dev.ucp.shopping.discount: extendscheckout, adds discount code managementdev.ucp.shopping.fulfillment: extendscheckout, adds shipping optionsdev.ucp.shopping.buyer_consent: extendscheckout, adds explicit consent management
The mechanism works like this: an extension cannot exist without its parent capability.
If the agent does not support checkout, all extensions that extend it (discount, fulfillment, buyer_consent) are automatically excluded from the negotiation.
This allows for a modular composition: a merchant can support the basic checkout without discounts, or add only the extensions they need.
The agent, by comparing this list with its own capabilities, determines what both sides can handle.
Session management
We can start creating a session by executing the “2. Capabilities & Extensions” request in the Postman project.
After the invocation, the merchant responds with the initialized session:
{
... OMISSIS ...
"id": "42b9bc87-4477-46d3-83c0-a59c059e110d",
"line_items": [
{
"id": "1bd97562-b8b4-4e64-87f9-fe83096a8cb3",
"item": {
"id": "bouquet_roses",
"title": "Mazzo di rose rosse",
"price": 3500,
"image_url": null
},
"quantity": 1,
"totals": [
{
"type": "subtotal",
"display_text": null,
"amount": 3500
},
{
"type": "total",
"display_text": null,
"amount": 3500
}
],
"parent_id": null
}
],
"buyer": {
... OMISSIS ...
},
"status": "ready_for_complete",
"currency": "EUR",
"totals": [
{
"type": "subtotal",
"display_text": null,
"amount": 3500
},
{
"type": "total",
"display_text": null,
"amount": 3500
}
],
... OMISSIS ...Note the id field, which contains the checkout ID, in our example, 42b9bc87-4477-46d3-83c0-a59c059e110d and the partial order total in totals.
We can update the session, for example by applying a coupon since our server supports this capability, by executing the “3. Example of Discount Extension” request in the Postman project. Make sure to replace the checkout ID in the URL /checkout-sessions/CHECKOUT_ID with the one returned from the session creation.
WARNING: You can make multiple invocations of the various services, but you must change the idempotency-key value in the header, otherwise you will get an error in the form:
{
"detail": "Idempotency key reused with different parameters",
"code": "IDEMPOTENCY_CONFLICT"
}Returning to our example, after applying the discount code we will see the new total updated accordingly.
"totals": [
{
"type": "subtotal",
"display_text": null,
"amount": 3500
},
{
"type": "discount",
"display_text": null,
"amount": 350
},
{
"type": "total",
"display_text": null,
"amount": 3150
}
]It is not clear how the agent should know the discount code in advance, but it is easy to deduce that this component will still be tied to the human interaction present in the flow.
To complete the process, it is then necessary to provide shipping data (fulfillment, Postman request “4. Fulfillment”) and finalize the order with payment details (Postman request “5. Payment”).
In the Google scenario, both steps are outside the automated process.
In the folder samples/rest/python/client/flower_shop of the test project, a demo client is available that simulates the entire purchase process and can be executed with:
cd samples/rest/python/client/flower_shop/
uv sync
uv run simple_happy_path_client.py --server_url=http://localhost:8182Conclusion
Returning to the two initial questions:
On discovery: UCP standardizes transactions, not merchant discovery.
Implementing the protocol on your site is not enough; you need to be indexed in a catalog (Google Merchant Center, Shopify Catalog, or future equivalents).
For independent merchants, this means that GEO (Generative Engine Optimization) will likely become a requirement, not an option.
On agent autonomy: there is a significant difference between what the standard allows and what current implementations do/will do.
UCP supports fully autonomous purchases via AP2 and cryptographic mandates; Google has chosen a more conservative approach with manual confirmation.
And the Agentic Commerce Protocol by OpenAI?
It is worth noting that OpenAI has published its own standard, the Agentic Commerce Protocol (ACP), with similar goals but a different architecture.
We are therefore facing two standards that are either competing or potentially complementary.
One thing is certain: agentic commerce is no longer science fiction; the question is not if it will arrive, but how quickly and who will be ready to intercept it.
