Skip to content
Universal Commerce Protocol Universal Commerce Protocol Protocol registry / en

Reference note

UCP extensions: names, parents and versions

Declare UCP extensions: names, parents, versions and schemas. Learn why Discount can remain negotiable with Checkout alone, under conditions.

Published , revised . Part of the UCP framework.

A UCP extension adds behavior to an existing capability. Its name alone does not activate it: the merchant and platform must share a version, then have a parent that remains in the intersection. For a multi-parent extension, at least one parent must remain in the intersection, not all of its parents.

This note describes the UCP 2026-08-25 specification, as consulted on September 22, 2026. It distinguishes extensions defined by UCP from third-party extensions, whose authors manage their versions independently.

Name an extension and identify its author

Capability names follow the format {reverse-domain}.{service}.{capability}. For example, dev.ucp.shopping.checkout identifies Checkout in the UCP namespace. A vendor controlling example.com could name a payment extension com.example.payments.installments; this is an illustration, not an available product.

The dev.ucp.* namespace is reserved for capabilities approved by UCP governance. A custom extension uses its author’s namespace. The schema field points to its machine-readable schema; the optional spec field points to its human-readable documentation. The name is therefore not an API route.

The platform must check that the name matches the domain serving the schema before fetching it. This check establishes provenance, not a guarantee of quality or trustworthiness. The detailed rules appear in Namespace Governance.

Declare one or more parents

The extends field takes a string for a single parent, such as dev.ucp.shopping.checkout, or an array for multiple parents.

The official Discount extension can extend Cart, Checkout or both. The following declaration fragment belongs inside ucp.capabilities. It illustrates the multi-parent case; it is neither a complete profile nor a transaction to send as-is.

{
  "dev.ucp.shopping.discount": [
    {
      "version": "2026-08-25",
      "extends": [
        "dev.ucp.shopping.cart",
        "dev.ucp.shopping.checkout"
      ],
      "spec": "https://ucp.dev/2026-08-25/specification/shopping/extensions/discount/",
      "schema": "https://ucp.dev/2026-08-25/schemas/shopping/discount.json"
    }
  ]
}

Declaring both parents does not require both to be present for the extension to remain. Nor does it allow the use of Cart when Cart was not negotiated: check which resource is actually being extended before applying Discount to it.

Negotiate a shared version, then check for remaining parents

The intersection algorithm proceeds in this order:

  1. Keep capabilities whose names appear in both profiles.
  2. For each capability, look for exactly matching versions in both declarations. Exclude it if there is no shared version. If several versions are shared, select the most recent of those shared versions.
  3. Remove an extension if none of its parents remains present.
  4. Repeat this removal until the result stabilizes, since removing one extension can orphan another.

A more recent date alone does not prove compatibility. The name, shared version and dependencies are separate checks.

Example: Discount with Checkout alone

In this matrix, both profiles have selected ucp.version = 2026-08-25. They declare Discount at that same version, with Cart and Checkout as parents, and the other declaration checks are assumed to be satisfied. The table isolates the parent check after intersection:

Checkout present Cart present Decision on Discount at this step
Yes No Retained: Checkout is sufficient
No Yes Retained: Cart is sufficient
Yes Yes Retained: both parents are present
No No Removed: no parent remains

If only one party declared Discount, it would already be excluded before this check. A retained result in this table certifies neither the final validity of the schemas nor a working integration.

Distinguish the UCP version from a third-party extension version

For a UCP release denoted by D, the profile selects ucp.version = D. Services, capabilities and extensions defined by UCP must then declare that same version D. In the previous example, Checkout and Discount therefore both declare 2026-08-25.

A platform must reject a dev.ucp.* entry whose version differs from the profile version. An older UCP release is selected through a separate profile advertised in supported_versions, not by adding older dev.ucp.* versions to the current profile.

Third-party extensions follow a different rule: their authors choose their versions and release cadence. This independence does not remove the need for a version shared by the merchant and platform, or for checks against the UCP versions they depend on. Payment handler versions are also controlled by their authors. See Component Versioning and Release Snapshots.

A release date identifies a compatibility line whose documents may receive backported corrections. When documenting an integration, also retaining the consultation date and a copy of the schemas used avoids confusing successive states of the same release. This documentary record does not replace schema caching and retrieval rules.

Compose schemas without losing their constraints

UCP requires OpenAPI or OpenRPC transport definitions to reference the base schemas. Extension schemas describe their additions and how they compose with those bases through allOf.

Each parent declared in extends must have a corresponding entry in $defs, named with its exact full identifier. For a Checkout operation, resolution uses the dev.ucp.shopping.checkout entry; a multi-parent extension does not mean that the Cart schema must also be applied to that operation. See Extension Schema Pattern.

In JSON Schema, allOf requires all subschemas to be satisfied. It is not a merge that discards the parent’s constraints. For example, combining an integer type with a minimum of zero accepts 3, but rejects -1 and 1.5. The JSON Schema documentation explains this distinction.

The specification recommends that authors declare a requires object in the schema (SHOULD) to specify required protocol and capability versions. These bounds check versions that have already been selected; they do not replace negotiation. When present, they must be checked during resolution (MUST). An incompatible extension is excluded, then orphaned extensions are removed again. See Version Requirements.

Prepare the integration checks

Before relying on an extension, document and verify:

  • its author, name, schema and the semantics of the added fields;
  • UCP version consistency and the third-party versions actually shared;
  • the result with one parent present, with all parents absent and with a chain of dependencies;
  • the requires constraints, then requests and responses against the composed schemas;
  • the expected behavior when the optional extension is not negotiated.

These checks concern the capabilities actually declared by both parties. They do not establish that a particular product or provider supports an extension. To put the declaration in context, consult the UCP manifest note and the UCP framework decision grid.

Sources

The Discount fragment is adapted from the UCP documentation, © 2026 UCP Authors, under the Apache 2.0 license.


Back to the UCP framework · All notes · Lire en français