An AI shopping agent doesn’t buy the instant it decides to buy. It searches, compares, adds to cart, sometimes pauses for the human to confirm β and by the time it submits a checkout session, the price or stock level it read minutes earlier may already be wrong. Both leading agentic-checkout protocols treat that gap as a first-class problem: OpenAI and Stripe’s Agentic Commerce Protocol (ACP) and Google’s Universal Commerce Protocol (UCP) each define explicit, structured codes for exactly this failure mode β not optional advice, but fields the checkout schema requires a merchant backend to be able to emit.
What ACP’s checkout schema actually requires
ACP’s schema.agentic_checkout.json
(spec version 2026-04-17) defines two parallel taxonomies a merchant’s checkout
responses can populate:
MessageWarning.codeincludeslow_stock,price_change,shipping_delay,limited_availability, andexpiring_promotionβ signals the agent should surface to the buyer without blocking the transaction.MessageError.codeincludesout_of_stockandquantity_exceededβ failures that stop the checkout outright.
These aren’t free-text notes. They’re a closed enum in the OpenAPI/JSON Schema contract
itself, in openapi.agentic_checkout.yaml
and its companion schema file. A merchant backend that can’t compute a live
available_quantity and compare it against what the agent is requesting has no way to
populate the field β the checkout session either lies or errors.
What UCP’s schema requires, and where it’s less explicit
UCP’s cart schema (cart.json)
carries a messages[] array for “validation messages, warnings, or informational
notices” and a context object UCP’s own description says the merchant “uses for
pricing, availability, currency” β but the interesting detail is one level down, in the
product catalog. UCP’s variant.json
type carries price at the variant level (price, list_price, unit_price), not
just a page-level range, and points to a dedicated
availability.json
type with a boolean available field plus a status string whose well-known values are
in_stock, backorder, preorder, out_of_stock, and discontinued.
UCP has no dedicated price_change or quantity_exceeded error code the way ACP does β
that responsibility sits with the generic messages[] array instead of a named enum.
The structural point stands either way: both protocols push price and availability down
to the variant an agent actually selected, not the product page as a whole.
Why this is a transaction problem, not a data-quality one
A price or stock mismatch at checkout isn’t a display bug an agent can shrug off. ACP’s
own error taxonomy treats out_of_stock as a hard stop β the checkout session cannot
proceed β and price_change as something the agent must relay and the buyer must
re-confirm. Either way, the agent’s plan (add to cart, check out, done) breaks mid-flow,
and it has no way to know whether the interruption is real without a backend that
computes current price and quantity, live, at the moment the checkout session is created
or updated. A store whose price and stock only update on a nightly batch job will hand
every agent a session that’s correct on average and wrong often enough to matter.
What this means for your store
- Variant-level price and availability, not page-level. If your product feed states one price and one “in stock” flag for a product with ten variants, neither protocol’s schema has anywhere accurate to put an agent’s actual selection.
- Compute stock at request time. A cached or batch-synced quantity is exactly the gap
ACP’s
out_of_stockandquantity_exceededcodes exist to catch β the difference is whether your backend catches it before the agent does, or after. - Populate the warning codes you have, before the error codes you don’t.
low_stockandprice_changelet an agent finish the transaction with an informed buyer instead of hitting a hard failure later in the same session.
FAQ
Do AI shopping agents need real-time inventory data?
Yes. Both major agentic-checkout protocols β OpenAI/Stripe’s ACP and Google’s UCP β
define structured fields for stock status and price at the checkout or variant level,
and ACP’s schema includes dedicated error codes (out_of_stock, quantity_exceeded)
for when that data is wrong. A backend that only syncs inventory periodically will
populate those fields incorrectly during the gap between syncs.
What’s the difference between ACP and UCP on price/stock signaling?
ACP defines a closed set of named codes in its checkout schema β price_change and
low_stock as warnings, out_of_stock and quantity_exceeded as blocking errors. UCP
instead carries price and availability as structured fields on the product variant
itself (a status enum including in_stock, backorder, and out_of_stock), and
relies on a generic messages[] array rather than a dedicated price-change code.
Does a JSON-LD Product page with a price and “InStock” availability solve this?
Not on its own. Static structured data on a page tells an agent what was true when the page was last rendered or crawled. Both ACP and UCP checkout flows expect the merchant’s live backend to answer price and availability questions at the moment a checkout session is created, which is a different system than the page’s structured data β usually the same inventory system that would need to back a real-time feed or API.
Sources
- ACP
schema.agentic_checkout.jsonβMessageWarning/MessageErrorcode enums (GitHub, fetched directly) - ACP
openapi.agentic_checkout.yamlβ checkout API definition (GitHub, fetched directly) - ACP repository README β maintainers, version, beta status (GitHub, fetched directly)
- UCP
cart.json(GitHub, fetched directly) - UCP
variant.jsonβ variant-level price fields (GitHub, fetched directly) - UCP
availability.jsonβ status enum (GitHub, fetched directly) - UCP
product.jsonβ page-level price range (GitHub, fetched directly)
Both schemas confirm the same thing from opposite directions: price and stock accuracy at the moment of checkout is now a structural requirement of buying with an agent, and it’s exactly the kind of check AgentReady’s scan runs against a live store rather than taking a static feed’s word for it.