# Native Host Requirements for Implementing the UCP Embedded Protocol

> Implement UCP Embedded Protocol by injecting global JavaScript objects for JSON-RPC 2.0 message exchange between host apps and embedded UIs. Learn native host requirements.

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

---

**Native hosts must inject global JavaScript objects named `Embedded{Capability}ProtocolConsumer` and `Embedded{Capability}Protocol` into the web-view context to enable JSON-RPC 2.0 message exchange between the host application and embedded business UIs.**

The Universal-Commerce-Protocol (UCP) Embedded Protocol defines how native applications—such as iOS/Android apps or desktop clients—host business UIs within web-views while maintaining secure, bidirectional communication. According to the specification in [`docs/specification/embedded-protocol.md`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/docs/specification/embedded-protocol.md), native hosts must implement a specific bridging layer that exposes standardized global objects to the embedded JavaScript context. This article details the mandatory technical requirements for building a compliant native host implementation.

## Mandatory Bridging Layer Components

Native hosts must provide two distinct global JavaScript objects that serve as the communication bridge between the host runtime and the embedded business UI.

### Consumer Object Injection

The host must inject a **consumer object** into the iframe or web-view before the business UI loads. According to [`docs/specification/embedded-protocol.md`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/docs/specification/embedded-protocol.md), this object must be named following the pattern `window.Embedded{Capability}ProtocolConsumer` (recommended) or `window.webkit.messageHandlers.Embedded{Capability}ProtocolConsumer` for WebKit-based environments.

The consumer object must implement a single method:

- `postMessage(message: string): void` – Accepts a JSON-stringified JSON-RPC 2.0 request that the host parses and acts upon.

For example, the Checkout capability requires `EmbeddedCheckoutProtocolConsumer`, while the Cart capability uses `EmbeddedCartProtocolConsumer` as defined in [`embedded-checkout.md`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/embedded-checkout.md) and [`embedded-cart.md`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/embedded-cart.md) respectively.

### Producer Object Exposure

The host must also expose a **producer object** that allows the native side to send messages back to the embedded context. The host injects JavaScript that calls `window.Embedded{Capability}Protocol.postMessage(jsonMessage)`, where the embedded context listens for these calls immediately upon loading.

## Handshake Timing and Message Flow

Proper initialization sequencing is critical for protocol compliance.

### Ready Handshake Requirements

As specified in the Native Hosts section of [`embedded-protocol.md`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/embedded-protocol.md), the host must complete the following steps **before** the embedded context loads:

1. Register the global consumer and producer objects in the JavaScript context.
2. Prepare to receive the initial `ready` request (method name `ec.ready` for checkout contexts).
3. Validate the incoming handshake and reply with a JSON-RPC response containing the matching `id`.

The embedded UI broadcasts its `ready` request immediately upon loading. If the global objects are not present, the handshake fails, preventing subsequent communication.

### Message Format Compliance

All messages exchanged via the injected globals must conform to the JSON-RPC 2.0 envelope defined in the Message Format section of the specification. Each message must include:

- `"jsonrpc": "2.0"`
- `"method"` – The procedure name being invoked.
- `"params"` – Arguments for the method.
- `"id"` – Optional for notifications, required for requests.

The host must parse the JSON string, validate the envelope structure, and reply with matching `id` values for requests.

## Security and Error Handling Constraints

Native implementations must enforce strict security policies and standardized error responses.

### Origin Validation

As documented in the Security section of [`embedded-protocol.md`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/embedded-protocol.md), hosts utilizing `postMessage`-based bridges must validate the origin of all incoming `postMessage` calls. Failure to validate origins constitutes a `security_error`. The bridge must not be exposed to untrusted frames or contexts outside the UCP ecosystem.

### Error Response Standards

Transport-level failures—such as malformed JSON or unknown methods—must return using the JSON-RPC `error` field. Application-level errors must be wrapped within the `result.ucp.status` payload. This dual-layer error model ensures consistent error handling across native and web host implementations.

## Capability-Specific Naming Conventions

Each UCP capability defines exact global names that native hosts must implement:

- **Checkout**: `EmbeddedCheckoutProtocolConsumer` / `EmbeddedCheckoutProtocol`
- **Cart**: `EmbeddedCartProtocolConsumer` / `EmbeddedCartProtocol`

The capability-specific bindings in [`docs/specification/embedded-checkout.md`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/docs/specification/embedded-checkout.md) and [`docs/specification/embedded-cart.md`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/docs/specification/embedded-cart.md) define the exact method contracts and event sequences for each context. The OpenRPC schema at [`source/services/shopping/embedded.openrpc.json`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/source/services/shopping/embedded.openrpc.json) provides the complete method definitions useful for code generation and validation.

## Implementation Examples

### iOS WKWebView Consumer Injection

When implementing a host using iOS WKWebView, inject the consumer object before loading the business UI:

```javascript
// Swift → WKUserContentController injection
let script = """
window.EmbeddedCheckoutProtocolConsumer = {
  postMessage: function(message) {
    // Forward the JSON-RPC string to the native layer
    window.webkit.messageHandlers.checkoutConsumer.postMessage(message);
  }
};
"""
webView.evaluateJavaScript(script, completionHandler: nil)

```

### Native Message Handler

The following Python pseudocode demonstrates handling incoming EP messages and responding via the producer bridge:

```python
def handle_checkout_message(json_str: str):
    msg = json.loads(json_str)               # Parse JSON-RPC envelope

    assert msg["jsonrpc"] == "2.0"
    method = msg["method"]

    if method == "ec.ready":
        # Process handshake, return optional upgrade or credentials

        response = {
            "jsonrpc": "2.0",
            "id": msg.get("id"),
            "result": {
                "ucp": {"version": "1.0", "status": "success"},
                # ... additional fields ...

            }
        }
        # Send back via the producer bridge

        webview.evaluate_javascript(
            f'window.EmbeddedCheckoutProtocol.postMessage({json.dumps(response)})')

```

### Host-to-Embedded Notifications

After the `ready` handshake succeeds, the host can send state updates to the embedded context:

```javascript
// Host-initiated notification
const notification = {
  jsonrpc: "2.0",
  method: "ec.start",
  params: {
    checkout: { /* current checkout state */ }
  }
};
window.EmbeddedCheckoutProtocol.postMessage(JSON.stringify(notification));

```

## Summary

- Native hosts must inject `Embedded{Capability}ProtocolConsumer` (for incoming messages) and `Embedded{Capability}Protocol` (for outgoing messages) before the embedded UI loads.
- All messages must use JSON-RPC 2.0 envelopes with proper `jsonrpc`, `method`, `params`, and optional `id` fields.
- The host must handle the `ec.ready` handshake immediately upon receiving it from the embedded context.
- Security requires origin validation on all `postMessage` calls to prevent exposure to untrusted frames.
- Transport errors use the JSON-RPC `error` field; application errors use `result.ucp.status`.
- Capability-specific bindings in [`embedded-checkout.md`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/embedded-checkout.md) and [`embedded-cart.md`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/embedded-cart.md) define exact global names like `EmbeddedCheckoutProtocolConsumer`.

## Frequently Asked Questions

### What happens if the host injects the global objects after the embedded UI loads?

The embedded business UI sends its `ready` request immediately upon loading. If `window.Embedded{Capability}ProtocolConsumer` is not present, the request fails, the handshake never completes, and the embedded UI remains in a non-functional state. According to [`embedded-protocol.md`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/embedded-protocol.md), hosts must register these globals before loading the web-view content.

### Can native hosts use MessageChannel instead of injected globals?

Yes, after the initial handshake completes, hosts may upgrade to a `MessageChannel` for subsequent communication. However, the host must still provide the initial bridging layer via injected globals to handle the `ready` request and establish the session. The specification allows for transport upgrades but requires the global object bridge for initialization.

### How should native hosts handle session errors?

When receiving `error` or `session_error` notifications via the consumer object, the host must tear down the embedded web-view and optionally redirect the buyer using the `continue_url` provided in the error payload. This ensures secure session termination and proper buyer experience flow as defined in the Response Handling section of the specification.

### Where can developers find the complete method definitions for code generation?

Developers should reference [`source/services/shopping/embedded.openrpc.json`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/source/services/shopping/embedded.openrpc.json) in the Universal-Commerce-Protocol/ucp repository. This OpenRPC schema defines the complete set of EP methods, parameters, and structures, enabling automated client generation and request validation for native host implementations.