cloudflare-domain-launch
Everything below is CLI/API; the dashboard is touched exactly once (the registrant contact, §1). Auth for all API calls: Authorization: Bearer $CLOUDFLARE_API_TOKEN, base URL https://api.cloudflare.com/client/v4, account id from the dashboard URL or GET /accounts.
1. Buy the domain (Registrar API)
- Check availability + price:
POST /accounts/{account_id}/registrar/domain-checkwith{"domains": ["example.dev", ...]}— returns per-domain availability and price. - Register:
POST /accounts/{account_id}/registrar/registrationswith a minimal body:{"domain_name": "example.dev", "years": 1, "auto_renew": true}. The minimal body relies on the account's default address-book contact for the registrant — and there is no API to set that contact; it must be configured once in the dashboard before you script registrations. This is the one mandatory non-CLI step. - Registration is async. A 200 from the POST means accepted, not owned. Poll the registration status until
stateissucceededbefore wiring anything against the domain.
2. Deploy the static site (Pages via wrangler)
wrangler pages project create <name> --production-branch=release
wrangler pages deploy . --project-name=<name> --branch=release
Live immediately at <name>.pages.dev. Then attach the custom domain:
POST /accounts/{account_id}/pages/projects/<name>/domains with {"name": "example.dev"} (repeat for www.example.dev).
3. Gotchas (each makes a working site look broken)
- Pages does NOT always auto-create the DNS records for a custom domain. If the apex/www attachments stay
pending, create the records yourself in the zone:CNAMEfor both the apex (@) andwww, target<name>.pages.dev, proxied (orange cloud). The attachment activates once the records exist. .devis HSTS-preloaded (HTTPS-only, baked into every browser) — the site is dark (curlreports000) until the edge cert for the hostname issues. That window is normal, not a failure; wait for the cert before tearing anything down.- A local
curl 000can also be your own machine's stale NEGATIVE DNS cache — if you (or anything on the machine) queried the name before the record existed, the NXDOMAIN got cached locally. Before assuming it's broken, verify from a resolver that never saw the negative answer:dig @1.1.1.1 example.dev, or bypass local DNS entirely withcurl --resolve example.dev:443:<cf-ip>. If either works, the site is fine and the bug is your cache.
Security — domain registration spends real money
POST …/registrar/registrations is a real financial transaction — it charges the Cloudflare account and registers a domain. Always run domain-check first, surface the exact domain + price to the user, and get explicit human confirmation before the registration call. Never auto-register in a loop. The API token is a secret: source it from an env var, never hardcode or log it.
Related skills
name-a-product— find the name and clear it for conflicts BEFORE you buy. Also documents that theregistrationsPOST executes immediately with no dry-run.saas-brand-system/vibebrand— generate the brand system once the domain is live.