---
title: Serve a UCP Profile
description: Serve a UCP profile at /.well-known/ucp from a custom eve channel.
url: "https://eve.dev/docs/protocols/ucp"
docs_index: /llms.txt
---

> For an index of all documentation, see [/llms.txt](/llms.txt).

The [Universal Commerce Protocol](https://ucp.dev/) (UCP) is an open standard for agentic commerce. A business declares UCP support by serving a JSON **profile** at `/.well-known/ucp`. The profile lists supported spec versions, services, capabilities, payment handlers, and the public keys agents use to verify signed responses.

To support UCP with eve:

1. [Author the profile](#author-the-profile)
2. [Serve it from a channel](#serve-it-from-a-channel)
3. [Add your commerce endpoints](#add-your-commerce-endpoints)

## Author the profile

Your profile is a plain JSON object that follows the [UCP spec](https://ucp.dev/2026-08-25/specification/overview#profile-structure). The `ucp` object declares the `version`, `services`, `capabilities`, and `payment_handlers` of your business. The top-level `keys` array is a standard JWK Set of the public keys agents use to verify your signed messages. The same document also works as a key source for [Web Bot Auth](https://ucp.dev/2026-08-25/specification/overview#deployment-patterns-for-wba-interop).

```ts
// agent/ucp-profile.ts
export const profile = {
  ucp: {
    version: "2026-08-25",
    services: {
      "dev.ucp.shopping": [
        {
          version: "2026-08-25",
          spec: "https://ucp.dev/2026-08-25/specification/overview",
          transport: "rest",
          schema: "https://ucp.dev/2026-08-25/services/shopping/rest.openapi.json",
          endpoint: "https://your_deployment_url_here/ucp/shopping",
        },
      ],
    },
    capabilities: {
      "dev.ucp.shopping.checkout": [
        {
          version: "2026-08-25",
          spec: "https://ucp.dev/2026-08-25/specification/shopping/checkout",
          schema: "https://ucp.dev/2026-08-25/schemas/shopping/checkout.json",
        },
      ],
    },
    payment_handlers: {
      "dev.shopify.shop_pay": [
        {
          id: "shop_pay_1234",
          version: "2026-08-25",
          spec: "https://shopify.dev/ucp/shop-pay-handler",
          schema: "https://shopify.dev/ucp/schemas/shop-pay-config.json",
          available_instruments: [
            {
              type: "shop_pay",
            },
          ],
        },
      ],
      "com.example.processor_tokenizer": [
        {
          id: "processor_tokenizer",
          version: "2026-08-25",
          spec: "https://example.com/specs/payments/processor_tokenizer-payment",
          schema: "https://example.com/schemas/payments/delegate-payment.json",
          available_instruments: [
            {
              type: "card",
              constraints: {
                properties: {
                  brand: { enum: ["visa", "mastercard"] },
                },
              },
            },
          ],
        },
      ],
    },
  },
  keys: [
    {
      kid: "business_2025",
      kty: "EC",
      crv: "P-256",
      x: "...",
      y: "...",
      use: "sig",
      alg: "ES256",
    },
  ],
};
```

## Serve it from a channel

Serve the profile at `/.well-known/ucp` from a custom channel:

```ts
// agent/channels/ucp.ts
import { defineChannel, GET } from "eve/channels";
import { profile } from "../ucp-profile";

const body = JSON.stringify(profile);

export default defineChannel({
  cors: true,
  routes: [
    GET("/.well-known/ucp", async () => {
      return new Response(body, {
        headers: {
          "content-type": "application/json",
          "cache-control": "public, max-age=300",
        },
      });
    }),
  ],
});
```

- **Caching**: The spec requires `public` and a `max-age` of at least 60 seconds, and forbids `private`, `no-store`, and `no-cache`. See [Profile Requirements](https://ucp.dev/2026-08-25/specification/overview#hosting).
- **CORS**: `cors: true` suits public discovery metadata. Pass a `cors` options object to narrow origins. See [CORS](../channels/custom#cors).
- **HTTPS, no redirects**: The spec requires HTTPS and forbids 3xx responses on the profile endpoint.

## Add your commerce endpoints

Each `services[].endpoint` URL must point at endpoints you serve, for example from a custom channel:

```ts
// agent/channels/ucp-shopping.ts
import { defineChannel, POST } from "eve/channels";

export default defineChannel({
  routes: [
    POST("/ucp/shopping/checkout-sessions", async (req) => {
      const request = await req.json();
      // Create a checkout session per your published schema. Every UCP
      // response must carry the `ucp` envelope with the negotiated
      // version and the capabilities active for this response. Checkout
      // responses also require `payment_handlers`, even when empty.
      return Response.json({
        ucp: {
          version: "2026-08-25",
          capabilities: {
            "dev.ucp.shopping.checkout": [{ version: "2026-08-25" }],
          },
          payment_handlers: {},
        },
        id: "checkout_123",
        status: "incomplete",
        // ...other checkout fields per the checkout schema
      });
    }),
  ],
});
```

Routes are relative to the `endpoint` base in your profile, per the service's OpenAPI schema. Keep them in sync with the paths you mount here.

## Verify

Run `eve dev` and fetch the profile locally:

```sh
curl -i http://localhost:2000/.well-known/ucp
```

Then fetch it from your deployment:

```sh
curl -i https://your_deployment_url_here/.well-known/ucp
```

Expect a `200` with the profile JSON:

```http
HTTP/2 200
content-type: application/json
cache-control: public, max-age=300
```

## What's not covered

You implement the commerce behavior yourself: the checkout, cart, and order state machines; payment-handler execution; and request signing and verification.

## Read next

- [Channels overview](/docs/channels): The channel contract this builds on.
- [Custom channels](../channels/custom): The route helpers, CORS, and metadata this page uses.

---

For a semantic overview of all documentation, see [/sitemap.md](/sitemap.md)

For an index of all available documentation, see [/llms.txt](/llms.txt)

For agent-facing discovery, including API and MCP surfaces, see [/agents.md](/agents.md)