Skip to main content
Documentation

Custom domains

Optionally buy and attach your own domain to your DeepSpace app.

On this page

By default, every deployed app lives at <name>.app.space - a fully production-grade URL with SSL that most apps ship and stay on. When you want a branded URL, you can attach your own domain - myapp.com, myapp.ai, myapp.io - directly from the CLI. Domain purchase, DNS, and SSL are handled end-to-end; you don't touch a registrar dashboard.

How it works#

DeepSpace registers domains through a hybrid backend:

  • Cloudflare Registrar for ~27 TLDs at cost (.com, .dev, .app, .xyz, and others)
  • Porkbun for .ai, .io, .me, .co, ccTLDs, and other variants

Routing uses Cloudflare Custom Hostnames against the platform's SaaS zone (app.space). After purchase, the platform provisions ownership and DCV records on the new domain's zone, then activates a hostname route.

Billing is via Stripe Checkout - the same payment flow as in-app purchases. Auto-renew is on by default.

Search and buy#

# Find an available domain and its price
npx deepspace app domain search my-startup
npx deepspace app domain search my-startup --limit 20

# Buy via Stripe Checkout (browser opens for payment)
npx deepspace app domain buy my-startup.com
bash

buy opens a Stripe Checkout tab in your browser. After payment, the CLI polls for provisioning:

  • Cloudflare Registrar TLDs (.com, .dev, .app): ~60-90 seconds
  • Porkbun TLDs (.ai, .io, .me): 15-60 minutes (registry-side NS propagation)

You can Ctrl-C out of the polling loop without losing progress - provisioning continues server-side. Re-check with domain status <domain>.

Buy options#

# Print the Checkout URL instead of opening a browser
npx deepspace app domain buy myapp.com --no-open

# Exit immediately after Checkout session is created (no polling)
npx deepspace app domain buy myapp.com --no-wait

# Skip the confirmation prompt (required in non-TTY contexts)
npx deepspace app domain buy myapp.com --yes

# Combine with --app to buy and attach in one command
npx deepspace app domain buy myapp.com --app my-app
bash

For buy and attach, --app accepts the immutable app id or the current live name; without it, the CLI resolves DEEPSPACE_APP_ID from the surrounding app directory. Names are URL leases, not durable identity, so scripts should prefer the id — see app identity.

With --json, buy returns the Checkout session immediately without polling, and supplies the domain status follow-up action to run once payment completes.

List, inspect, and manage#

# Domains you own
npx deepspace app domain list
npx deepspace app domain list --json

# Detail for one domain (registrar status, hostname status, expiry, errors)
npx deepspace app domain status myapp.com
npx deepspace app domain status myapp.com --json
bash

Domains, billing, and renewal status are also visible in the web dashboard at dashboard.deep.space.

Re-point a domain at a different app#

npx deepspace app domain attach myapp.com --app new-app-name
bash

attach re-points an owned registration to the resolved immutable app id - the CLI resolves whatever you pass to --app (id or live name) to the id and binds that. Use it when:

  • You want to move a domain from a staging app to production
  • You're consolidating multiple domains under one app

Because the binding is to the id, renaming an app does not require re-attaching its domain. The domain follows the app through any rename, along with data, secrets, and collaborators - see app identity.

Detach without releasing#

npx deepspace app domain detach myapp.com --yes
bash

detach removes routing but keeps the registration on file. You keep owning the domain and can re-attach later. There is no domain release - releasing a registration goes through the registrar's own portal.

Auto-renew#

# Disable auto-renew (will expire at end of term)
npx deepspace app domain renew myapp.com --auto off

# Re-enable
npx deepspace app domain renew myapp.com --auto on
bash

Agent-friendly flags#

The CLI is designed for both humans and automation:

FlagAvailable onPurpose
--jsonsearch, buy, list, status, attachMachine-readable stdout
--yesbuy, detachSkip confirmation prompt (required in non-TTY)
--no-waitbuyExit after Checkout session creation
--no-openbuyPrint URL instead of opening browser
--limit <n>searchCap the number of results

Pitfalls#

`--app` defaults to your current directory

If you run deepspace app domain buy myapp.com outside an app directory without --app, the CLI errors with No app specified. Pass --app <name>, or run from an app directory with a wrangler.toml.

Premium domains can have different registration and renewal prices

chargedCents in list / status is what you paid this year. The pricing object exposes separate registrationCost / renewalCost. For non-premium TLDs they match; for premium domains, introductory pricing can reset at renewal - read domain status before assuming.

Don't wrap `buy` in `timeout N`

The CLI polls for up to 5 minutes (Cloudflare TLDs) or 60 minutes (Porkbun TLDs). An artificial timeout aborts before payment completes. Use --no-wait for fire-and-forget; otherwise let it run and Ctrl-C if needed (safe; provisioning continues server-side).

Pricing visibility#

The CLI shows the price during search and the Checkout flow. The price starts from the registrar's cost (Cloudflare Registrar or Porkbun) and DeepSpace adds a markup: you pay the registrar cost × 1.3, plus a $1 fee. Renewals charge to your saved Stripe card automatically.

Next steps#