# Buying a domain

> Buy a new domain in the console with live pricing: the money-safe flow that authorizes, registers, then captures payment, and how it becomes a connected domain.

Source: https://docs.customdomain.ai/docs/sell/buying-a-domain

You can buy a brand-new domain without leaving the console, under **Buy a
domain** in the console sidebar (`/app/sell`). Search a name to see availability with live retail
pricing (the renewal price is shown up front), then register it in a couple of
clicks. The platform resolves which upstream registrar fulfills each TLD; that
choice isn't shown in the buying flow and doesn't change anything for you; the
domain is managed here either way.

## Shop-style search

Searching a name surfaces more than the exact match. Results come back in three
grouped sections:

* **Exact match**: the name you typed.
* **Other endings**: the same name on other TLDs
  (`.com .net .org .io .co .ai .app .dev .xyz .me`).
* **Similar names**: close variants of the name (common prefixes and suffixes,
  e.g. `get-`, `try-`, `-app`, `-hq`) on the primary TLD.

Each result shows availability and a live price. To get grouped suggestions from
the API, pass `?suggest=1` on the search request; every result then carries a
`Kind` field (`exact`, `tld`, or `variant`) that the console uses to group
them. Without `suggest=1` the endpoint returns the exact name only. See the
[Registrar API reference](/docs/api-reference/registrar/searchDomains).

## The money-safe flow

The purchase is ordered so you can never pay for a domain you don't get:

1. **Search & price**: availability and a live retail quote per domain
   (`GET /v1/registrar/search`, `POST /v1/registrar/quote`; see the
   [Registrar API reference](/docs/api-reference/registrar/searchDomains)).
2. **Authorize**: a checkout on the page, in place of the search results (no
   pop-up and no off-site redirect), shows the order and collects the card, and
   **authorizes** the amount. Nothing is charged yet. **Back to search** puts the
   results back as you left them.
3. **Register**: the platform registers the domain server-side, driven by the
   Stripe webhook; the browser returning to the console is only a fallback
   trigger, so closing the tab doesn't strand the order. Fulfillment is
   idempotent per checkout session: a retry or reload can't register or charge
   twice.
4. **Capture**: only after the registration succeeds is the card actually
   charged. If registration fails, the authorization is **released** and you pay
   nothing.

A completed purchase fires the `domain.purchased`
[webhook](/docs/webhooks/overview#event-catalog); a failed registration fires
`purchase.error`.

## After the purchase

A purchased domain behaves exactly like a domain you brought yourself:

* it **appears in the Domains console** automatically;
* it is **auto-connected**: the fresh zone gets an apex record pointing
  [where your application sends its domains](/docs/connect-flow/routing): the
  edge, or your own infrastructure's hostname (an `ALIAS` or `A` records,
  whichever the registrar accepts at the apex; on your own infrastructure the
  `A` records go to your `apex_ipv4`), so the connection starts moving
  `pending → propagating → live` immediately, with no setup step;
* it is **manageable via the same connections API**: records, status,
  webhooks, and [offboarding](/docs/connect-flow/offboarding) are identical.

## Buying through the embedded widget

The same money-safe flow is available to integrators embedding
[the widget](/docs/widget-sdk/overview), not just console users. Call
`window.customdomain.purchaseDomain(config)` to open the in-widget buy screen;
once your end user picks a domain, the widget starts a real checkout
(`POST /v1/registrar/checkout`) and fires a `customdomain:purchase` event
carrying a Stripe session. Mount Stripe Embedded Checkout (or redirect) with
its `clientSecret` / `url`, then finalize with `POST /v1/registrar/fulfill`,
which registers the domain, captures the charge, and auto-connects it, exactly
like the console flow above. See the
[SDK reference](/docs/widget-sdk/reference#events--callbacks) for the event
shape and the
[Registrar API reference](/docs/api-reference/registrar/startDomainCheckout) for
both endpoints.

## Who can buy

Starting a purchase (`POST /v1/registrar/checkout`) ends in a new connection, so
it follows the same billing rules as connecting a domain. A workspace without a
trial or subscription gets `402 billing_required` before anyone pays, except
while it still has [free domains](/docs/billing/plans-and-quotas#the-first-ten-domains-are-free) (the first
ten), which go through without a card. Search and pricing are reads and stay open.

## Availability

Buying is live on the hosted service. The purchase engine is **fail-closed**:
in any environment where `SELL_PURCHASE_ENABLED`, a registrar credential, and a
Stripe key aren't all configured, purchasing returns `503` rather than taking
an order it can't fulfill. Search and pricing work independently of the
purchase gate. A purchase that takes no payment (`POST /v1/registrar/purchase`)
has its own switch, `SELL_DIRECT_PURCHASE_ENABLED`, and is off on the hosted
service: every purchase there goes through checkout.

The [MCP server](/docs/mcp/overview) has a `create-domain-order` tool, but
purchases through MCP are off on the hosted service. The tool is gated by a
[purchase authorization callback](/docs/mcp/overview#purchase-authorization-callback)
as well as by the direct purchase switch, and the hosted service configures no
callback, so it answers `rejected`. Agents can still read orders with
`check-order-status` and `list-domain-orders`.
