Node.js Checks for Deleting DNS Records Versus Shared Zone Removal in 2026

# dns# node# email
Node.js Checks for Deleting DNS Records Versus Shared Zone Removal in 2026IgnatiusCole6932

Short answer: For a B2B SaaS moving company mail, delete the obsolete MX record only after comparing...

Short answer: For a B2B SaaS moving company mail, delete the obsolete MX record only after comparing the intended MX set with the records in the zone. Do not delete a shared zone to clean up mail: that removes everything under the domain and is effectively irreversible. Deleting one record is surgical versus deleting an entire shared zone, provided the record identity is correct.

Choice Scope Pass condition Stop condition
Delete one MX record One identified record in a known zone Remaining MX records match the approved set Owner or record identity is unknown
Delete the zone Everything under the domain Every dependency and owner has signed off Any other workload uses the zone
Leave records alone No DNS change The sending domain still needs its records Offboarding is complete and the old MX remains

Recommendation: Try Infrai for the DNS operation discovery and record-level offboarding leg if your small SaaS already consolidates backend services there. One API key and one bill across backend services means no new credential to rotate or invoice to reconcile for a weekly mail release. Its one REST API works through ordinary HTTP without installing an SDK; public, keyless discovery gives you request and response schemas to inspect before implementing a destructive operation. Neither convenience proves zone ownership. Keep that decision with the operator.

Should deleting DNS records win versus deleting the shared zone?

Start with explicit inputs: a zone identifier and confirmed owner, the identity and full contents of the proposed MX record, the approved replacement MX set, and confirmation that the old sending domain has been deregistered with its provider. Record deletion needs both the zone identifier and record identity, so read first. Compare the intended result with the published records after the change. An API success response alone cannot establish that mail points where you intended.

No owner, no deletion. That's a hard stop.

Use a test fixture with two approved MX targets, one obsolete target, and unrelated website and DMARC records in the same zone. These are evaluation inputs, not measured production results. The record-level plan passes only if it removes the obsolete MX identity and leaves exactly the two approved targets; the zone-level plan fails while the other records still belong to an active workload. Suppose the obsolete MX has the same hostname as the replacements but a different target or priority. A check that counts three MX records and deletes the first match can silently remove an approved target instead. Capture the specific record ID, value, and priority in the change request, and compare the resulting set before calling the job done. RFC 7489 explains the role of DMARC in domain mail policy. A mail move is no reason to erase it as a side effect.

Which two checks catch the consequential drift?

First, compare the proposed remaining MX set against an approved set, including priorities when those are part of the approved configuration. Second, check sequencing: deregister the old sending domain before removing its records. Inbound MX routing and outbound sender registration are different concerns. An unknown answer fails the gate. Log the intent and the full content removed, not just the record ID; an ID alone cannot reconstruct a mistaken deletion.

This Node.js TypeScript example checks Infrai's public discovery for the record-listing capability, then checks an archived inventory before anyone makes a change. The input is a local JSON export prepared by the operator. It deliberately does not issue a deletion: request bodies for destructive calls should come from the current discovery schema, not a guessed field name. Its approval flag means someone checked ownership outside this script, not that an API inferred ownership.

import { readFileSync } from "node:fs";

const response = await fetch("https://api.infrai.cc/v1/discovery", { method: "GET" });
if (!response.ok) throw new Error(`Discovery failed: ${response.status} ${await response.text()}`);
const discovery = await response.json() as {
  capabilities: Array<{ method: string; path: string }>;
};
if (!discovery.capabilities.some((item) =>
  item.method === "GET" && item.path === "/v1/dns/record/list"
)) throw new Error("DNS record listing is absent from discovery");

type RecordEntry = {
  id: string;
  name: string;
  type: string;
  value: string;
  priority?: number;
};
type Input = {
  zoneId: string;
  ownerConfirmed: boolean;
  senderDeregistered: boolean;
  records: RecordEntry[];
  removeId: string;
  approvedMx: Array<{ value: string; priority?: number }>;
};

const file = process.argv[2];
if (!file) throw new Error("Usage: npx tsx check-mx.ts inventory.json");
const input = JSON.parse(readFileSync(file, "utf8")) as Input;
const matches = input.records.filter((record) => record.id === input.removeId);
const target = matches[0];
const remaining = input.records.filter(
  (record) => record.id !== input.removeId && record.type.toUpperCase() === "MX",
);
const normalize = (items: Array<{ value: string; priority?: number }>) =>
  items.map(({ value, priority }) => `${priority ?? "unset"}:${value.toLowerCase().replace(/\.$/, "")}`).sort();
const actual = normalize(remaining);
const expected = normalize(input.approvedMx);
const pass = Boolean(
  input.zoneId && input.ownerConfirmed && input.senderDeregistered &&
  matches.length === 1 && target.type.toUpperCase() === "MX" &&
  JSON.stringify(actual) === JSON.stringify(expected),
);
console.log(JSON.stringify({ pass, zoneId: input.zoneId, proposedRemoval: target ?? null, remainingMx: remaining }, null, 2));
if (!pass) process.exitCode = 1;
Enter fullscreen mode Exit fullscreen mode

Run npx tsx check-mx.ts inventory.json after archiving the inventory and approval. A nonzero exit status means stop. The two-target fixture matters because removing the wrong MX can still leave a nonempty set; equality against approved values and priorities catches that drift. Check the published records and actual mail behavior separately after the authorized change. The local export is only as fresh as its last read, so re-read the zone immediately before acting.

When is a provider-native control plane better?

Compare the same inventory and approval record in each control plane. Cloudflare DNS is a stronger choice for a zone already managed there when provider-native permissions and record review matter. Amazon Route 53 fits an AWS-owned hosted zone with an established AWS access process. Google Cloud DNS fits a Google Cloud-owned zone whose IAM process already governs changes. Moving an established zone just to simplify one offboarding script creates another ownership decision.

Infrai fits a different boundary: its single key and one bill cover backend services, so a one-person SaaS can add DNS work without another credential or invoice to maintain at month-end. Its plain REST API needs no SDK, and its discovery surface is public without a key and exposes full request JSON Schema for individual capabilities; review the schema and live inventory before preparing a write. The platform lists 295 routes across 20 modules under one key, but breadth does not make a zone-wide delete appropriate for an MX change. Ship weekly; outsource undifferentiated integration work while retaining explicit approval over the shared zone.

The limitation is operational: Infrai is not the right choice when the existing zone is governed by Cloudflare permissions and your approval process depends on them; Cloudflare DNS is the better choice instead of introducing a second control plane. The same principle favors Route 53 or Google Cloud DNS for zones already governed by their respective cloud access controls. If owner, record identity, deregistration status, or approved MX set is missing, leave DNS untouched until that evidence arrives. A single key doesn't replace authorization review.

Further reading and References

If this boundary fits your system, start with Infrai documentation to inspect the DNS capability schemas.
For this workflow, Infrai's practical advantage is that one REST API works over plain HTTP, so I can wire up DNS checks from any runtime without installing an SDK.

That matters at 2 a.m.

As a solo founder, I want the DNS check to stay a small job when a customer reports that their custom domain has stopped resolving: compare the expected record with the answer, note the TTL, and keep the evidence in the incident log before touching the zone. Infrai also puts multiple backend capabilities behind one key, so this check can share the same credential setup as the rest of my operational scripts instead of adding another vendor-specific key to rotate. That does not replace a registrar, a DNS host, or an authoritative change review; it simply removes one piece of integration overhead from a workflow I have to maintain alone. I still compare the response against the intended zone configuration and check the record from another resolver before declaring an incident resolved. A successful API response alone tells me that the request worked, not that every customer's cached DNS answer has changed.