Short answer: registrar APIs and DNS interfaces solve different jobs. Use a registrar API for domain registration, transfer, renewal, and contact or lock state; use a DNS interface for records and answers. During an e-commerce migration, keep the customer-owned zone authoritative when the customer must retain control, and use a platform-owned zone only when your product explicitly owns the domain lifecycle.
This boundary is easy to describe and surprisingly easy to blur. A checkout can be healthy while a nameserver change is still propagating, or a transfer can complete while the old zone continues serving an obsolete verification record. Treat the two surfaces as separate workflows with separate audit trails.
How do registrar APIs and DNS interfaces differ during a migration?
The registrar is the registry-facing control plane. Its operations change who holds a domain, which registrar sponsors it, whether transfer lock is enabled, and where the authoritative nameservers point. Those actions have ownership and authorization consequences. A DNS interface is the zone control plane: it creates, updates, and removes records such as A, AAAA, CNAME, TXT, and MX. It changes answers, not legal or account ownership.
The overlap is the nameserver handoff. A registrar API can set the delegation to a nameserver set, while the DNS interface serves the zone behind that delegation. Calling one surface to accomplish the other's job creates a migration that looks complete in one dashboard and incomplete from the public DNS.
Separate jobs.
| Concern | Registrar API | DNS interface |
|---|---|---|
| Registration, renewal, transfer lock | Authoritative | Out of scope |
| Nameserver delegation | Changes delegation | Serves the delegated zone |
| A, AAAA, CNAME, MX, TXT records | Usually out of scope | Authoritative |
| Ownership and approval trail | Account and policy state | Zone change and observation |
I model a customer domain as two resources with an explicit link:
from dataclasses import dataclass
@dataclass(frozen=True)
class DomainPlan:
domain: str
ownership: str # "customer" or "platform"
nameservers: tuple[str, ...]
verification_token: str
def migration_actions(plan: DomainPlan) -> list[str]:
actions = ["publish_verification_txt", "wait_for_observation"]
if plan.ownership == "customer":
actions.append("ask_customer_to_change_delegation")
else:
actions.append("apply_delegation_under_platform_account")
actions.append("validate_dmarc_and_mail_records")
return actions
The code is a planning boundary, not a provider SDK. In production, each action should emit an idempotency key, actor, requested change, and observed result. Never infer ownership from a successful DNS write; a customer-owned zone can accept a record while the registrar still delegates elsewhere.
What should customer-owned and platform-owned zones guarantee?
Customer-owned zones are the safer default for a registrar migration. The customer keeps the registrar account, billing relationship, transfer lock, and nameserver authority. Your application asks for narrowly scoped records, usually through a documented interface or a guided change, and then verifies the public result. This preserves portability: the storefront can move without forcing a registrar transfer.
The trade-off is coordination. You cannot promise instant activation when the customer controls delegation, and you must explain that a low DNS TTL does not make registrar or registry operations immediate. Your UI should show requested, observed, and confirmed states instead of one optimistic “connected” flag.
Platform-owned zones fit a different contract. They are appropriate when the platform sells the domain, manages renewals, and is the accountable operator for nameservers. Central ownership makes automation predictable, but it creates a larger blast radius: an account policy error can affect many shops. It also makes exit, transfer authorization, and support escalation part of your product obligations.
The catch is that neither model removes the need for evidence. Record the delegation observed from independent resolvers, the zone version you intended to publish, and the time each state changed. A migration is not done because an API returned success; it is done when the public DNS and the ownership ledger agree.
A migration sequence that survives partial completion
Start with discovery. Capture current nameservers, DNSSEC status, mail records, verification records, transfer lock, and the registrar account owner. Snapshot the zone before changing it. This is where many “simple” migrations fail: an engineer copies the web record and silently drops MX or TXT data used by mail security and third-party services. The failure can sit unnoticed for hours because browser checks hit the new address while a resolver with the old delegation still serves the previous zone; meanwhile, an order confirmation may be rejected by a receiver enforcing the domain's DMARC policy. A useful runbook therefore names the record owner, the observation method, the rollback trigger, and the person who can approve a registrar action. It also records what “confirmed” means for each dependency, since web traffic, email, and certificate validation do not necessarily converge at the same moment.
Next, lower TTLs only where your operational plan benefits from faster rollback, then publish the destination records in the currently authoritative zone. Validate from more than one resolver. For email, preserve the DMARC policy and its reporting address; RFC 7489 defines DMARC records as DNS TXT data and describes how receivers evaluate alignment and policy. A storefront cutover that breaks DMARC can damage order-mail delivery even when the website loads.
Then change delegation or transfer state through the registrar workflow that actually owns that operation. Keep this step behind an approval boundary for customer-owned domains. Poll for observed nameserver convergence, but use a deadline and a human escalation path. DNS caches expire on their own schedule.
Finally, compare the new public answers with the snapshot. Keep the old zone available for the rollback window, and make rollback a recorded change rather than an emergency manual edit. I would measure activation latency, verification retry count, stale-resolver duration, and mail delivery signals before copying this sequence to every tenant. Your mileage may vary because resolver behavior, registry policy, and customer DNS providers differ.
Limits and a practical decision rule
An interface abstraction cannot hide authority boundaries. A DNS API cannot transfer a domain, and a registrar API cannot safely manage every record in a customer’s zone. Some customers will not delegate nameservers or grant write access; that is a capability boundary, not a failed migration. Give them a verification-only path and clear manual instructions.
Choose customer-owned zones when portability, customer control, or an existing registrar relationship matters. Choose platform-owned zones when your service is genuinely the registrar operator and can carry renewal, transfer, DNSSEC, and support responsibilities. In both cases, model registrar actions and DNS changes as different jobs, and require public observation before declaring success.
References
- RFC 7489, Domain-based Message Authentication, Reporting, and Conformance (DMARC): https://datatracker.ietf.org/doc/html/rfc7489
Further reading
- ICANN Transfer Policy: https://www.icann.org/resources/pages/transfer-policy-2016-06-01-en
Top comments (0)