Tutorial for UCP spec version 2026-04-08. This guide walks you through implementing UCP from scratch. Cross-reference with the official spec for authoritative details.

Getting Started with UCP

This tutorial series takes you from zero to a working UCP implementation. You will create a discovery profile, expose your catalog, build carts, handle checkout, and manage orders. We will use REST transport for clarity, but the same concepts apply to MCP, A2A, and embedded.

Step 1: Your First UCP Discovery Profile

Every UCP-enabled merchant needs a JSON profile at /.well-known/ucp. This is how agents discover what you support. Let us create one.

1

Create the well-known directory

On your web server, create the directory for the well-known endpoint:

mkdir -p /var/www/your-store/.well-known
2

Write the UCP profile

Create .well-known/ucp (no file extension) with your profile JSON:

{
  "ucp": {
    "version": "2026-04-08",
    "services": {
      "dev.ucp.shopping": [
        {
          "version": "2026-04-08",
          "spec": "https://ucp.dev/2026-04-08/specification/overview",
          "transport": "rest",
          "endpoint": "https://your-store.com/api/ucp",
          "schema": "https://ucp.dev/2026-04-08/services/shopping/rest.openapi.json"
        }
      ]
    },
    "capabilities": {
      "dev.ucp.shopping.checkout": [
        {
          "version": "2026-04-08",
          "spec": "https://ucp.dev/2026-04-08/specification/checkout",
          "schema": "https://ucp.dev/2026-04-08/schemas/shopping/checkout.json"
        }
      ]
    }
  }
}
3

Configure your web server

For nginx, ensure the file is served with the correct content type:

# nginx config
location = /.well-known/ucp {
    default_type application/json;
    add_header Access-Control-Allow-Origin *;
    try_files $uri =404;
}
CORS is required

Agents will fetch your profile from different origins. You must set Access-Control-Allow-Origin or agents will be blocked by CORS.

4

Verify your profile

curl -s https://your-store.com/.well-known/ucp | jq .ucp.version
# Expected: "2026-04-08"

curl -s https://your-store.com/.well-known/ucp | jq '.ucp.capabilities | keys'
# Expected: ["dev.ucp.shopping.checkout"]
Done!

Your store is now discoverable by UCP agents. Agents can fetch your profile and learn that you support shopping via REST with checkout capability. In the next steps, we will implement the actual endpoints.

Step 2: Product Discovery (Catalog Endpoint)

Now agents know you exist, but they cannot see your products. Let us expose your catalog.

Your REST endpoint (declared as https://your-store.com/api/ucp in the profile) needs to handle catalog queries:

# Agent searches for products
GET https://your-store.com/api/ucp/catalog?q=wireless+headphones&limit=10

# Response:
{
  "ucp": { "version": "2026-04-08" },
  "results": [
    {
      "id": "item_123",
      "title": "Premium Wireless Headphones",
      "price": 19999,
      "currency": "USD",
      "description": "Noise-cancelling, 30h battery",
      "seller": { "domain": "your-store.com" }
    }
  ],
  "total": 1,
  "has_more": false
}

For per-product detail:

GET https://your-store.com/api/ucp/products/item_123

{
  "ucp": { "version": "2026-04-08" },
  "id": "item_123",
  "title": "Premium Wireless Headphones",
  "price": 19999,
  "currency": "USD",
  "variants": [
    { "id": "var_black", "title": "Black", "price": 19999 },
    { "id": "var_white", "title": "White", "price": 19999 }
  ]
}

Step 3: Building a Cart

Agents build carts across multiple conversation turns. Your API needs to accept line items and return estimated totals.

# Create a cart
POST https://your-store.com/api/ucp/carts
{
  "line_items": [
    { "product_id": "item_123", "variant_id": "var_black", "quantity": 1 }
  ]
}

# Response:
{
  "ucp": { "version": "2026-04-08" },
  "id": "cart_abc123",
  "line_items": [
    {
      "id": "li_1",
      "item": { "id": "item_123", "title": "Premium Wireless Headphones" },
      "variant_id": "var_black",
      "quantity": 1,
      "price": 19999
    }
  ],
  "totals": [
    { "type": "subtotal", "amount": 19999 },
    { "type": "estimated_tax", "amount": 1599 },
    { "type": "estimated_total", "amount": 21598 }
  ]
}

Update the cart as the buyer changes their mind:

PUT https://your-store.com/api/ucp/carts/cart_abc123
{
  "line_items": [
    { "id": "li_1", "quantity": 2 }
  ]
}

Step 4: Your First Checkout

When the buyer is ready, convert the cart to a checkout session and collect the remaining information.

# Create checkout from cart
POST https://your-store.com/api/ucp/checkout-sessions
{
  "cart_id": "cart_abc123",
  "line_items": [...]
}
# Response: status = "incomplete"

# Add buyer info and fulfillment
PUT https://your-store.com/api/ucp/checkout-sessions/chk_xyz
{
  "buyer": {
    "email": "customer@example.com",
    "first_name": "Jane",
    "last_name": "Doe"
  },
  "fulfillment": {
    "methods": [{
      "type": "shipping",
      "destination": {
        "street_address": "123 Main St",
        "address_locality": "Austin",
        "address_region": "TX",
        "postal_code": "78701",
        "address_country": "US"
      }
    }]
  }
}
# Response: status = "ready_for_complete"

Complete the checkout by submitting payment:

POST https://your-store.com/api/ucp/checkout-sessions/chk_xyz/complete
{
  "payment": {
    "instrument": {
      "type": "card",
      "tokenized": "tok_xxx"
    },
    "credential": "ap2_mandate_xxx"
  }
}

# Success:
{ "status": "completed", "order_id": "order_789" }

# Needs human input:
{
  "status": "requires_escalation",
  "continue_url": "https://your-store.com/checkout/chk_xyz/3ds"
}
Agent Profile Required

All checkout operations require the agent to identify itself. Include the UCP-Agent header in REST requests:

UCP-Agent: profile="https://agent.example/profile"

Step 5: Order Management

After checkout, set up webhooks for order lifecycle events and an endpoint for on-demand order status:

# Agent asks "where's my order?"
GET https://your-store.com/api/ucp/orders/order_789

# Response:
{
  "ucp": { "version": "2026-04-08" },
  "id": "order_789",
  "status": "fulfilled",
  "fulfillment": {
    "expectations": [{
      "description": "Arrives in 2-3 business days",
      "fulfillable_on": "now"
    }],
    "events": [{
      "occurred_at": "2026-07-04T10:30:00Z",
      "type": "shipped",
      "tracking_number": "1Z999",
      "tracking_url": "https://ups.com/track/1Z999"
    }]
  }
}

Step 6: Handling Escalations

Some transactions need human input. UCP makes this graceful:

  1. Detect when escalation is needed (3DS challenge, address validation, final-sale confirmation)
  2. Return status: "requires_escalation" with a continue_url
  3. The continue_url should be a page on your site where the buyer completes the step
  4. After the buyer completes the step, your checkout session updates
  5. The agent can poll the checkout status or receive a webhook
{
  "ucp": { "version": "2026-04-08" },
  "id": "chk_xyz",
  "status": "requires_escalation",
  "continue_url": "https://your-store.com/checkout/chk_xyz/verify",
  "messages": [{
    "type": "info",
    "code": "3ds_required",
    "content": "Payment verification required. Please complete in your browser."
  }]
}
You did it!

You now have a working UCP implementation. Agents can discover your store, search your catalog, build carts, check out, and track orders. Next, check the platform guides for platform-specific optimizations, or the agent guides if you are building the agent side.

Next: Platform Guides → Read the Spec Overview