UCP Cart Capability
Before writing code
Fetch live spec: Web-search site:ucp.dev specification shopping cart and fetch the page for the exact Cart schema, operation names, and binding details. Also fetch https://ucp.dev/latest/schemas/shopping/cart.json for the authoritative JSON Schema. Field names and required-ness change between spec versions — never write the schema from memory.
Conceptual Architecture
Why Cart is separate from Checkout
Checkout carries payment handler configuration, buyer commitment, and a status lifecycle. That is overhead a buyer does not need while still browsing. Cart is the lightweight half: collect items, get estimated totals, share a link — with no payment configuration and no status machine.
The canonical progression is:
cart session → checkout session → order
Cart handles exploration. Checkout enforces commitment.
Operations
| Operation | Purpose |
|---|---|
| Create Cart | Initialize a session with line items and optional buyer / context data |
| Get Cart | Read current state; returns not_found once expired or cancelled |
| Update Cart | Full replacement of cart contents — not a patch |
| Cancel Cart | Terminate the session |
Update Cart replacing rather than merging is the detail most implementations get wrong. Send the complete intended line-item set every time.
Key data model
id— cart identifierline_items— entries with quantity (in the authoritative sale basis), unit price, and line totalscontext— localization signals: country, region, postal code, locationbuyer— optional name, email, phonecurrency— ISO 4217totals— estimated subtotal, tax, fulfillment, discountsmessages— validation warnings and informational noticescontinue_url— handoff link for session recoveryexpires_at— optional expiry
State model
Carts are binary: they exist or they do not. There is no incomplete → completed lifecycle, and totals stay estimates until checkout conversion. Treat any amount read from a cart as indicative only — never as something to charge against.
Conversion to Checkout
Create a checkout referencing cart_id. Two rules govern this:
- The business uses the cart contents and ignores overlapping payload fields. Do not attempt to pass line items alongside a
cart_idand expect them to merge. - Conversion is idempotent — if an incomplete checkout already exists for that cart, the business returns the existing session rather than creating a second one.
After checkout completion the business may clear the cart, driven by TTL or its own business logic. Do not depend on the cart surviving.
Bindings
Cart is exposed over REST, MCP, and Embedded. It is not an A2A capability. Negotiate it like any other capability — see ucp-dev-patterns for the intersection algorithm.
Implementation Guidance
- Make
Create Cartidempotent on your side too; agents retry aggressively. - Populate
continue_url— it is what makes a cart shareable and recoverable, which is the main reason Cart exists as a separate capability. - Surface validation problems through
messagesrather than failing the whole request, so an agent can repair one line item without rebuilding the cart. - Set
expires_atdeliberately and honour it inGet Cartwithnot_found. - Reference implementation: https://github.com/Universal-Commerce-Protocol/samples