From e6d07662224ad985b830a8f03825a3c618382e9a Mon Sep 17 00:00:00 2001 From: hemanth Date: Mon, 20 Jul 2026 10:48:01 -0700 Subject: [PATCH] docs: add cart session persistence guidance to cart-rest spec Add non-normative session persistence guidance inline in the cart-rest spec page rather than as a separate guide document: - Session resumption: cart ID as canonical resumption handle - Expiry handling: cart_expired error code distinct from not_found - Agent reconnection: patterns for voice/chat agents Drops prescriptive TTL recommendations per reviewer feedback. TTL is a platform-specific decision. Closes #344 --- docs/specification/cart-rest.md | 66 +++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/docs/specification/cart-rest.md b/docs/specification/cart-rest.md index c6c700a2e..3f6d8fad3 100644 --- a/docs/specification/cart-rest.md +++ b/docs/specification/cart-rest.md @@ -542,6 +542,72 @@ HTTP 200 and the UCP envelope containing `messages`: } ``` +## Session Persistence + +!!! note "Non-normative" + This section provides implementation guidance and is not part of the normative specification. + +The cart capability defines `expires_at` but intentionally leaves session +persistence details to implementers. The guidance below captures recommended +patterns observed across early implementations. + +### Session Resumption + +The cart `id` is the canonical resumption handle. A buyer (or agent acting on +their behalf) resumes a cart by providing its `id` to `GET /carts/{id}` or +`PUT /carts/{id}`, regardless of how the cart was originally created. + +- **Cross-transport persistence**: A cart created over MCP SHOULD be retrievable + over REST, and vice versa. The cart `id` is transport-agnostic. +- **Buyer binding** is a business decision. Some businesses scope carts to a + buyer identity; others (especially guest-friendly merchants) allow any session + with the cart `id` to resume. + +### Expiry Handling + +When a cart has expired, businesses SHOULD return a `cart_expired` error code +rather than a generic `not_found`, so platforms can distinguish "this cart +existed but expired" from "this cart ID was never valid": + + +```json +{ + "ucp": { + "version": "{{ ucp_version }}", + "status": "error", + "capabilities": { + "dev.ucp.shopping.cart": [{"version": "{{ ucp_version }}"}] + } + }, + "messages": [ + { + "type": "error", + "code": "cart_expired", + "content": "Cart has expired", + "severity": "unrecoverable" + } + ], + "continue_url": "https://merchant.com/" +} +``` + +Platforms receiving a `cart_expired` error SHOULD offer to recreate the cart with +the same items rather than silently failing. Businesses MAY implement grace +periods (accepting updates to recently-expired carts) but this is not required. + +### Agent Reconnection + +Voice and chat agents may lose connectivity, or the buyer may return after a +pause. The following patterns apply: + +- If the cart is still valid (`expires_at` in the future), the agent resumes by + calling `PUT /carts/{id}` with the existing cart ID. +- If the cart has expired, the agent receives the `cart_expired` error and can + offer to recreate the cart with the buyer's previously selected items. +- Agents SHOULD proactively check `expires_at` and warn the buyer when the cart + is close to expiring (e.g., "Your cart expires in 5 minutes, shall I complete + the order?"). + ## Security Considerations ### Authentication