AI has reshaped how we explore and interact with the digital world. But when it comes to shopping, it’s mostly stayed on the sidelines. You can tell an AI agent you want to buy a PS5, and it will surface a few online stores. After that, though, you’re on your own – switching tabs, navigating product pages, and filling out checkout forms yourself.
The Universal Commerce Protocol (UCP) changes that dynamic. It turns AI agents from passive recommenders into active participants in commerce. Instead of just pointing you somewhere, an agent can browse, select, and complete a purchase on your behalf. UCP is the standardized language that makes this interaction possible between agents and merchants.
By the end of this guide, you’ll understand how UCP works under the hood, how agents and merchants connect, how to integrate UCP into your e-commerce stack, and how to implement product discovery, cart management, and checkout flows that actually function in real-world scenarios.
The Replay is a weekly newsletter for dev and engineering leaders.
Delivered once a week, it's your curated guide to the most important conversations around frontend dev, emerging AI tools, and the state of modern software.
To understand UCP, start with the gap it fills. If we want true agentic commerce, an AI can’t just browse pages and return links. That’s still surface-level interaction. It needs a structured, reliable way to talk directly to e-commerce systems and payment providers.
UCP addresses this by defining a standardized communication layer between AI shopping agents and online merchants. Instead of guessing how a store works, the agent follows a shared protocol.
Now, let’s go a level deeper and look at how UCP actually works in practice.
UCP works through the following parts:
Let’s dig into how UCP works in practice. We’ll walk through the flow step by step and break down what’s happening under the hood.
Before anything happens, the AI agent needs clarity. It has to know who the merchant is, what services are available, and how to communicate with them at a technical level.
To get that information, the agent retrieves the merchant’s Business Profile – a plain JSON document that outlines supported services, capabilities, and endpoints.
We’ll break down the structure of the UCP Business Profile in more detail later in the article.
Now imagine a shopper types: “Find me a pair of blue running shoes under $150.”
The agent doesn’t just search the web. It consults the catalog exposed through the Business Profile.
It extracts the relevant details from the request – color, category, price limit and structures them into a JSON payload, and sends that to the merchant’s backend.
The backend responds with a structured list of matching products. No scraping. No guesswork.
Once the shopper selects an item, the agent uses the cart_management capability to handle cart operations.
It can:
All of this happens through defined UCP endpoints, keeping the session state in sync.
When the buyer is ready to pay, UCP uses the Agent Payments Protocol (AP2).
The agent requests a one-time payment token from a trusted provider such as Google Pay. That token is securely generated and sent to the merchant, who processes the charge through their payment processor.
The agent never handles raw payment credentials directly – everything is tokenized and verified.
Agentic commerce starts with a handshake between two key documents: the Business Profile and the Platform Profile.
Let’s break down what each one does.
First up, the Business Profile. It’s a JSON file that every merchant posts at a standard web address. It gives an overview of which services(such as REST APIs) are running, what their capabilities or features are, and where to find more information.
Take a look at a sample business profile JSON below:
{
"ucp": {
"version": "2026-01-23",
"services": {
"dev.ucp.shopping": [
{
"version": "2026-01-23",
"spec": "<https://ucp.dev/specification/overview>",
"transport": "rest",
"endpoint": "<https://business.example.com/ucp/v1>",
"schema": "<https://ucp.dev/2026-01-23/services/shopping/rest.openapi.json>"
},
{
"version": "2026-01-23",
"spec": "<https://ucp.dev/specification/overview>",
"transport": "mcp",
"endpoint": "<https://business.example.com/ucp/mcp>",
"schema": "<https://ucp.dev/2026-01-23/services/shopping/mcp.openrpc.json>"
},
{
"version": "2026-01-23",
"spec": "<https://ucp.dev/specification/overview>",
"transport": "a2a",
"endpoint": "<https://business.example.com/.well-known/agent-card.json>"
},
{
"version": "2026-01-23",
"spec": "<https://ucp.dev/specification/overview>",
"transport": "embedded",
"schema": "<https://ucp.dev/2026-01-23/services/shopping/embedded.openrpc.json>"
}
]
},
"capabilities": {
"dev.ucp.shopping.checkout": [
{
"version": "2026-01-23",
"spec": "<https://ucp.dev/specification/checkout>",
"schema": "<https://ucp.dev/2026-01-23/schemas/shopping/checkout.json>"
}
],
"dev.ucp.shopping.fulfillment": [
{
"version": "2026-01-23",
"spec": "<https://ucp.dev/specification/fulfillment>",
"schema": "<https://ucp.dev/2026-01-23/schemas/shopping/fulfillment.json>",
"extends": "dev.ucp.shopping.checkout"
}
],
"dev.ucp.shopping.discount": [
{
"version": "2026-01-23",
"spec": "<https://ucp.dev/specification/discount>",
"schema": "<https://ucp.dev/2026-01-23/schemas/shopping/discount.json>",
"extends": "dev.ucp.shopping.checkout"
}
]
},
"payment_handlers": {
"com.example.processor_tokenizer": [
{
"id": "processor_tokenizer",
"version": "2026-01-23",
"spec": "<https://example.com/specs/payments/processor_tokenizer>",
"schema": "<https://example.com/specs/payments/merchant_tokenizer.json>",
"config": {
"type": "CARD",
"tokenization_specification": {
"type": "PUSH",
"parameters": {
"token_retrieval_url": "<https://api.psp.example.com/v1/tokens>"
}
}
}
}
]
}
},
"signing_keys": [
{
"kid": "business_2025",
"kty": "EC",
"crv": "P-256",
"x": "WbbXwVYGdJoP4Xm3qCkGvBRcRvKtEfXDbWvPzpPS8LA",
"y": "sP4jHHxYqC89HBo8TjrtVOAGHfJDflYxw7MFMxuFMPY",
"use": "sig",
"alg": "ES256"
}
]
}
In the above, the business profile specifies the UCP version it supports. It then goes on to state the transport services for UCP it supports: in the example JSON file, REST API, MCP, a2a, and embedded are the supported transport services. There is also an endpoint for the various transport methods. Finally, there are links to schemas for the AI to use when rendering results from the endpoints.
There are also the capabilities that the business supports. The sample JSON above supports checkout, fulfillment, and discounts.
The Platform Profile specifies the tasks the AI agent is able to perform and the payment method it can initiate.
Let’s check out a sample JSON file for a platform profile below:
{
"ucp": {
"version": "2026-01-23",
"services": {
"dev.ucp.shopping": [
{
"version": "2026-01-23",
"spec": "<https://ucp.dev/specification/overview>",
"transport": "rest",
"schema": "<https://ucp.dev/2026-01-23/services/shopping/rest.openapi.json>"
}
]
},
"capabilities": {
"dev.ucp.shopping.checkout": [
{
"version": "2026-01-23",
"spec": "<https://ucp.dev/specification/checkout>",
"schema": "<https://ucp.dev/2026-01-23/schemas/shopping/checkout.json>"
}
],
"dev.ucp.shopping.fulfillment": [
{
"version": "2026-01-23",
"spec": "<https://ucp.dev/specification/fulfillment>",
"schema": "<https://ucp.dev/2026-01-23/schemas/shopping/fulfillment.json>",
"extends": "dev.ucp.shopping.checkout"
}
],
"dev.ucp.shopping.order": [
{
"version": "2026-01-23",
"spec": "<https://ucp.dev/specification/order>",
"schema": "<https://ucp.dev/2026-01-23/schemas/shopping/order.json>",
"config": {
"webhook_url": "<https://platform.example.com/webhooks/ucp/orders>"
}
}
]
},
"payment_handlers": {
"com.google.pay": [
{
"id": "gpay_1234",
"version": "2024-12-03",
"spec": "<https://developers.google.com/merchant/ucp/guides/gpay-payment-handler>",
"schema": "<https://pay.google.com/gp/p/ucp/2026-01-23/schemas/gpay_config.json>"
}
],
"dev.shopify.shop_pay": [
{
"id": "shop_pay_1234",
"version": "2026-01-23",
"spec": "<https://shopify.dev/ucp/shop-pay-handler>",
"schema": "<https://shopify.dev/ucp/schemas/shop-pay-config.json>"
}
],
"dev.ucp.processor_tokenizer": [
{
"id": "processor_tokenizer",
"version": "2026-01-23",
"spec": "<https://example.com/specs/payments/processor_tokenizer-payment>",
"schema": "<https://ucp.dev/2026-01-23/schemas/payments/delegate-payment.json>"
}
]
}
},
"signing_keys": [
{
"kid": "platform_2025",
"kty": "EC",
"crv": "P-256",
"x": "MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4",
"y": "4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM",
"use": "sig",
"alg": "ES256"
}
]
}
In the platform profile JSON file, the AI agent specifies the UCP version it understands. It also declares the shopping capabilities it supports, such as checkout, fulfillment, and order. The file lists the payment methods the agent can handle, like Google Pay and Shop Pay, and includes the public keys used for signing its communications.
If you want to implement UCP on your e-commerce marketplace, this is a high-level overview of what you would do.
Discovery is the first step for any UCP integration. This is where the server broadcasts its identity and supported features:
app.get("/.well-known/ucp", (context) => {
return json({
business_profile: {
name: "UCP Demo Server",
ucp: {
version: "2026-01-11",
services: {
"dev.ucp.shopping": { endpoint: BASE_URL }
},
capabilities: ["checkout", "order", "fulfillment"]
}
}
})
})
The /.well-known/ucp endpoint is where our business profile is. AI agents hit this endpoint to find out where the shopping services live and what features you have.
The checkout session is initiated with a session to hold the cart, buyer information, and discount:
app.post("/checkout-sessions", (request) => {
const session = CheckoutService.createSession()
if (request.body.line_items) session.updateItems(request.body.line_items)
if (request.body.buyer) session.setBuyer(request.body.buyer)
return json(transformToUCP(session), 201)
})
Unlike traditional APIs that might require a full payload upfront, UCP allows us to start with an empty session and gradually build it. We use a service layer to abstract the session persistence, returning a protocol-compliant JSON representation to the client.
Instead of separate endpoints for every minor change, we use a single PUT endpoint to sync the session state:
app.put("/checkout-sessions/:id", (request) => {
const session = CheckoutService.getSession(id)
if (!session || session.isClosed()) return error("Session unavailable", 404)
if (request.body.line_items) session.updateItems(request.body.line_items)
if (request.body.fulfillment) session.updateFulfillment(request.body.fulfillment)
return json(transformToUCP(session))
})
The PUT endpoint handles patch-like updates. If the user changes their zip code, we update the fulfillment object; if they add an item, we update the cart.
Once the session or shopping is complete, we transition from a transient checkout state to a permanent order object:
app.post("/checkout-sessions/:id/complete", (request) => {
const session = CheckoutService.complete(id)
const order = OrderService.createFromCheckout(session)
const response = transformToUCP(session)
response.order = transformToUCP(order)
return json(response)
})
We mark the session as final to prevent further edits and to instantiate a permanent Order.
The response includes both the final checkout state and the new order details.
Once an order exists, it follows its own lifecycle, primarily focused on retrieval and cancellations:
app.get("/orders/:id", (id) => {
const order = OrderService.get(id)
return json(transformToUCP(order))
})
// Endpoint: POST /orders/:id/cancel
app.post("/orders/:id/cancel", (id) => {
const success = OrderService.cancel(id)
return success ? noContent() : error("Cancellation failed", 400)
})
After checkout, the interaction shifts to the Order resource. These endpoints allow clients to track the status of their purchase or initiate a cancellation if supported by the merchant’s business rules.
The above is a high-level overview of a UCP compliant nodejs backend.
This example illustrates how a server can:
All while communicating through the standardized UCP format.
You can find the codebase here.
Let’s go ahead and run a sample from Google to demonstrate how this works.
We will run the Agent-to-Agent (A2A) sample, which simulates a user interacting with a business through a chat interface.
To run this, ensure you have the following prerequisites installed:
First, clone the sample repo with the following command:
git clone <https://github.com/Universal-Commerce-Protocol/samples.git>
Navigate into the business agent’s directory:
cd a2a/business_agent
Next, install the required Python dependencies using uv
uv sync
Now, create a local environment file from the example template:
cp env.example .env
Open the .env file and add your Gemini API key to the GOOGLE_API_KEY variable.
Finally, start the business agent server. This will expose the UCP endpoints that the chat client will interact with.
uv run business_agent
Keep this terminal window open, as the backend server needs to remain running.
Open a new terminal window and navigate to the chat-client directory:
cd a2a/chat-client
Install the necessary Node.js packages:
npm install
Once the installation is complete, start the development server:
npm run dev
Go ahead and open the link in the browser. In the chat input field, type the following prompt and press Enter:
“Show me cookies available in stock.”

UCP represents a real shift in how commerce works in an AI-driven world.
By introducing a standardized way for AI agents to discover, interact with, and transact with online merchants securely, UCP moves us closer to a future where shopping feels as simple as having a conversation.
In this guide, we covered the core ideas behind UCP, from the handshake between agents and merchants to the mechanics that enable agentic commerce. We also walked through a high-level implementation of a UCP-compliant backend in Node.js to see how it all comes together in practice.

React Server Components and the Next.js App Router enable streaming and smaller client bundles, but only when used correctly. This article explores six common mistakes that block streaming, bloat hydration, and create stale UI in production.

Gil Fink (SparXis CEO) joins PodRocket to break down today’s most common web rendering patterns: SSR, CSR, static rednering, and islands/resumability.

@container scroll-state: Replace JS scroll listeners nowCSS @container scroll-state lets you build sticky headers, snapping carousels, and scroll indicators without JavaScript. Here’s how to replace scroll listeners with clean, declarative state queries.

Explore 10 Web APIs that replace common JavaScript libraries and reduce npm dependencies, bundle size, and performance overhead.
Hey there, want to help make our blog better?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up now