# How Universal Commerce Protocol (UCP) Handles Capability Negotiation Between Platforms and Businesses

> Discover how Universal Commerce Protocol (UCP) streamlines capability negotiation between platforms and businesses using a precise five-step process for efficient integration.

- Repository: [Universal Commerce Protocol (UCP)/ucp](https://github.com/Universal-Commerce-Protocol/ucp)
- Tags: how-to-guide
- Published: 2026-04-26

---

**UCP handles capability negotiation through a deterministic five-step process where platforms fetch business discovery profiles, intersect capability sets by ISO-date version, prune orphaned extensions, validate constraint requirements, and compose final schemas for payload validation.**

The Universal Commerce Protocol (UCP) separates protocol-version compatibility from capability negotiation to enable flexible integrations between commerce platforms and business systems. According to the Universal-Commerce-Protocol/ucp source code, businesses act as servers publishing discovery profiles while platforms serve as clients that compute active capabilities through a deterministic intersection algorithm. This process ensures that only mutually supported features activate for each session, with strict validation against schemas defined in [`source/schemas/ucp.json`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/source/schemas/ucp.json) and related specification files.

## Discovery Profile Retrieval at `/.well-known/ucp`

The negotiation begins when a platform retrieves the business's **discovery profile** from the `/.well-known/ucp` endpoint. This JSON document must conform to the **UCP Discovery Profile** schema defined in [`source/discovery/profile_schema.json`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/source/discovery/profile_schema.json), which specifies the structure for both `$defs/platform_profile` and `$defs/business_profile` objects. The profile contains the business's advertised capabilities, supported protocol versions, and service definitions, serving as the authoritative source for the intersection algorithm.

Businesses may also advertise version-specific URLs through `supported_versions` fields, allowing platforms to select appropriate endpoints. The core metadata schema in [`source/schemas/ucp.json`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/source/schemas/ucp.json) defines the `capabilities`, `services`, and `payment_handlers` objects that appear within these discovery documents.

## The Capability Intersection Algorithm

The platform executes the **Intersection Algorithm** described in [`docs/specification/overview.md`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/docs/specification/overview.md) to determine which capabilities are active for the session. For each capability name present in both the business profile and the platform's own capability list, the algorithm selects the **highest mutually-supported version** using ISO-date version strings that sort chronologically.

```python
def intersect(biz_caps, plat_caps):
    result = {}
    # 1. Compute intersection of names

    for name, biz_versions in biz_caps.items():
        if name not in plat_caps:
            continue
        # 2. Select highest common version

        common = set(v["version"] for v in biz_versions) & \
                 set(v["version"] for v in plat_caps[name])
        if not common:
            continue
        result[name] = max(common)   # ISO-date strings sort correctly

    # 3. Prune orphaned extensions

    changed = True
    while changed:
        changed = False
        for name, ext in list(result.items()):
            if "extends" in ext:
                parents = ext["extends"] if isinstance(ext["extends"], list) else [ext["extends"]]
                if not any(p in result for p in parents):
                    del result[name]
                    changed = True
    return result

```

If a capability name exists only in one party's list, or if no common version exists between the two sets, that capability is immediately dropped from consideration.

## Extension Pruning and Dependency Resolution

Capabilities that extend others through the `extends` property require special handling during negotiation. As defined in [`source/schemas/capability.json`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/source/schemas/capability.json), an extension survives only if at least one of its parent capabilities remains in the intersection set. The platform iteratively removes **orphaned extensions**—those whose parents were dropped during version conflict resolution—until no more capabilities are removed.

This pruning handles transitive dependency chains. For example, if capability B extends capability A, and capability C extends capability B, the removal of A triggers the removal of B, which subsequently triggers the removal of C. The algorithm repeats until the capability set stabilizes.

## Version Constraint Validation

After intersection and pruning, the platform validates any remaining capabilities against their **version constraints**. The `requires` object inside capability definitions—specified in the `$defs/requires` section of [`source/schemas/ucp.json`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/source/schemas/ucp.json)—can mandate specific protocol versions or dependent capability versions.

The platform checks that the negotiated protocol version satisfies `requires.protocol` constraints and that any required capability versions are present in the active set. Capabilities failing these checks are excluded from the final composition, ensuring that the platform never attempts to use features with unmet dependencies.

## Schema Composition and Payload Validation

With the final capability set determined, the platform fetches the base schemas and any extension schemas, composing them using JSON Schema's `allOf` directive according to the **Schema Resolution Convention** in the specification. This merged schema validates all subsequent request and response payloads exchanged during the session.

The composition process treats capabilities as modular units, allowing extensions to augment base functionality while maintaining strict validation guarantees. Each capability's `spec` and `schema` references from the discovery profile drive this final assembly stage.

## Error Handling and Fallback Mechanisms

When any negotiation step fails—whether due to empty capability intersections, unsatisfied version constraints, or schema composition errors—UCP returns a **negotiation-failure response** with `status: "error"` and a specific error code such as `capabilities_incompatible`. As documented in `docs/specification/overview.md#error-handling`, the response may include an optional `continue_url` field that redirects the shopper to a fallback web checkout flow, allowing transactions to proceed even when protocol-level negotiation cannot succeed.

## Summary

- **Discovery**: Platforms fetch business profiles from `/.well-known/ucp` conforming to [`source/discovery/profile_schema.json`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/source/discovery/profile_schema.json).
- **Intersection**: The algorithm selects the highest common ISO-date version for each capability present in both parties' lists.
- **Pruning**: Extensions with `extends` references are removed iteratively if their parent capabilities are absent, as defined in [`source/schemas/capability.json`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/source/schemas/capability.json).
- **Validation**: The platform enforces `requires` constraints from [`source/schemas/ucp.json`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/source/schemas/ucp.json) against the negotiated protocol version.
- **Composition**: Final schemas merge via `allOf` to validate session payloads.
- **Fallback**: Negotiation failures return structured errors with optional `continue_url` for web-based fallbacks.

## Frequently Asked Questions

### What happens when capability versions don't match between platform and business?

When version sets have no intersection, the platform drops that capability from the active set. The algorithm compares ISO-date version strings and selects the maximum value present in both lists; if the intersection is empty, the capability is excluded from further negotiation steps.

### How does UCP handle transitive extension dependencies?

The platform applies iterative pruning to handle transitive chains. If capability B extends A, and C extends B, removing A triggers removal of B, which then triggers removal of C. This process repeats until no orphaned extensions remain, ensuring only capabilities with satisfied dependency graphs activate.

### What is the role of the `/.well-known/ucp` endpoint in capability negotiation?

The `/.well-known/ucp` endpoint serves as the uniform location where businesses publish their **discovery profiles**. Platforms initiate negotiation by sending an HTTP GET to this endpoint—or to version-specific URLs from `supported_versions`—to retrieve the JSON document containing advertised capabilities, versions, and service configurations required for the intersection algorithm.

### How does UCP handle negotiation failures?

UCP returns a standardized error response with `status: "error"` and codes like `capabilities_incompatible` when negotiation cannot produce a valid capability set. The response may include a `continue_url` parameter that redirects to a web-based checkout flow, providing a graceful degradation path when protocol-level agreement is impossible.