# Domain Expiry & Purchase via Cloudflare Registrar ## API setup Requires a Cloudflare API token with TWO permission groups: | Permission | Level | What it gives | |---|---|---| | Zone → DNS → Edit | Edit | DNS record management | | Account → Domain Registration → Read | Read | View domains, expiry dates, auto-renew status | | Account → Domain Registration → Admin | Write (+ Admin) | Purchase domains, transfer domains, renew | The Admin level adds `domain_create`, `domain_register` capabilities not visible in `Read`. The `check_availability` endpoint requires Route: `GET /accounts/{id}/registrar/domains/{name}/check` — NOT the POST variant. ## Endpoints ### List registered domains ``` GET /accounts/{id}/registrar/domains ``` Returns: - `name`: domain name - `expires_at`: ISO date (e.g. "2027-02-06T00:43:04.000Z") - `auto_renew`: boolean - `cloudflare_registration`: boolean (true = registered through Cloudflare) - `permissions`: array of strings (e.g. `["contact_read", "contact_write", "domain_renew", "nameserver_write", "domain_delete"]`) ### Check domain availability ``` GET /accounts/{id}/registrar/domains/{name}/check ``` Returns: - `available`: boolean - `can_register`: boolean - `supported_tld`: boolean - `premium`: boolean - `fees.registration_fee`: number (USD) - `fees.renewal_fee`: number (USD) - `fees.transfer_fee`: number (USD) ### Renew a domain ``` PUT /accounts/{id}/registrar/domains/{name}/renewal Body: {"period": 1} # years ``` ## Real data pulled from Germaine's account (Jul 6, 2026) 12 domains, all registered through Cloudflare, all auto-renew ON: | Domain | Expires | Days Left | Price/yr | |---|---|---|---| | forefrontisp.com | Oct 7, 2026 | 92 | $10.46 | | vigilanttac.com | Oct 14, 2026 | 99 | $10.46 | | voipsimplicity.com | Nov 17, 2026 | 133 | $10.46 | | katiewattsdesign.com | Dec 29, 2026 | 175 | $10.46 | | boxpilotlogistics.com | Feb 6, 2027 | 214 | $10.46 | | germainebrown.com | Aug 3, 2027 | 392 | $10.46 | All standard .com pricing at $10.46/yr (Cloudflare at cost — no markup). ## Portal integration The DNS & Domains portal page (`dns.html`) has two tabs: 1. **DNS Zones** — Lists all zones with record count, plan, customer link. Opens DNS record editor. 2. **Registered Domains** — Lists all domains with expiry, auto-renew, days left (color-coded). Renew button per domain. Search + Register panel with availability check and pricing. Key fields for the domain table: - `name` → domain name - `expires_at` → formatted as "Mon DD, YYYY" - `auto_renew` → boolean badge (green if ON, red if OFF) - Days left = `(expires_at - now).days` - Color coding: green (>180 days), amber (90-180 days), red (<90 days) The search panel shows availability results with registration fee, renewal fee, and transfer fee. "Add to Cart" button would trigger registration flow. ## Pitfalls - The availability check endpoint uses GET with the domain in the path, NOT POST with body. POST returns "Page not found". - `can_register` is `False` on domains already owned by the account — that's expected, not an error. - Expiry dates are stored in UTC. Convert to local timezone when displaying. - Cloudflare does NOT disclose registration fees in the availability check response JSON field directly — the fee is nested under `fees.registration_fee`. - Premium domains return `premium: true` and have different pricing. The portal should flag these.