> ## Documentation Index
> Fetch the complete documentation index at: https://docs.asva-ai.com/llms.txt
> Use this file to discover all available pages before exploring further.

# UCP Capability Discovery: Hosting .well-known/ucp

> Host and validate your /.well-known/ucp manifest so AI agents can discover your commerce capabilities before making any catalog or checkout calls.

Before an AI agent can browse your catalog or place an order, it needs to know what your store supports and where to call it. The `/.well-known/ucp` file is that declaration. When a UCP-compatible platform — Google AI Mode, Gemini, or any other agent — encounters your domain, it fetches this file first. Without it, agents cannot discover or transact with you at all.

<Warning>
  The manifest must be served at `https://yourdomain.com/.well-known/ucp` (or `/.well-known/ucp.json`) with `Content-Type: application/json` and no authentication required. Agents will not send credentials to fetch capability discovery files.
</Warning>

## Minimal manifest

The minimum valid manifest requires a `product_catalog` capability and a `checkout` capability. Both must include an `endpoint` URL.

```json /.well-known/ucp theme={null}
{
  "version": "1.0",
  "capabilities": {
    "product_catalog": {
      "endpoint": "https://yourstore.com/api/ucp/products"
    },
    "checkout": {
      "endpoint": "https://yourstore.com/api/ucp/checkout"
    }
  }
}
```

## Full manifest with all capabilities

Declare optional capabilities to unlock additional agent behaviors — shipping cost calculation, order tracking, and return initiation.

```json /.well-known/ucp theme={null}
{
  "version": "1.0",
  "capabilities": {
    "product_catalog": {
      "endpoint": "https://yourstore.com/api/ucp/products",
      "format": "json",
      "version": "1.0",
      "supports_search": true,
      "supports_filters": ["category", "price", "availability"]
    },
    "checkout": {
      "endpoint": "https://yourstore.com/api/ucp/checkout",
      "supported_methods": ["POST"],
      "requires_authentication": false,
      "version": "1.0"
    },
    "shipping": {
      "endpoint": "https://yourstore.com/api/ucp/shipping",
      "supported_methods": ["POST"]
    },
    "orders": {
      "endpoint": "https://yourstore.com/api/ucp/orders",
      "supported_methods": ["GET", "POST"]
    },
    "returns": {
      "endpoint": "https://yourstore.com/api/ucp/returns",
      "supported_methods": ["POST"]
    }
  }
}
```

## Required capabilities

| Capability        | Required | Description                                       |
| ----------------- | -------- | ------------------------------------------------- |
| `product_catalog` | Yes      | Endpoint agents call to fetch your products       |
| `checkout`        | Yes      | Endpoint agents call to create and confirm orders |

## Optional capabilities

| Capability | Description                                         |
| ---------- | --------------------------------------------------- |
| `shipping` | Shipping options and real-time cost calculation     |
| `orders`   | Order history lookup and tracking status            |
| `returns`  | Initiating returns from inside the agent experience |
| `reviews`  | Product reviews and ratings for agent context       |

## Hosting the manifest

<Tabs>
  <Tab title="Next.js / Vercel">
    Place the file at `public/.well-known/ucp`. Next.js serves everything in `public/` as static files automatically.

    ```bash theme={null}
    mkdir -p public/.well-known
    ```

    Then create `public/.well-known/ucp` with your manifest JSON. No additional configuration required — Vercel will serve it at `/.well-known/ucp`.

    <Note>
      Vercel sets `Content-Type` based on file extension. Since `ucp` has no extension, verify the response header is `application/json`. You may need a `vercel.json` rewrite rule or a Route Handler to set the header explicitly.
    </Note>
  </Tab>

  <Tab title="Express.js">
    Serve the manifest from a route handler so the `Content-Type` header is always correct:

    ```javascript theme={null}
    app.get('/.well-known/ucp', (req, res) => {
      res.json({
        version: '1.0',
        capabilities: {
          product_catalog: { endpoint: `${process.env.BASE_URL}/api/ucp/products` },
          checkout: { endpoint: `${process.env.BASE_URL}/api/ucp/checkout` }
        }
      })
    })
    ```
  </Tab>

  <Tab title="Nginx">
    Alias the path to a static JSON file on disk:

    ```nginx theme={null}
    location /.well-known/ucp {
      default_type application/json;
      alias /var/www/html/.well-known/ucp.json;
    }
    ```
  </Tab>

  <Tab title="Shopify">
    Shopify does not allow arbitrary files at the domain root. Use the [Manifest Generator](https://asva-ai.com/tools/manifest) to generate your file, then host it via a Shopify app route or a custom domain proxy. See the full [Shopify UCP guide](/ucp/shopify).
  </Tab>
</Tabs>

## Common mistakes

<AccordionGroup>
  <Accordion title="404 — file not at domain root">
    The manifest must be at `https://yourdomain.com/.well-known/ucp`, not on a subdomain like `shop.yourdomain.com/.well-known/ucp`. Check that your web server routes the root domain correctly, and that `.well-known` directories aren't blocked by a `.htaccess` or server config.
  </Accordion>

  <Accordion title="JSON parse error">
    Validate your JSON before deploying. Common causes: trailing commas, unescaped quotation marks inside strings, or missing closing brackets.

    ```bash theme={null}
    cat .well-known/ucp | python3 -m json.tool
    ```

    If the command exits without output, your JSON is valid.
  </Accordion>

  <Accordion title="Wrong Content-Type header">
    The response must include `Content-Type: application/json`. Some static hosts serve unknown file extensions as `text/plain`. Override this in your hosting configuration — see the Nginx and Express examples above.
  </Accordion>

  <Accordion title="Endpoint is behind authentication">
    The `/.well-known/ucp` file must be publicly accessible with no API key, cookie, or auth header required. AI agents follow the `.well-known` convention and will not authenticate to fetch this file.
  </Accordion>
</AccordionGroup>

## Validate with Asva

Use the [Manifest Generator and Validator](https://asva-ai.com/tools/manifest) to generate a compliant manifest from your endpoint URLs, validate the JSON of an existing file, and confirm your hosted manifest is publicly reachable.

To validate via the API:

```bash theme={null}
curl -X POST https://asva-ai.com/api/audit \
  -H "Authorization: Bearer $ASVA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"domain": "yourstore.com", "checks": ["well_known"]}'
```

## Next steps

<CardGroup cols={2}>
  <Card title="Product catalog endpoint" icon="boxes-stacked" href="/ucp/product-catalog">
    Structure your catalog endpoint so agents can find the right product and variant.
  </Card>

  <Card title="Checkout and payments" icon="credit-card" href="/ucp/checkout-and-payments">
    Implement cart creation and order confirmation.
  </Card>
</CardGroup>
