Skip to content

Universal Commerce Protocol (UCP) Official Specification

Universal Commerce Protocol (UCP) Official Specification

Section titled “Universal Commerce Protocol (UCP) Official Specification”

The key words MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD, SHOULD NOT, RECOMMENDED, MAY, and OPTIONAL in this document are to be interpreted as described in RFC 2119 and RFC 8174.

Schema notes:

  • Date format: Always specified as RFC 3339 unless otherwise specified
  • Amounts format: Minor units (cents)

UCP separates protocol version compatibility from capability negotiation. The business’s profile at /.well-known/ucp describes capabilities for the protocol version it declares. Businesses that support older protocol versions SHOULD publish version-specific profiles and advertise them via the supported_versions field — a map from protocol version to profile URI, enabling platforms to discover the exact capabilities for a specific protocol version.

Capability negotiation follows a server-selects architecture where the business (server) determines the active capabilities from the intersection of both parties’ declared capabilities. Both business and platform profiles can be cached by both parties, allowing efficient capability negotiation within the normal request/response flow between platform and business.

UCP uses reverse-domain naming to encode governance authority directly into capability identifiers. This eliminates the need for a central registry.

All capability and service names MUST use the format:

{reverse-domain}.{service}.{capability}

Components:

  • {reverse-domain} - Authority identifier derived from domain ownership
  • {service} - Service/vertical category (e.g., shopping, common)
  • {capability} - The specific capability name

Examples:

NameAuthorityServiceCapability
dev.ucp.shopping.checkoutucp.devshoppingcheckout
dev.ucp.shopping.fulfillmentucp.devshoppingfulfillment
dev.ucp.common.identity_linkingucp.devcommonidentity_linking
com.example.payments.installmentsexample.compaymentsinstallments

The spec and schema fields are REQUIRED for all capabilities. The origin of these URLs MUST match the namespace authority:

NamespaceRequired Origin
dev.ucp.*https://ucp.dev/...
com.example.*https://example.com/...
Namespace PatternAuthorityGovernance
dev.ucp.*ucp.devUCP governing body
com.{vendor}.*{vendor}.comVendor organization
org.{org}.*{org}.orgOrganization

The dev.ucp.* namespace is reserved for capabilities sanctioned by the UCP governing body. Vendors MUST use their own reverse-domain namespace for custom capabilities.

A service defines the API surface for a vertical (shopping, common, etc.). Services include operations, events, and transport bindings defined via standard formats:

  • REST: OpenAPI 3.x (JSON format)
  • MCP: OpenRPC (JSON format)
  • A2A: Agent Card Specification
  • EP(embedded): OpenRPC (JSON format)
FieldTypeRequiredDescription
versionstringYesService version (YYYY-MM-DD format)
specstringYesURL to service documentation
restobjectNoREST transport binding
rest.schemastringYes*URL to OpenAPI spec (JSON)
rest.endpointstringYes*Business’s REST endpoint
mcpobjectNoMCP transport binding
mcp.schemastringYes*URL to OpenRPC spec (JSON)
mcp.endpointstringYes*Business’s MCP endpoint
a2aobjectNoA2A transport binding
a2a.endpointstringYes*Business’s A2A Agent Card URL
embeddedobjectNoEmbedded transport binding
embedded.schemastringYes*URL to OpenRPC spec (JSON)

* Required when the transport object is present

The endpoint field provides the base URL for API calls. OpenAPI paths are appended to this endpoint to form the complete URL.

Example: With endpoint https://business.example.com/api/v2 and OpenAPI path /checkout-sessions, the resolved URL is:

POST https://business.example.com/api/v2/checkout-sessions

Rules:

  • endpoint MUST be a valid URL with scheme (https)
  • endpoint SHOULD NOT have a trailing slash
  • OpenAPI paths are relative and appended directly to endpoint

A capability is a feature within a service. It declares what functionality is supported and where to find documentation and schemas.

An extension is an optional module that augments another capability. Extensions use the extends field to declare their parent(s):

{
"dev.ucp.shopping.fulfillment": [
{
"version": "2026-01-11",
"spec": "https://ucp.dev/2026-01-11/specification/fulfillment",
"schema": "https://ucp.dev/2026-01-11/schemas/shopping/fulfillment.json",
"extends": "dev.ucp.shopping.checkout"
}
]
}

Extensions can be:

  • Official: dev.ucp.shopping.fulfillment extends dev.ucp.shopping.checkout
  • Vendor: com.example.installments extends dev.ucp.shopping.checkout

Multi-parent extensions MAY extend multiple parent capabilities by using an array:

{
"extends": ["dev.ucp.shopping.checkout", "dev.ucp.shopping.cart"]
}

Businesses publish their profile at /.well-known/ucp. Example:

{
"ucp": {
"version": "2026-01-11",
"services": {
"dev.ucp.shopping": [
{
"version": "2026-01-11",
"transport": "rest",
"endpoint": "https://business.example.com/ucp/v1",
"schema": "https://ucp.dev/2026-01-11/services/shopping/rest.openapi.json"
},
{
"version": "2026-01-11",
"transport": "mcp",
"endpoint": "https://business.example.com/ucp/mcp",
"schema": "https://ucp.dev/2026-01-11/services/shopping/mcp.openrpc.json"
}
]
},
"capabilities": {
"dev.ucp.shopping.checkout": [
{
"version": "2026-01-11",
"spec": "https://ucp.dev/2026-01-11/specification/checkout",
"schema": "https://ucp.dev/2026-01-11/schemas/shopping/checkout.json"
}
],
"dev.ucp.shopping.fulfillment": [
{
"version": "2026-01-11",
"spec": "https://ucp.dev/2026-01-11/specification/fulfillment",
"schema": "https://ucp.dev/2026-01-11/schemas/shopping/fulfillment.json",
"extends": "dev.ucp.shopping.checkout"
}
]
},
"payment_handlers": {
"com.example.processor_tokenizer": [
{
"id": "processor_tokenizer",
"version": "2026-01-11",
"spec": "https://example.com/specs/payments/processor_tokenizer",
"schema": "https://example.com/specs/payments/processor_tokenizer.json",
"available_instruments": [
{
"type": "card",
"constraints": {
"brands": ["visa", "mastercard", "amex"]
}
}
],
"config": {
"environment": "production",
"business_id": "merchant_xyz789"
}
}
]
}
},
"signing_keys": [
{
"kid": "business_2025",
"kty": "EC",
"crv": "P-256",
"x": "WbbXwVYGdJoP4Xm3qCkGvBRcRvKtEfXDbWvPzpPS8LA",
"y": "sP4jHHxYqC89HBo8TjrtVOAGHfJDflYxw7MFMxuFMPY",
"use": "sig",
"alg": "ES256"
}
]
}

Platforms MUST communicate their profile URI with each request to enable capability negotiation.

HTTP Transport: Platforms MUST use Dictionary Structured Field syntax (RFC 8941) in the UCP-Agent header:

POST /checkout HTTP/1.1
UCP-Agent: profile="https://agent.example/profiles/shopping-agent.json"
Content-Type: application/json
{"line_items": [...]}

MCP Transport: Platforms MUST include a meta object containing request metadata:

{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "create_checkout",
"arguments": {
"meta": {
"ucp-agent": {
"profile": "https://agent.example/profiles/shopping-agent.json"
}
},
"checkout": {
"line_items": [...]
}
}
},
"id": 1
}
  1. Profile Advertisement: Platforms MUST include their profile URI in every request using the transport-appropriate mechanism.
  2. Discovery: Platforms MAY fetch the business profile from /.well-known/ucp before initiating requests. If fetched, platforms SHOULD cache the profile according to HTTP cache-control directives.
  3. Namespace Validation: Platforms MUST validate that capability spec URI origins match namespace authorities.
  4. Schema Resolution: Platforms MUST fetch and compose schemas for negotiated capabilities before making requests.
  1. Profile Resolution: Upon receiving a request with a platform profile URI, businesses MUST fetch and validate the platform profile unless already cached.
  2. Capability Intersection: Businesses MUST compute the intersection of platform and business capabilities.
  3. Extension Validation: Extensions without their parent capability in the intersection MUST be excluded.
  4. Response Requirements: Businesses MUST include the ucp field in every response containing:
    • version: The UCP version used to process the request
    • capabilities: Array of active capabilities for this response

The capability intersection algorithm determines which capabilities are active for a session:

  1. Compute intersection: For each business capability, include it in the result if a platform capability with the same name exists.

  2. Select version: For each capability in the intersection, compute the set of version strings present in both the business and platform arrays. If the set is non-empty, select the highest version (latest date). If the set is empty (no mutual version), exclude the capability from the intersection.

  3. Prune orphaned extensions: Remove any capability where extends is set but none of its parent capabilities are in the intersection.

  4. Repeat pruning: Continue step 3 until no more capabilities are removed (handles transitive extension chains).

Negotiation Errors:

CodeDescriptionRESTMCP
invalid_profile_urlProfile URL is malformed, missing, or unresolvable400-32001
profile_unreachableResolved URL but fetch failed (timeout, non-2xx)424-32001
profile_malformedFetched content is not valid JSON or violates schema422-32001
version_unsupportedPlatform’s protocol version not supported422-32001
capabilities_incompatibleNo compatible capabilities in intersection200result

Signature Errors:

CodeDescriptionRESTMCP
signature_missingRequired signature header/field not present401-32000
signature_invalidSignature verification failed401-32000
key_not_foundKey ID not found in signer’s signing_keys401-32000
digest_mismatchBody digest doesn’t match Content-Digest header400-32000
algorithm_unsupportedSignature algorithm not supported400-32000