PATCH/PUT records to point it
wherever you need. It does that job well, and the API is mature. But it is also a separate registrar
account:
- The domain lives behind a GoDaddy API Key + Secret (
Authorization: sso-key KEY:SECRET), its own dashboard, and its own Good as Gold prepaid balance — disconnected from wherever the agent’s email, cards, secrets, and KYC live. - WHOIS contacts, registrant consent, renewals, and nameserver delegation are yours to wire up and keep registered against your identity, by hand, per domain.
- “Who let this agent buy a domain or rewrite a DNS record, and what else can it touch?” is answered in GoDaddy for the registrar, and in unrelated systems for everything else. The domain has no shared accountability with the rest of the agent’s footprint.
domains primitive gives the agent the same capability —
search a name, buy it, connect an existing one, and edit the live DNS zone — but the domain is
rooted in one governed identity:
- The tenant user that owns the domain is the same user that owns its email inboxes, the entity it formed, its cards, its vault secrets, and its KYC.
- A purchased or connected domain is automatically wired to that identity’s email (SPF/DKIM/MX),
so
support@acme.comis the same identity that boughtacme.com— not a second integration. - Whether an agent may buy a domain — and whether each DNS write is allowed at all — is decided by that user’s Account Kit and per-agent assignment at execution time, then logged.
GoDaddy is a trademark of GoDaddy Operating Company, LLC, used here for identification only. No endorsement or affiliation is implied.
Tested against: the GoDaddy Domains API v1 (REST; no official Node SDK — raw
fetch),
production base https://api.godaddy.com (test env https://api.ote-godaddy.com), auth header
Authorization: sso-key KEY:SECRET, docs snapshot June 2026; and the Naive Node SDK
@usenaive-sdk/server against the Naive API (base https://api.usenaive.ai/v1, docs
snapshot June 2026).Version notes:- GoDaddy purchases are headless:
POST /v1/domains/purchasededucts the price from a funded Good as Gold balance and requires aconsentblock (agreement keys fromGET /v1/domains/agreements) plus four WHOIS contact objects. Naive’sdomains.purchase(domain)returns a hostedcheckout_url(Stripe) that a human completes — no contact schema, no prepaid balance. This is a real workflow difference; see what doesn’t map yet. - GoDaddy edits DNS with
PATCH /v1/domains/{domain}/records(add) andPUT /v1/domains/{domain}/records/{type}/{name}(replace), min TTL 600. Naive edits the live zone withPOST /v1/domains/:id/zone-records(create/replace) andDELETE /v1/domains/:id/zone-records/:recordId, TTL 60–86400, allowed types A/AAAA/CNAME/MX/TXT/CAA, with DMARC/DKIM and inbound MX/TXT protected and a CAA allowlist. - The Naive Node SDK
domainssub-client exposes onlylist(),search(), andpurchase()today. Connect, verify, and DNS zone editing are available over REST and the CLI (naive domains …) / MCP — the snippets below call them withfetch. See the SDK parity note. - Access model differs. GoDaddy’s production API requires ≥1 domain in the account for the Management/DNS API (≥50 for the Availability API) and a Good as Gold balance to buy. Naive needs no registrar account — domains hang off your tenant identity; purchased domains are currently capped at 3 per company (see domains guide).
Concept map
| GoDaddy | Naive | Notes |
|---|---|---|
Authorization: sso-key KEY:SECRET per registrar account | new Naive({ apiKey }) + naive.forUser(id) | Naive scopes every primitive to one identity, not just the registrar |
| One GoDaddy account, isolated from your other vendors | tenant user via naive.forUser(id) | The core consolidation win |
GET /v1/domains/available?domain=acme.com → available + price | client.domains.search("acme.com") → { available, price, priceInCents } | Single-name availability + price check |
POST /v1/domains/purchase (consent + 4 contacts, deducts Good as Gold) | client.domains.purchase("acme.com") → { checkout_url, domain_id } | Naive returns a checkout link; no contact schema or prepaid balance |
GET /v1/domains → list registered domains | client.domains.list() → { domains: [...] } | List domains for the identity |
| (use a domain you already own) | POST /v1/domains/connect { domain } → { dns_records } | BYOD: connect an existing domain for email |
GET /v1/domains/{domain}/records → all zone records | GET /v1/domains/:id/zone-records → { records: [{ id, type, name, value, ttl }] } | Live zone read with provider record IDs |
PATCH /v1/domains/{domain}/records (add) | POST /v1/domains/:id/zone-records { mode: "append" } | Add a record |
PUT /v1/domains/{domain}/records/{type}/{name} (replace) | POST /v1/domains/:id/zone-records (default mode: "replace") | Create-or-replace at (type, name) |
PUT /v1/domains/{domain}/records (replace all) | — | No “replace entire zone” call — edit per record |
DELETE /v1/domains/{domain}/records/{type}/{name} | DELETE /v1/domains/:id/zone-records/:recordId | Delete by provider record ID, not type/name |
| (verify email setup yourself) | POST /v1/domains/:id/verify + GET /v1/domains/:id/dns-records | Naive checks the email-provider (SPF/DKIM/MX) records for you |
Set custom nameservers (PUT /v1/domains/{domain} → nameServers) | — | Naive manages the zone; you edit records, not delegation — see gaps |
Domain forwarding / redirects (/v1/domains/{domain}/forwards) | — | No equivalent — use a CNAME/A record + your app |
Renewals (/v1/domains/{domain}/renew), transfers (/transfer), privacy | — | Not exposed — see gaps |
Bulk availability / suggestions (/v1/domains/available array, /suggest) | — | Single-name search only |
WHOIS contacts (contactRegistrant, …) supplied per purchase | Handled internally against your company | You do not assemble contact objects |
| API Key + (no scopes) — full-account access | Account Kit domains primitive + per-agent assignment | Permission is execution-time policy on the identity — see gains |
| Good as Gold prepaid balance | Naive credits + hosted checkout | Purchase is a governed, approvable action — see gains |
Before / after: the core path
The path that matters for almost every “give my agent a domain” use case is find a name, buy it, then point a record at your app. Here it is on both platforms.The workflow that changes: a domain that is an email identity
On GoDaddy, wiring a domain for email is a manual DNS chore: look up your provider’s MX/TXT/DKIM records andPATCH them in yourself, then hope verification passes. On Naive, a connected or
purchased domain is the agent’s email identity — connect hands you the exact records, verify
confirms them, and inboxes drop straight onto it.
Buying through Naive skips steps 1–2 entirely: purchased domains are auto-configured for email,
so you go straight from
checkout_url to email.createInbox.Minimal viable migration
The smallest swap that keeps a working agent running is just search + buy + edit one record.Install the SDK and set your key
NAIVE_API_KEY (a server-side key from the dashboard).Swap availability + price
Replace
GET /v1/domains/available?domain=… with client.domains.search("acme.com"). The shape
is { available, price, priceInCents, currency } — note GoDaddy returns price in micros,
Naive in dollars (price) and cents (priceInCents).Swap purchase
Replace
POST /v1/domains/purchase (consent + four contacts + Good as Gold) with
client.domains.purchase("acme.com"). Instead of a headless balance deduction you get a
checkout_url to complete payment; the domain registers and auto-wires to the identity’s email.
Handle the pending_approval response if your Account Kit gates purchases (see below).Swap DNS edits
Replace
PUT /v1/domains/{domain}/records/{type}/{name} with
POST /v1/domains/:id/zone-records (default mode: "replace"), and
DELETE /v1/domains/{domain}/records/{type}/{name} with
DELETE /v1/domains/:id/zone-records/:recordId (delete by provider record ID from
GET …/zone-records). Bump any ttl: 600 GoDaddy floor down to Naive’s 60 if you want faster
propagation.Consolidate further once you’re on Naive
This is where the migration pays for itself. In GoDaddy, the API Key isolates the registrar and nothing else, and a domain is an anonymous asset behind a prepaid balance. On Naive, the unit of isolation is a tenant user, and the domain is rooted in that identity’s verified, formed business — and is its email identity.Gain #1 — one identity across primitives
- With GoDaddy, the agent’s domains are an island behind an API Key. With Naive,
naive.forUser(acme.id)is a single handle to domains and email and formation and cards and vault. - The domain is not an anonymous asset — it is auto-wired as the email identity of the entity that user already formed and verified. Tear the customer down from one place; sibling tenants can never read each other’s domains, inboxes, cards, or secrets.
Gain #2 — execution-time permission enforcement
- Whether an agent may buy a domain at all is policy on the Account Kit, and whether a purchase freezes for human review is the same policy — not a check you hand-write and not a GoDaddy balance you guard manually.
- The agent’s code is identical for every tier —
client.domains.purchase("acme.com"). Whether the call runs is decided at execution time:- An agent whose Account Kit disables
domainsis refused withforbidden, with no code change on your side. domains.purchaseis a sensitive action: withrequiresApproval: trueit returns{ status: "pending_approval", approval_id }and the API replays it only after a human approves.- DNS writes are bounded by the zone’s safety rules (allowed types, protected DMARC/DKIM, CAA allowlist, and related checks documented there) and per-company rate limits documented in the domains guide — enforcement you would otherwise hand-roll on top of GoDaddy.
- An agent whose Account Kit disables
Gain #3 — unified accountability
- Every search, purchase, and DNS edit for a customer lands in one per-user activity log — alongside their email, formation, card, and vault events, not in a separate GoDaddy dashboard:
- Every DNS edit (success or rejection) also appends an
activity_logrow and emits adomain.updatedlive event onGET /v1/events— so the audit trail is built into the write, not reconstructed after the fact. - That is the question that is hard to answer when domains live in GoDaddy, email lives elsewhere, and secrets live somewhere else. Under Naive it is a single query.
What does not map yet
A migration guide that hides gaps is worse than none. The core path (search → buy → edit DNS) maps cleanly, but the following GoDaddy capabilities have no direct equivalent on Naive’s domains primitive today. Check this list against your app before you commit.| GoDaddy feature | Status on Naive | Workaround |
|---|---|---|
| Headless purchase (deduct from Good as Gold, no human) | Different model | Naive returns a checkout_url a human completes — no fully unattended buy |
Custom nameservers (PUT /v1/domains/{domain} → nameServers) | Not provided — Naive manages the zone | Edit records via zone-records; you cannot delegate the zone elsewhere |
Domain forwarding / redirects (/forwards) | Not provided | Use a CNAME/A record pointing at your app/host |
Renewals (/renew, renewAuto) | Not exposed | Managed by Naive; no per-domain renew call |
Transfers in/out (/transfer, auth/EPP codes) | Not provided | Domains are registered and held within Naive |
WHOIS / contact management (contactRegistrant, privacy, /v1/domains/{domain}/contacts) | Handled internally | You do not assemble or edit contact objects |
Bulk availability + suggestions (available array, /suggest) | Single-name search only | Loop search per name; no suggestion engine |
| TLD breadth (hundreds of TLDs, agreements per TLD) | Limited catalog | search returns availability for supported TLDs only |
| More than 3 domains / company | Currently capped at 3 purchased domains per company | Connect (BYOD) additional domains you own elsewhere |
”Replace entire zone” (PUT /v1/domains/{domain}/records) | Per-record edits only | Edit each record with zone-records; protected records can’t be removed |
| Min TTL 600 parity / arbitrary record types | TTL 60–86400; types A/AAAA/CNAME/MX/TXT/CAA only | No SRV/NS/PTR; DMARC/DKIM + inbound MX/TXT are protected |
| Typed SDK methods for connect/verify/DNS | SDK has only list/search/purchase | Use REST or the naive domains CLI / MCP tools for the rest |
Where to go next
domainsprimitive — full search/purchase/connect/verify + DNS zone editingdomainsSDK sub-client — typedlist/search/purchasesignaturesdomainsCLI —connect,verify,zone-records,set-record,delete-record- Email — inboxes that drop straight onto a verified or purchased domain
- Account Kits and Approvals — the policy model behind execution-time governance and purchase approval
- Formation and Verification — the entity + KYC the domain’s email identity hangs off
- Tenant users — the identity that owns the domain, email, cards, and vault