Agentic commerce (UCP)
What the Universal Commerce Protocol is, what Monokaido supports, and how an AI agent's purchase runs from product search to the order.
On this page
The Universal Commerce Protocol (UCP)
is an open protocol through which AI agents and commerce platforms find a
shop, read its catalog and prepare a purchase for a person. The shop publishes
a machine-readable profile at a fixed address on its own domain; the agent
reads it, learns which capabilities the shop offers, and then talks to the
shop's REST API. A Monokaido shop whose merchant switched UCP on answers that
protocol, version 2026-04-08, on its own custom domain.
What an agent can do in a Monokaido shop
- Discover the shop.
GET https://shop.example.com/.well-known/ucpreturns the business profile: the protocol version, the REST endpoint and the capabilities on offer. No header and no credential are needed. - Read the catalog. Search by text (with an optional price filter), look
up as many as 20 products or variants at once by id, SKU or handle, and read
one product in detail with the variant that matches a choice of options
(
Color: Black,Size: M). Prices, stock status, images and descriptions are the ones the shop shows, in the shop's languages. - Build a cart. The shop prices it with its own rules: its prices with VAT, its markup rules, its stock and its discount codes.
- Prepare a checkout. From the cart or straight from line items, with the buyer's e-mail, a shipping address and one of the shop's shipping methods, each with its fee.
- Hand the buyer over. Every open cart and checkout carries a
continue_url, which you give the buyer once the checkout is ready. The buyer opens it in a browser, the items and the applied discount code land in their cart on the shop, and the shop's own checkout opens (for a cart, the shop's cart page). - Learn the outcome. Once the buyer has ordered, the next read of the
checkout returns
completedwith the order's id, number and a confirmation link.
What an agent cannot do
These are deliberate limits of the implementation. Plan your product around them rather than discovering them in production.
- No payment goes through UCP. The profile and every checkout carry
payment_handlers: {}.POST …/completeplaces no order and changes nothing. The buyer always pays on the shop's own website, with the shop's own payment methods. - The buyer finishes on the shop. Only the items and the applied discount
code travel with the
continue_url. The buyer's e-mail, address and shipping choice stay in the UCP session; the buyer enters them again on the shop's checkout, where they may also change the order. - No push. There are no webhooks and no order capability. Poll the checkout to learn whether an order was placed.
- No sign-in for the buyer. Every session is anonymous (no identity linking). A buyer who is signed in to the shop in the same browser tab gets the items in their customer cart.
- One discount code per cart or checkout, one shipping option per checkout, no pickup-point choice (the buyer picks the point on the shop), no category filter in the catalog (a request that names a category is refused).
- REST only. No MCP, A2A or embedded transport.
- A shop in catalog mode offers catalog search and lookup only — no cart, no checkout.
The full comparison with the specification is in UCP conformance.
The purchase at a glance
Agent / platform → Shop (UCP API):
GET /.well-known/ucpReads the shop’s business profile: the protocol version, the REST endpoint and the capabilities the shop offers. No headers needed; the answer may be cached for five minutes.
Agent / platform → Shop (UCP API):
POST /ucp/v1/catalog/searchSearches the shop’s catalog (lookup and product read items by id). Every /ucp/v1 call carries the UCP-Agent header with the platform’s profile URL.
Agent / platform → Shop (UCP API):
POST /ucp/v1/cartsCreates a cart the shop prices — its own prices, stock and discounts. A cart lives 7 days from its last change.
Agent / platform → Shop (UCP API):
POST /ucp/v1/checkout-sessionsincompleteCreates a checkout from the cart (cart_id) or straight from line_items. While something is missing its status is incomplete.
Agent / platform → Shop (UCP API):
PUT /ucp/v1/checkout-sessions/{id}requires_escalationAdds the buyer’s e-mail and, with the fulfillment extension, the address and the shipping option. When nothing is missing: requires_escalation with the message payment_required and a continue_url.
Agent / platform → Buyer (browser):
continue_urlGives the buyer the continue_url. Monokaido takes no payment through UCP, and POST …/complete does not complete the checkout.
Buyer (browser) → Shop (UCP API):
GET /ucp/continue/{token}Opens continue_url on the shop’s domain. The page moves the lines and the discount code into the buyer’s cart in this browser and opens the shop’s checkout.
Buyer (browser) → Shop (UCP API):
/checkoutFinishes the purchase on the shop’s checkout, payment included — like any other customer.
Agent / platform → Shop (UCP API):
GET /ucp/v1/checkout-sessions/{id}completedOnce an order holds at least one of the session’s items, the next read of the checkout returns completed with the order. There are no webhooks: read to learn the outcome.
A cart’s continue_url (no checkout) works the same way, except that it opens the shop’s cart instead of the checkout.
The agent never holds the buyer's money or card. It prepares the basket and the details; the decision and the payment stay with the buyer, on the shop.
Who reads what
Merchants
- Turning UCP on for a shop — what the shop needs, where the switch is, how to check it works and what changes for customers.
- UCP FAQ — payments, orders, data, and what to do when something does not show up.
Developers of an agent or a platform
- Developer quickstart — a whole purchase step by step in curl, JavaScript and Python.
- Concepts and lifecycle — the profile, the
UCP-Agentheader, capability negotiation, carts and checkouts, statuses, money and languages. - API reference (OpenAPI) — every endpoint, header, field and response.
- Errors and messages — every code and what a client should do about it.
- Idempotency, concurrency and limits — retries, concurrent writes, rate limits and lifetimes.
- Security and data protection — what is stored, for how long, and what protects it.
- UCP conformance — where the implementation follows the specification and where it departs from it.
- UCP FAQ — short answers with links to the detail.
AI agents
For AI agents — the rules an agent should follow in a shop, and tool definitions ready for function calling.
Machine-readable resources
Everything on these pages is also available in a form a tool or a language model can read directly.
The whole UCP API to import into Swagger Editor, Postman, Insomnia or openapi-generator — by URL or as a file.
https://help.monokaido.com/ucp/ openapi.json The same document in YAML, for tools and reviews that prefer it.
https://help.monokaido.com/ucp/ openapi.yaml Tool definitions for a language model’s function calling, mapped onto the UCP operations.
https://help.monokaido.com/ucp/ tools.json The whole UCP developer guide as one Markdown file, for a language model’s context.
https://help.monokaido.com/ucp/ llms-full.txt The contents of the whole manual for language models, in the llms.txt format.
https://help.monokaido.com/llms.txt
Protocol version
Monokaido implements UCP 2026-04-08 and only that version. The shop
reads your platform profile (and caches it) and requires its ucp.version to
be exactly 2026-04-08; any other date, older or newer, is refused with
422 version_unsupported (a value that is not a date makes the profile
profile_malformed). A capability your profile lists only at another version
is not negotiated. The capabilities a shop can offer
are dev.ucp.shopping.catalog.search, dev.ucp.shopping.catalog.lookup,
dev.ucp.shopping.cart, dev.ucp.shopping.checkout, and the extensions
dev.ucp.shopping.fulfillment (shipping on checkouts) and
dev.ucp.shopping.discount (codes on carts and checkouts). The shop's own
profile always says which of them it offers right now.
A 30-second taste
The business profile is public and needs no header. Ask any shop that has UCP switched on:
curl -s https://shop.example.com/.well-known/ucp
const res = await fetch('https://shop.example.com/.well-known/ucp');
const profile = await res.json();
const [rest] = profile.ucp.services['dev.ucp.shopping'];
console.log(rest.endpoint, Object.keys(profile.ucp.capabilities));
import requests
profile = requests.get("https://shop.example.com/.well-known/ucp", timeout=10).json()
rest = profile["ucp"]["services"]["dev.ucp.shopping"][0]
print(rest["endpoint"], list(profile["ucp"]["capabilities"]))
A shop that takes orders answers 200 with Cache-Control: public, max-age=300
and this body:
{
"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://shop.example.com/ucp/v1",
"schema": "https://ucp.dev/2026-04-08/services/shopping/rest.openapi.json"
}
]
},
"capabilities": {
"dev.ucp.shopping.catalog.search": [
{
"version": "2026-04-08",
"spec": "https://ucp.dev/2026-04-08/specification/catalog/search",
"schema": "https://ucp.dev/2026-04-08/schemas/shopping/catalog_search.json"
}
],
"dev.ucp.shopping.catalog.lookup": [
{
"version": "2026-04-08",
"spec": "https://ucp.dev/2026-04-08/specification/catalog/lookup",
"schema": "https://ucp.dev/2026-04-08/schemas/shopping/catalog_lookup.json"
}
],
"dev.ucp.shopping.cart": [
{
"version": "2026-04-08",
"spec": "https://ucp.dev/2026-04-08/specification/cart",
"schema": "https://ucp.dev/2026-04-08/schemas/shopping/cart.json"
}
],
"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"
}
],
"dev.ucp.shopping.fulfillment": [
{
"version": "2026-04-08",
"spec": "https://ucp.dev/2026-04-08/specification/fulfillment",
"schema": "https://ucp.dev/2026-04-08/schemas/shopping/fulfillment.json",
"extends": "dev.ucp.shopping.checkout"
}
],
"dev.ucp.shopping.discount": [
{
"version": "2026-04-08",
"spec": "https://ucp.dev/2026-04-08/specification/discount",
"schema": "https://ucp.dev/2026-04-08/schemas/shopping/discount.json",
"extends": [
"dev.ucp.shopping.checkout",
"dev.ucp.shopping.cart"
]
}
]
},
"payment_handlers": {}
}
}GET https://shop.example.com/.well-known/ucp for a shop whose primary domain is shop.example.com, not in catalog mode.
Use the endpoint the profile publishes as the base of every further call. It
names the shop's primary domain, which can differ from the domain you asked. A
host without UCP answers 404 with
{"code":"not_found","content":"No UCP business on this host"}, whatever the
reason. A shop whose company is deactivated or locked for an unpaid
subscription answers 503 with {"code":"service_unavailable","content":"This shop is temporarily unavailable"}
and Retry-After: 60.
Every call under /ucp/v1 then needs a UCP-Agent header naming your
platform profile. The Developer quickstart takes it from
there.