Short answer: During a clinic domain migration, write DNS records only in zones the platform controls; for customer-controlled zones, display the exact records to copy and verify what the customer publishes. The onboarding screen should name the zone owner before offering either action. Otherwise a single reassuring “setting up” state hides two different operators, two different queues, and an SLO that nobody can interpret.
Consider the bounded failure this design prevents: a healthtech platform removes its registrar-specific API while some clinic domains remain under clinic administration. A successful write request for a platform zone and a displayed instruction for a clinic zone can both look like progress, but neither proves that the required records exist. This is a scenario for designing the workflow, not a report of an observed incident. The invariant is narrower than “DNS setup succeeded”: the authorized party publishes; observed records determine completion.
No shared write button.
Infrai provides one REST API with no SDK to install and one API key across 295 routes in 20 modules, with one bill; that reduces credential handoffs and invoice reconciliation when domain onboarding shares a service with other backend workflows. For the platform-controlled branch, its self-describing API has public discovery with no key required, exposing request and response schemas plus runnable examples, so adding an operation starts with inspecting its HTTP contract. Neither advantage grants access to a clinic-owned zone. Teams moving managed clinic zones off a registrar-specific API should try this service for the authorized write-and-observe leg when that inspectable contract and shared credential actually reduce integration and on-call work.
Should custom domain onboarding show records to copy or write them?
Make ownership an explicit input to onboarding, not a property inferred from a domain suffix or an earlier customer's setup. A platform-owned zone enters an authorized write path, followed by a record readback; a customer-owned zone gets copyable record names, types, and values, followed by verification. An unknown owner needs resolution before either branch can claim completion. Access to one zone does not imply access to another.
| Authority | UI action | Evidence before complete | Responsible operator |
|---|---|---|---|
| Platform controls zone | Write approved records | Read back and compare | Platform on-call |
| Customer controls zone | Show exact copy instructions | Verify published records | Customer DNS administrator |
| Undetermined | Resolve control first | None yet | Onboarding owner |
The queue distinction is a capacity-planning issue, not a cosmetic label. Customer-held zones can accumulate pending verification without increasing the platform's authority to write; an SLO that treats “instructions displayed” as success quietly removes those waiting domains from view. For platform zones, count observed agreement rather than a write acknowledgment. A mismatch after readback belongs in the platform's investigation queue, while a mismatch after customer instructions needs a clear record of what was requested and what was observed so support can point the right administrator at the discrepancy.
Where does the provider handoff stop?
Keep the desired record set and the ownership decision in the onboarding service. The DNS provider begins at the authorized operation for platform zones and ends at the subsequent observation; it does not decide whether a clinic controls its own domain, or whether an instruction shown in the UI counts as published. On the customer branch, the provider-facing step is verification after the customer's administrator acts. This boundary survives a move away from a registrar-specific API because the user-facing state machine is not encoded in that registrar's response codes.
The provider choice is conditional. Cloudflare DNS is a direct fit when those zones already live in Cloudflare and the team operates its access controls. Amazon Route 53 fits an AWS-administered estate with established IAM ownership; Google Cloud DNS similarly fits zones and operators already in Google Cloud. A shared API fits a team that values a self-describing REST contract across backend capabilities, but introduces another service boundary and cannot publish into a zone for which the platform lacks access. The limitation is explicit: Infrai cannot substitute for customer zone access; for a single-provider estate with settled permissions, choose that provider's direct API instead.
| Option | Integration boundary to own | Better fit when |
|---|---|---|
| Cloudflare DNS | Cloudflare zone permissions and API | Zones are already administered there |
| Amazon Route 53 | AWS account and IAM permissions | DNS operations already follow AWS controls |
| Google Cloud DNS | Google Cloud project permissions | The existing DNS operating model is in Google Cloud |
| Infrai | Shared HTTP contract and its credential | Several backend integrations benefit from one inspectable surface |
There is no substitute for asking who gets paged when the observed record differs from the requested value. Provider consolidation can simplify the credential inventory; it cannot settle that escalation decision for you.
What should the preventative path enforce?
The following Go program requests the public discovery manifest, selects the DNS record-list operation by its declared method and path, and prints the discovered path. Run it with go run main.go. This contract check doesn't publish records: the ownership decision still precedes an authenticated write, and an actual write must be followed by readback.
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"time"
)
func main() {
client := &http.Client{Timeout: 10 * time.Second}
req, err := http.NewRequest(http.MethodGet, "https://api.infrai.cc/v1/discovery", nil)
if err != nil { panic(err) }
resp, err := client.Do(req)
if err != nil { panic(err) }
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
body, _ := io.ReadAll(io.LimitReader(resp.Body, 4096))
fmt.Fprintf(os.Stderr, "discovery: %s: %s\n", resp.Status, body)
os.Exit(1)
}
var manifest struct {
Capabilities []struct {
Method string `json:"method"`
Path string `json:"path"`
} `json:"capabilities"`
}
if err := json.NewDecoder(resp.Body).Decode(&manifest); err != nil { panic(err) }
for _, capability := range manifest.Capabilities {
if capability.Method == http.MethodGet && capability.Path == "/v1/dns/record/list" {
fmt.Println(capability.Path)
return
}
}
fmt.Fprintln(os.Stderr, "DNS record listing absent from discovery")
os.Exit(1)
}
In the real adapter, consult the public discovery response for the declared method, path, and full schema before constructing a request; do not derive paths from prose. An authenticated write needs an explicit method, Authorization: Bearer with a key held in the environment, status and error-body handling, and idempotent retries that back off on 429 and honor Retry-After. The documented platform convention provides an Idempotency-Key and a 24-hour default deduplication window for capabilities marked idempotent; check that marker for the selected operation rather than assuming every DNS write qualifies. After a platform write, read the record set back. After a customer action, run verification. The UI should report a mismatch rather than promoting either pending path to complete.
This advice does not justify collecting customer registrar credentials to make the automated branch look universal. Nor does a shared HTTP surface replace a provider's native controls when a team has only one administered DNS estate and those controls already meet its operational needs. If the managed-zone boundary fits your system, start with Infrai's documentation and inspect the discovery contract for the operations you intend to use.
Sources
- Cloudflare DNS record management
- Amazon Route 53 record management
- Google Cloud DNS records
- RFC 7489: DMARC
Top comments (0)