DEV Community

Manu Shukla
Manu Shukla

Posted on • Originally published at ecorpit.com

11 scopes and one quote token: letting an AI agent register domains without a runaway bill in 2026

11 scopes and one quote token: letting an AI agent register domains without a runaway bill in 2026

Summary. GoDaddy opened the beta of its Developer Platform on 14 July 2026 with a rebuilt v3 Domains API, 11 assignable token scopes, and a registration endpoint that refuses to run without an Idempotency-Key header. Cloudflare's Registrar API beta, last updated 24 April 2026, takes a different route: no price-lock token, a Check call immediately before purchase, and a documented 201-or-202 response with a 10-second wait window. AWS Route 53 has registered domains over RegisterDomain since 2014 and returns an OperationId instead. All three are now reachable by a coding agent, and the differences between them decide whether a timed-out retry costs you nothing or buys the same name twice. Cloudflare's own documentation quotes at-cost prices of $8.57 for a .com and $10.11 for a .dev; GoDaddy's launch example briefs an agent with a ceiling of "under $20 a year". In India the constraint is not the API at all: the NIXI bulk-booking notice caps an individual at two .in registrations and an accredited company at 100 without written approval from the NIXI CEO, and a breach of personal data caused by weak safeguards carries a penalty of up to Rs 250 crore under the Digital Personal Data Protection Act 2023.

This is a build guide for the engineers wiring that loop. It covers what each registrar's purchase contract actually guarantees, which token scope belongs on which job, the failure codes an agent will hit in its first week, and the approval gate you need in front of any of it.

Why domain provisioning became an agent problem

Almost every other step in a deploy is already an API call. Compute, TLS certificates and CI all run from code. Naming did not, so the pipeline stopped at a browser: search, buy, then click through a DNS panel. Hemanth Guntupalli, Vice President of Engineering and Product at GoDaddy, put the reason for closing that gap plainly in the launch post: "An agent can scaffold the app, provision the infrastructure, and wire the deploy, but a browser step stops it cold."

The engineering problem is not the search call. It is the money. A GET that returns availability is free and infinitely retryable. A POST that registers lemonstand.dev charges a real card, creates a real registry object, and in most cases cannot be undone. Cloudflare states this in one line in its own docs: registrations are non-refundable once they complete successfully. An agent that retries a timed-out request the way it retries a failed read will buy two domains.

So the interesting part of all three APIs is the contract around that one call.

What GoDaddy actually shipped on 14 July 2026

The beta covers the first workflows a developer hits: finding a name, registering it, and managing DNS. Four pieces matter for automation.

A v3 surface for the money path. Availability checks run at POST /v3/domains/check-availability, natural-language suggestions at GET /v3/domains/suggestions, and registration splits into POST /v3/domains/registration-quotes followed by POST /v3/domains/registrations. Transfers, renewals and contacts still run on the older stable endpoints behind the same token and the same https://api.godaddy.com base URL. That split matters more than it looks, and the reason appears further down.

Personal Access Tokens with real scopes. PATs are required for all v3 Domains APIs. The classic sso-key developer key still works but is scheduled for deprecation. A PAT carries an expiry in days and one or more capability scopes, and can be revoked on its own without rotating an account-wide key pair.

Open access with machine-readable limits. Any GoDaddy account can generate a token. Rate limiting returns a 429 with Retry-After, RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset headers; the documented example shows Retry-After: 30 against a RateLimit-Limit: 600.

Documentation built for machines. Every docs page is served as markdown, the whole set is published as one plain-text file at /llms-full.txt, and OpenAPI specs ship per version namespace. The quickstart's first suggestion is to hand domains-v3.json to your model as context.

An alpha CLI called gddy wraps the same endpoints. Each command maps to a documented REST call, so a flow you prove at the terminal is the flow your agent runs.

The purchase contract: quote, consent, idempotency key

GoDaddy splits pricing from execution. POST /v3/domains/registration-quotes is free, locks the price and settings, and returns a quoteToken with a short expiry. Registration executes against that token. If the period in the execute call does not match the quote, the API returns QUOTE_MISMATCH rather than a surprise invoice. An expired token returns QUOTE_EXPIRED and you re-quote.

The execute call takes three things beyond the token: a per-attempt Idempotency-Key, a consent object, and nothing resembling a payment instrument.

curl -s -X POST "https://api.godaddy.com/v3/domains/registrations" \
  -H "Authorization: Bearer $GODADDY_PAT" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "quoteToken": "qt_abc123...",
    "domain": "lemonstand.dev",
    "period": 1,
    "consent": {
      "agreedAt": "2026-07-02T10:30:00.000Z",
      "agreementTypes": ["DNRA"]
    }
  }'
Enter fullscreen mode Exit fullscreen mode

Three details in that request repay attention.

The Idempotency-Key is a UUID you generate per attempt. Replay the same key after a timeout and the server returns the original response instead of creating a second order. GoDaddy's docs are explicit that this is the only safe way to retry a registration. It is worth knowing that the header itself is still an IETF Internet-Draft, draft-ietf-httpapi-idempotency-key-header-07, working its way through the HTTPAPI working group on the standards track rather than a published RFC, so its semantics are a vendor promise per API, not a guarantee you can assume. Our own guide to idempotency keys for safe REST retries covers the server-side storage model this depends on.

The consent object records which registration agreement types were accepted and when. GoDaddy's documentation says these values should reflect the actual acceptance flow rather than hardcoded placeholders from an automation script. That is the hook your approval gate hangs on: an agent can prepare everything up to this object, but a human event has to produce it.

There is no card field anywhere in the request body. Registration draws on the payment profile attached to the account. If billing is not configured, the quote fails with NO_PAYMENT_PROFILE at HTTP 422 before any registration logic runs.

The gap in the contract is the one nobody advertises: transfer and renewal endpoints do not support Idempotency-Key. For those, GoDaddy documents a read-before-retry pattern instead. Call GET /v1/domains/{domain} first; if the domain is present, renewAuto has changed, or status is PENDING_TRANSFER, do not retry. An agent that treats every money-moving endpoint identically will be correct on registration and wrong on renewal.

Give the agent the smallest token that finishes the job

Scopes are the part most teams get wrong, because the token picker offers a "Domains & DNS" bundle that selects everything. Expand it and grant a subset. A write-scoped token satisfies read operations on the same resource; a read-scoped token is refused on writes with a 403.

Job the agent is doing Scopes it needs Scopes to withhold
Name discovery and price research domains.domain:read Everything else
Certificate renewal DNS updates in CI domains.domain:read, domains.dns:update domains.domain:create, domains.contact:update
Pointing a new app at an existing domain domains.domain:read, domains.dns:update, domains.nameserver:update domains.domain:create, domains.transfer:execute
Full register-and-configure loop domains.domain:read, domains.domain:create, domains.dns:update domains.domain:delete, domains.transfer:execute
Inbound transfer automation domains.domain:read, domains.transfer:execute, domains.transfer:update domains.domain:create, domains.domain:delete
Registrant contact maintenance domains.domain:read, domains.contact:update Every write scope on domains and DNS

The full set is 11 scopes: domains.domain:read, domains.domain:create, domains.domain:update, domains.domain:delete, domains.dns:update, domains.nameserver:update, domains.host:update, domains.forward:update, domains.contact:update, domains.transfer:execute and domains.transfer:update. One rule covers most of the risk: a CI job that renews certificates never needs domains.domain:create, and an agent doing name research never needs any write scope at all. If a token leaks, you revoke that token rather than rotating everything.

One trap sits underneath the scope model. A 403 does not always mean the scope is missing. GoDaddy returns 403 for both a missing scope and an ineligible account, with codes such as ACCOUNT_NOT_ELIGIBLE distinguishing them. The docs are blunt about the fix: match on the code field, never on the HTTP status alone, and never on the message text. The same discipline applies to the credentials themselves, which belong in a secrets manager rather than a config file; our note on AI agent credential isolation covers the pattern for handing short-lived secrets to a model-driven process.

Three registrar APIs, three different purchase contracts

The comparison below reflects each vendor's own current documentation as of 4 August 2026. It is the table to read before you pick a registrar for an automated pipeline, because the differences are not cosmetic.

Decision vector GoDaddy Domains v3 (beta, 14 Jul 2026) Cloudflare Registrar API (beta, updated 24 Apr 2026) AWS Route 53 Domains
Price lock before purchase quoteToken from a free quote call; mismatch returns QUOTE_MISMATCH No price-lock token; call Check immediately before registering No quote step; price is set by TLD
Double-charge protection Idempotency-Key header required on registration Not documented; docs warn against immediate retry after 202 DuplicateRequest error at HTTP 400 if an operation is already running
Credential model Personal Access Token with 11 assignable scopes, individually revocable Account API token with Registrar write permission IAM policy on route53domains actions
Async model Mostly synchronous; nameserver replacement returns 202 plus a Location header Waits up to 10 seconds, then 201 or 202; Prefer: respond-async forces async Returns an OperationId, polled with GetOperationDetail
WHOIS privacy default Set on the account profile privacy_mode defaults to redaction where the TLD supports it PrivacyProtectRegistrantContact defaults to true
Auto-renew default Set per domain after registration auto_renew defaults to false AutoRenew defaults to true
Renewals and transfers via API Yes, on the older stable v1 endpoints Not available in the beta Yes
Batch checks Availability endpoint per call Up to 20 domains per Check request Per-domain availability call
Published MCP server Read-only public server at https://api.godaddy.com/v1/domains/mcp Endpoints exposed through Cloudflare MCP by default Not documented on the API reference page

Two rows deserve a second look.

The auto-renew defaults invert between Cloudflare and AWS. Route 53 enables auto-renew on registration by default; Cloudflare's Registrar API leaves auto_renew at false. An agent that provisions across both and assumes one behaviour will silently drop a domain a year later. Set the flag explicitly, every time, in every provider.

The double-charge row is the one that decides architecture. Only GoDaddy currently documents a client-supplied idempotency key on the registration path. Cloudflare's guidance is behavioural rather than structural: treat 201 and 202 as expected outcomes and do not retry the same registration just because the first response was 202. Route 53 protects you at the server by rejecting a second concurrent request for the same domain with DuplicateRequest. Those are three different guarantees, and only one of them survives a client crash between the request and the response.

A provisioning flow that will not surprise you

The shape below assumes a coding agent with a read-scoped token in the discovery phase and a separate, tightly scoped token that only a human-approved job can reach.

Discovery and shortlisting run on the free calls. GoDaddy's gddy domain suggest and gddy domain available map to the documented endpoints, and Cloudflare's guidance applies to both platforms: search results come from cached data and are for discovery only, so re-check the final candidate against the registry before doing anything that costs money.

# Discovery: read-only token, no purchase capability anywhere in this step
gddy domain suggest "lemonade stand software" --tlds com --tlds dev --limit 5
gddy domain available lemonstand.dev

# Price lock: free, returns a short-lived quoteToken
gddy domain agreements --tld dev
gddy domain quote lemonstand.dev
Enter fullscreen mode Exit fullscreen mode

The quote is where the agent's job ends and the approval gate begins. Surface the exact price and the exact name to a person, capture that acceptance, and only then let a job holding the create scope execute against the token. GoDaddy requires both --agree and --confirm on the CLI purchase for the same reason.

# Execute: separate credential, human approval already captured
gddy domain purchase --quote-token <quoteToken> --agree --confirm

# Configure: "set" replaces records for this type and name, so re-running is safe
gddy dns set lemonstand.dev --type A --name @ --data 203.0.113.10 --ttl 600
Enter fullscreen mode Exit fullscreen mode

Registration is asynchronous in the general case. Poll GET /v3/domains/registrations/{id} until the status reaches COMPLETED or FAILED, and poll GET /v1/domains/{domain} until status is ACTIVE for first-time purchases on new accounts, which can sit in EXECUTING briefly. On Cloudflare the equivalent states are in_progress, succeeded, failed, action_required and blocked, and the documented rule is to stop polling on action_required and failed rather than looping.

Retries need backoff with jitter rather than a fixed interval, because synchronised retries across many clients turn a transient server problem into a retry storm:

import time, random

def retry_with_backoff(fn, max_attempts=4, base_delay=1.0):
    for attempt in range(max_attempts):
        try:
            return fn()
        except RetryableError:
            if attempt == max_attempts - 1:
                raise
            delay = base_delay * (2 ** attempt) + random.uniform(0, 1)
            time.sleep(delay)
Enter fullscreen mode Exit fullscreen mode

Note the TTL in the DNS call above. GoDaddy's minimum TTL for its hosted DNS is 600 seconds, so an agent that sets a 60-second TTL to speed up a cutover will have that value rejected or clamped. Plan the cutover around 10 minutes, not one.

The failure codes your agent will hit in week one

Most agent-driven provisioning failures are not exotic. They are billing and eligibility problems that surface at the quote step, which is exactly why the free quote call is worth making even when you already know the price.

Code and status What actually happened Correct agent behaviour
NO_PAYMENT_PROFILE (422) No payment method on the account Stop. Surface to a human; no retry will fix it
INVALID_PAYMENT_INFO (402) Payment authorisation failed at purchase time Stop and report; the card was declined or is unusable
ACCOUNT_NOT_FUNDED (403) Prepaid balance is zero with no fallback card Stop; this is a finance action, not an engineering one
MISSING_CONTACT (422) Registrant phone or address missing from the profile Stop; contact data has to be completed out of band
ACCOUNT_NOT_ELIGIBLE (403) Token scope is fine, the account is not Do not regenerate the token; check the code field
QUOTE_MISMATCH (422) Execute call disagrees with the quote, usually on period Re-quote and re-confirm the price with the requester
429 with Retry-After Rate limit hit, commonly by a bulk job Wait exactly Retry-After seconds; do not back off blindly

The pattern across that table is worth stating once: five of the seven cases are terminal for the agent and require a human. Building an agent that recognises a terminal failure and stops is more valuable than building one that retries cleverly. The real cost of agentic provisioning is not the API call, it is the blast radius of a loop that never gives up.

Cloudflare's Check endpoint fails in a different register, returning registrable: false with a reason such as domain_unavailable, extension_not_supported_via_api, extension_not_supported or extension_disallows_registration. The third and fourth of those mean the domain will never register through this path, so a retry is wasted work regardless of how long you wait.

What the MCP servers can and cannot do

Both vendors expose Model Context Protocol endpoints, and the capability gap between them and the REST APIs is deliberate.

GoDaddy's public MCP server sits at https://api.godaddy.com/v1/domains/mcp over streamable HTTP and requires no account or credential, because it uses public domain data only. It is documented as read-only: it cannot register domains, modify DNS records, transfer domains, update account settings, or make purchases. Adding it to a client is four lines of configuration:

{
  "mcpServers": {
    "godaddy": {
      "url": "https://api.godaddy.com/v1/domains/mcp",
      "transport": "streamable-http"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Cloudflare takes the opposite position and states that its Registrar endpoints are available through Cloudflare MCP by default, with example agent prompts in the documentation that include "Register example.com on my Cloudflare account." That is a more capable surface and a larger blast radius, and it makes the token permission the only thing standing between a conversation and a charge.

Neither approach removes the need to think about the MCP layer itself as an attack surface; the same hardening questions apply here as anywhere else, and our notes on MCP server hardening cover the configuration side. The design question for a platform team is simple: does the conversational surface get read scopes only, with purchases routed through a separate audited job? For anything that spends money, the answer should be yes.

India-specific considerations

Three constraints change the design for Indian teams, and none of them appear in the API documentation.

The .in bulk-booking cap. NIXI, the .IN registry, published a notice in December 2021 stating that an individual registrant requesting more than two .in domains, or an accredited company requesting more than 100, requires written approval from the CEO of NIXI. The Internet Freedom Foundation obtained NIXI's justification for the rule under the Right to Information Act, and the answer given was "national security". Whatever the merits, the engineering consequence is concrete: a brand-protection agent that sweeps up defensive .in registrations will hit a manual approval gate that no retry policy can clear. Design the workflow to request approval, not to retry.

Registrant data under the DPDP Act. A registration payload carries the registrant's name, email, phone and postal address. That is personal data, and the Digital Personal Data Protection Act 2023 makes the data fiduciary responsible for reasonable security safeguards, with penalties reaching Rs 250 crore for a breach traced to their failure. An agent that logs full request bodies for debugging has just written registrant contact data into your observability stack. Redact contact objects before they reach logs, and keep the token that carries domains.contact:update out of any general-purpose agent.

Registration data minimisation is now the global default. ICANN's Registration Data Policy took effect on 21 August 2025 and replaced the earlier interim arrangements for gTLDs, with requirements covering the collection, transfer and retention of registration data. Both Cloudflare and AWS reflect the direction in their defaults: privacy_mode defaults to redaction where the TLD supports it, and Route 53 defaults PrivacyProtectRegistrantContact to true. If your provisioning code explicitly sets privacy off, someone chose that, and it is worth finding out who and why.

What to build before you hand over a purchase scope

A short list, in the order we would build it.

Start with two credentials, not one. A discovery token with domains.domain:read lives wherever the agent lives. A purchase token with domains.domain:create lives in a job the agent can request but cannot execute. This single split removes most of the risk without any new infrastructure.

Put a spend ceiling in the code path, not the prompt. A brief such as "under $20 a year" is guidance to a model, not a control. The quote response carries the exact price; compare it to a hard number in your own code and fail closed if it exceeds it.

Record the approval as data. The consent object wants a real timestamp and a real agreement type. Store the same acceptance event on your side, with the requester's identity, the quoted price and the quote token, so a purchase can be reconstructed later without reading model transcripts.

Make every configuration call replaceable rather than additive. gddy dns set replaces the records for a type and name, which makes re-running it safe. Prefer that shape over anything that appends, because an agent will re-run it.

Log the code, not the message. GoDaddy's error envelope returns a stable machine-readable code, a human-readable message, and per-field fields[] details on validation failures. Branch on code. Your error handling should not break because a vendor improved a sentence.

The wider pattern here is the same one that shows up in every agent integration we build: the API design decides how much you have to defend in your own code. A tool surface with a price lock and an idempotency key needs a thin wrapper. One without them needs a state machine. Our comparison of tool API styles for AI agents works through that trade-off across REST, GraphQL and gRPC, and it sits inside the broader 2026 web platform developer guide for teams planning this year's platform work.

FAQ

Does the GoDaddy v3 registration endpoint really require an idempotency key?

Yes. GoDaddy's documentation states that POST /v3/domains/registrations requires an Idempotency-Key header, and that sending the same key on a retry returns the original response instead of creating a second order. Generate a fresh UUID per attempt and reuse it only when retrying that specific attempt after a timeout.

What happens if I retry a domain renewal after a timeout?

Transfer and renewal endpoints do not support the Idempotency-Key header. GoDaddy documents a read-before-retry pattern instead: call the relevant read endpoint first, and if the domain shows the change already applied, do not retry. Treating renewal like registration is how teams double-charge themselves on money-moving calls.

Can the GoDaddy MCP server buy a domain for me?

No. The public MCP server uses public domain data only, requires no account credential, and is documented as read-only. It cannot register domains, modify DNS records, transfer domains, update account settings or make purchases. Registration still runs through the authenticated v3 REST API with a scoped Personal Access Token behind it.

How is the Cloudflare Registrar API different from GoDaddy's for automation?

Cloudflare's beta has no price-lock token, so its guidance is to call Check immediately before registering. It waits up to 10 seconds and returns 201 or 202, with Prefer: respond-async forcing async behaviour. Renewals, transfers and contact updates are not yet available through that API beta.

Which token scope should a CI job that updates DNS records have?

Only domains.domain:read and domains.dns:update. A certificate-renewal job never needs domains.domain:create, and withholding it means a compromised pipeline token cannot register anything. GoDaddy's Personal Access Tokens are individually revocable, so a leaked CI token is revoked without rotating any other credential.

Why does my call return 403 when the token has the right scope?

GoDaddy returns 403 for two different situations: a missing scope, and an account that is not eligible for the operation. The response body carries a distinguishing code, such as ACCOUNT_NOT_ELIGIBLE. Read that field before regenerating tokens, because a new token will not fix an eligibility problem.

Can an agent bulk-register .in domains for brand protection?

Not without a human step. The NIXI notice published in December 2021 requires written approval from the CEO of NIXI when an individual requests more than two .in domains or an accredited company requests more than 100. Build the workflow to raise an approval request rather than to retry a rejected registration.

What is the minimum DNS TTL I can set on GoDaddy-hosted DNS?

600 seconds, which is 10 minutes. An agent that sets a shorter TTL to accelerate a cutover will not get it. Plan any traffic move around a 10-minute propagation floor on GoDaddy-hosted zones, and lower the TTL well before the cutover window rather than at the moment of the change.

How eCorpIT can help

eCorpIT builds and hardens the provisioning layer that sits between a coding agent and a vendor API that can spend money: scoped credential design, approval gates that produce auditable consent records, idempotent job wrappers, and the error taxonomy that tells an agent when to stop. We are CMMI Level 5, MSME certified and ISO 27001:2022 certified, and we design applications aligned with Digital Personal Data Protection Act 2023 requirements where registrant or customer contact data is handled. If you are wiring agents into anything transactional and want the failure modes closed before they reach production, talk to our engineering team.

References

  1. Introducing the GoDaddy Developer Platform: Domain APIs for Developers and Their Agents - GoDaddy, 14 July 2026.
  2. GoDaddy Developers: Authenticate and PAT scopes - full scope reference.
  3. GoDaddy Developers: Handle errors - error envelope and status code guide.
  4. GoDaddy Developers: full documentation set as plain text - idempotency, rate limits and retry guidance.
  5. GoDaddy MCP server - read-only public tools and limitations.
  6. GoDaddy Developers: quickstart - token to first call.
  7. Cloudflare Registrar API - beta workflow, response codes and limitations, updated 24 April 2026.
  8. Amazon Route 53 RegisterDomain API reference - parameters, defaults and error types.
  9. The Idempotency-Key HTTP Header Field, draft-ietf-httpapi-idempotency-key-header-07 - IETF HTTPAPI working group.
  10. ICANN Registration Data Policy - effective 21 August 2025.
  11. NIXI's justification for 2 domains per person? National Security - Internet Freedom Foundation, 15 February 2022.
  12. Penalties and adjudication under India's DPDP Act 2023 - King Stubb and Kasiva.
  13. Model Context Protocol - open standard for connecting AI clients to external tools.

Last updated: 4 August 2026.

Top comments (0)