---
title: UCP catalog and buyer handoff
description: Search fixed-price domains through UCP and let the buyer review and complete
  checkout on Namegarage.
url: https://namegarage.com/docs/ucp
---


# UCP catalog and buyer handoff

Read `https://namegarage.com/.well-known/ucp` first. Its UCP `2026-08-25` profile declares catalog search, catalog lookup and shopping permalinks. It declares no payment handlers or agent checkout.

Find the REST shopping endpoint in `ucp.services["dev.ucp.shopping"]`. Use the `rest` entry and append `/catalog/search`, `/catalog/lookup` or `/catalog/product`. Every POST is a catalog read. Send JSON and `UCP-Agent: profile="https://your-platform.example/.well-known/ucp"`. The exact platform profile URL must be reviewed and configured before requests are accepted. The production pilot also requires a fresh RFC 9421 ES256 signature from the pinned platform key. Send `Signature-Input` with the pinned `keyid` and `created`, `Signature`, and a SHA-256 `Content-Digest` of the exact body. Cover the method, target, and content digest. A missing or invalid signature returns 401. This authenticates the platform, not the buyer.

Search accepts an optional `query`, `filters.price.min` and `filters.price.max` in USD minor units, `filters.categories` containing `domain`, and `pagination.limit`/`cursor`. The default page size is 10 and the maximum is 20. Follow `has_next_page` and the opaque cursor until exhausted. A changed price or availability returns the recoverable `cursor_expired` error; restart the same search without a cursor. Malformed cursors or changed search inputs return `invalid_request`; correct the inputs before retrying. Search uses deterministic keyword matching without an AI provider call.

Lookup accepts `ids` (up to 20); product lookup accepts one `id`. IDs are ACE domain names. A Unicode alias resolves to the same single variant. Batch responses correlate found variants through `inputs`; warnings identify unavailable inputs. An unknown ID means absent from this public catalog, not available for registration.

Each product has one available outright-purchase variant. Its price is explicit USD minor units, not a locked quote or a provider-fee total. Offer-only names, held names, leases, bundles and private negotiated terms are excluded. When an unsupported `context.currency` accompanies a price filter, the response warns that the filter was not applied. Unrecognized eligibility claims do not change prices. Avoid confidential project descriptions and personal context.

Use `config.endpoint` from `dev.ucp.shopping.permalink` to construct a single-item browser link: append `/example.invalid:1` with the returned ACE ID. The buyer follows the 303 redirect, sees the selected domain and current terms, and chooses the existing website purchase action. Opening or previewing the link creates no reservation, offer, account, order or payment. Prices and availability are checked again.

The resolver removes identifying, price, payment, consent and attribution query parameters. `continue_to` is accepted only for the selected domain's canonical buyer page; other destinations use that page. Invalid or unavailable selections lead to a catalog recovery page. Honor HTTP errors and `Retry-After`. A 200 UCP response can have `ucp.status: "error"`; inspect it before using products.

The optional `@namegarage/sdk@0.3.0` UCP helpers use these same read operations. A pilot peer using the SDK supplies a custom `fetch` that signs each outgoing catalog request. `createPurchaseLink()` only constructs a URL locally. A successful local fixture does not establish third-party platform interoperability.

Browser catalog reads use non-credentialed CORS. The profile supports GET/HEAD preflights; the three catalog paths support POST preflights for JSON, `UCP-Agent`, and the signature headers. `Retry-After` is exposed to browser clients. Opening a purchase link remains ordinary browser navigation.
