Back to articles
ArchitectureMCPUCPAgentic CommerceRESTIntegration Architecture

UCP April 2026: Cart, Catalog, and Signals Change Everything

The Universal Commerce Protocol just shipped its biggest release yet: cart management, catalog search, product lookup, and a signals framework for fraud prevention. I broke down 27 new schemas, 5 breaking changes, and the architectural implications for teams building commerce integrations.

Written by Artemii Karkusha — Integration Architect

April 10, 202614 min read

On April 8, 2026, the Universal Commerce Protocol shipped its most significant release since launch. Eighty-nine commits from twenty-plus contributors over eleven weeks. Twenty-seven new schemas. Five breaking changes. And three entirely new capabilities that transform UCP from a checkout protocol into a full commerce lifecycle specification.

After analyzing UCP's architecture against Visa's VIC reference agent, I've been tracking this spec closely. This release answers the question I raised in that analysis: can an open protocol cover the entire pre-purchase journey — discovery, browsing, cart building — without losing the schema rigor that makes it production-ready?

The answer is yes. Here's what changed, what broke, and what it means for integration teams building on top of UCP.

The Pre-Purchase Story Gets a Protocol

The headline feature of this release is three new top-level capabilities that cover everything before checkout.

UCP commerce lifecycle pipeline: Catalog Search, Cart, Checkout, and Order connected left-to-right, each with its capability endpoint label. Search and Cart marked NEW. Signals flow through every stage via the signals framework.

Cart: Browsing Without Commitment

UCP now has a formal Cart capability (dev.ucp.shopping.cart) — and the design reveals how carefully they thought about the distinction between "exploring" and "buying."

A cart is not a checkout. This sounds obvious, but most commerce platforms blur this line. Shopify's cart is a pre-checkout. Magento's quote becomes an order. The boundaries are fuzzy, and that fuzziness creates integration nightmares when you need to sync cart state across systems.

UCP's cart has a deliberately simple lifecycle:

Aspect Cart Checkout
State model Binary — exists or 404 Lifecycle — pending → active → complete
Pricing Estimated totals Final, committed pricing
Payment None Required for completion
Sharing continue_url for handoff Session-bound
Conversion Converts to checkout via cart_id Converts to order on completion

The conversion mechanism is idempotent — passing the same cart_id always returns the same checkout_id. This follows the Idempotency Mandate at the protocol level, preventing duplicate checkouts when network retries happen during cart-to-checkout conversion.

Real-World Example: In a multi-platform integration where an AI agent builds a cart across Shopify and Magento storefronts, UCP's cart-checkout separation means the agent can accumulate items from different merchants into separate carts, then convert each to a checkout independently. The cart's continue_url enables handoff between agents — one agent discovers products, another completes the purchase. This is the kind of workflow that falls apart when cart and checkout are the same object.

Catalog Search and Lookup: Discovery Gets Structured

Two new capabilities handle product discovery — and they're designed to be adopted independently, which is the right architectural call.

Catalog Search (dev.ucp.shopping.catalog.search) provides free-text search with structured filters:

// UCP Catalog Search — semantic query with filters
interface CatalogSearchRequest {
  readonly query?: string; // Optional — enables filter-only browsing
  readonly filters?: {
    readonly category?: readonly string[]; // OR semantics
    readonly price?: {
      readonly min?: number; // Minor units (cents)
      readonly max?: number;
    };
  };
  readonly context?: {
    readonly country?: string;
    readonly language?: string; // BCP 47
    readonly currency?: string; // ISO 4217
    readonly intent?: string; // Buyer purpose signal
  };
  readonly pagination?: {
    readonly limit?: number; // Default 10, business sets upper bound
    readonly cursor?: string;
  };
}

Two design decisions stand out here. First, query is optional — meaning you can do filter-only browsing, image search, or any other discovery modality via extensions. Second, category uses an array with OR semantics and supports multiple taxonomies (Google Product Category, Shopify, merchant-custom). This avoids the taxonomy lock-in problem that plagues catalog integrations between PIM systems and commerce platforms.

Catalog Lookup (dev.ucp.shopping.catalog.lookup) handles targeted retrieval when you already know what you want:

// Batch lookup with correlation tracking
interface CatalogLookupRequest {
  readonly ids: readonly string[]; // Product IDs, variant IDs, SKUs
  readonly filters?: SearchFilters; // Optional post-resolution filtering
}

// Response variants carry input correlation
interface VariantWithCorrelation {
  readonly variant: Variant;
  readonly inputs: readonly {
    readonly id: string;
    readonly match: "exact" | "featured"; // How this was resolved
  }[];
}

The inputs correlation on the response is particularly well-designed. When you batch-lookup 10 product IDs and get back 15 variants, each variant tells you which input IDs resolved to it and whether the match was exact (variant-level) or featured (product-level, server-selected). This eliminates the guesswork that happens in every catalog integration where you request items by ID and get back a flat list with no context about which request each result satisfies.

Production Pattern

The search/lookup split mirrors how mature PIM systems already work internally. Akeneo PIM separates search (Elasticsearch-backed, fuzzy, ranked) from retrieval (MySQL-backed, exact, complete). UCP formalizing this at the protocol level means your integration layer can route each operation to the right backend without the commerce platform needing to support both in a single endpoint.

Signals: Authorization Without Friction

The most architecturally significant change in this release isn't a new capability — it's the signals field added across checkout, cart, catalog search, and catalog lookup.

Signals are platform attestations about the buyer context — things the platform has directly observed or verified through third parties. They use reverse-domain naming (dev.ucp.buyer_ip, dev.ucp.user_agent, com.example.risk_score) and flow from platform to merchant on every request.

// Signals on a checkout request
interface CheckoutWithSignals {
  readonly signals?: {
    readonly "dev.ucp.buyer_ip"?: string;
    readonly "dev.ucp.user_agent"?: string;
    readonly [key: `${string}.${string}.${string}`]: unknown;
  };
}

This replaces the deprecated risk_signals field and represents a fundamental shift in how UCP handles trust. Instead of checkout-only risk data, signals flow through the entire commerce lifecycle — from product search through purchase. A merchant can adjust search results, cart pricing, and checkout approval based on the same signal data.

The reverse-domain naming is enforced via JSON Schema propertyNames, meaning custom signal providers can extend the namespace without collision. Shopify can define com.shopify.buyer_authenticated, Stripe can define com.stripe.risk_level, and they'll never conflict.

Real-World Example: In a SAP Commerce Cloud integration, fraud signals today come from the payment gateway at checkout time — too late to prevent catalog abuse. With UCP signals flowing through search and lookup, a merchant can throttle high-velocity product lookups from suspicious IPs before they even hit the cart. This is defense-in-depth at the protocol level, not bolted on as a payment-gateway afterthought.

Breaking Changes That Actually Matter

Five commits carry the ! breaking marker. Here's what requires migration work versus what you can absorb passively.

Must Migrate: Signed Amounts on Totals

total.json now uses signed_amount.json instead of unsigned amount.json. This fixes a real schema bug — discounts needed to be both >= 0 (from amount.json) and < 0 (from discount semantics), which was unsatisfiable.

The fix consolidates sign constraints into total.json as the single source of truth:

Total type Sign constraint
subtotal, tax, fee Must be >= 0
discount, items_discount Must be < 0

Migration: Update your Zod schemas and type definitions. If you were manually working around the unsigned amount constraint for discounts, you can now remove that workaround.

Must Migrate: Order Schema Overhaul

Orders now have a 1:N relationship with checkouts (one order can span multiple checkouts), currency is required, and adjustments use totals instead of amount. The quantity.original field tracks pre-adjustment quantities.

Migration: Update your order processing pipeline. The amounttotals rename on adjustments will break deserializers. The currency requirement may need a default value in your mapping layer if your upstream system doesn't always provide it.

Must Migrate: Embedded Protocol Error Alignment

Delegation error responses moved from JSON-RPC error to result using the standard error_response envelope. This is a wire-format change that will break embedded checkout implementations.

Migration: Update your ECP (Embedded Checkout Protocol) error handling. Errors now come through result with ucp.status: "error" instead of the JSON-RPC error field. The upside: ECP errors can now use recoverable severity, enabling retry logic that wasn't possible before.

Passive: Signals Replaces Risk Signals

risk_signals on checkout is deprecated but still accepted. Migrate to signals when convenient — this is additive, not breaking.

Passive: Discount Extends Cart

The discount extension's extends field changed from a string to an array (["dev.ucp.shopping.checkout", "dev.ucp.shopping.cart"]). If you're dynamically reading extends, handle both string and array forms.

The Schema Explosion: 27 New Types

This Universal Commerce Protocol release added 24 new shared type schemas on top of the 3 capability schemas. Here's the taxonomy:

Catalog Product Model (12 schemas): product, variant, product_option, option_value, detail_option_value, selected_option, category, description, media, rating, price, price_range. This is a complete product data model — comparable to what you'd find in a PIM system's core schema.

Search & Filter Types (4 schemas): search_filters, price_filter, pagination, input_correlation. Cursor-based pagination with required has_next_page and conditional next_cursor — no more guessing whether there's another page.

Monetary Types (3 schemas): amount, signed_amount, totals. The signed_amount type was the missing piece that enabled the totals fix.

Error Handling (2 schemas): error_code, error_response. Standard error envelope with ucp.status: "error" and messages[].

Security Types (2 schemas): signals, reverse_domain_name. Foundation for the signals framework.

The variant.json schema deserves special attention. It carries availability.status as an open vocabulary string (in_stock, backorder, preorder, etc.) rather than a closed enum. This means platform adapters don't need to map proprietary availability states into a fixed set of values — they can pass them through and let the consumer decide what each status means. The Schema Drift Trap teaches us that closed enums in integration schemas are a maintenance burden — open vocabularies with well-known values are more resilient to upstream changes.

What This Means for Integration Teams

If You're Building a UCP Platform Adapter

Good news: the ucp-js-sdk has already shipped v2.0.0 on npm with full support for the v2026-04-08 spec. All 27 new schemas are available as TypeScript types and Zod validators out of the box — no manual schema generation needed.

The catalog model (product, variant, option, media, rating) maps closely to standard commerce platform entities — but watch the price type, which uses integer minor units per ISO 4217. If your upstream platform uses decimal amounts (most do), you need a conversion layer.

The cart-to-checkout conversion is idempotent by spec. Your adapter must guarantee this — same cart_id → same checkout_id, always. Test this with concurrent requests.

If You're Building on the Embedded Protocol

The error response restructuring is your biggest migration item. All ECP delegation errors now use the standard error_response envelope through result instead of JSON-RPC error. Update your error handling, but gain recoverable severity for retry logic.

New ECP capabilities: ep.cart.* methods for cart management, ec.auth / ep.cart.auth for credential renewal during sessions. Plus ec_color_scheme query parameter for light/dark/auto theming.

If You're Consuming UCP via REST or MCP

New endpoints and tools to integrate:

Capability REST MCP
Cart POST/GET/PUT /carts, POST /carts/{id}/cancel create_cart, get_cart, update_cart, cancel_cart
Catalog Search POST /catalog/search search_catalog
Catalog Lookup POST /catalog/lookup, POST /catalog/product lookup_catalog, get_product
Order (new) GET /orders/{id} get_order

Service Definition Cleanup

The service definition files were renamed for clarity — openapi.jsonrest.openapi.json, openrpc.jsonmcp.openrpc.json, embedded.jsonembedded.openrpc.json. If you're generating clients from these files, update your paths. The old filenames are gone.

Implementation Checklist

Universal Commerce Protocol Schema Migration (do first)

  • Regenerate types from 27 new schema files
  • Update total handling for signed_amount (discounts are negative)
  • Rename amounttotals on order adjustments
  • Add currency as required field on Order
  • Handle extends as string or array on discount capability

New Capabilities (adopt incrementally)

  • Implement Cart CRUD operations
  • Implement Catalog Search with cursor-based pagination
  • Implement Catalog Lookup with batch correlation
  • Wire cart-to-checkout conversion with idempotency guarantee
  • Add signals field to all outgoing requests

Embedded Protocol (if applicable)

  • Migrate ECP error handling from JSON-RPC error to result envelope
  • Implement ep.cart.* methods
  • Add ec.auth / ep.cart.auth reauth support
  • Support ec_color_scheme query parameter

Observability

  • Log all new capability requests with correlation IDs
  • Track cart-to-checkout conversion rates
  • Monitor catalog search latency by filter type
  • Alert on signal feedback messages (code: signal)

The Integration Maestro Perspective

The API Contract Rule: The strength of an integration is determined by the precision of its contract — not the sophistication of its implementation.

This UCP release demonstrates what happens when a protocol team takes schema governance seriously. Twenty-seven new schemas, five breaking changes — and every break has a clear migration path with sign constraints moved to a single source of truth, deprecated fields marked with transition annotations, and response envelopes unified across transports.

The Universal Commerce Protocol's cart-checkout separation alone solves a problem I've battled in every commerce integration project: platforms that conflate "browsing" with "buying" force every downstream system to understand the implicit state machine. UCP makes it explicit. Cart is exploration. Checkout is commitment. The boundary is a protocol-level guarantee.

For teams building agentic commerce, this release is the tipping point. Before April 2026, UCP handled checkout — which is valuable but incomplete. Now it covers discovery through purchase: search products, build a cart, convert to checkout, complete the order. The full lifecycle, with formal schemas at every step and signals flowing through every request for fraud prevention.

The Schema Drift Trap is the rule to watch here. Twenty-seven new schemas means twenty-seven new surfaces where your implementation can drift from the spec. Pin your SDK to the v2026-04-08 release. Run conformance tests on every deploy. Schema discipline now prevents production incidents later.

Related rules: The API Contract Rule · The Schema Drift Trap · Fallback-First Design · The Idempotency Mandate

Related articles: Visa VIC vs UCP: Two Competing Visions for Agentic Commerce · REST vs SOAP vs GraphQL: What Wins for Integrations in 2025?

Enjoying this article?

Get more deep dives on integration architecture delivered to your inbox.

Artemii Karkusha
Artemii Karkusha

Integration Architect

Artemii Karkusha is an integration architect focused on ERP, eCommerce, and high-load system integrations. He writes about integration failures, architectural trade-offs, and performance patterns.

Came from LinkedIn or X? Follow me there for more quick insights on integration architecture, or subscribe to the newsletter for the full deep dives.