Hanzo AI

DNS

Your DNS records: the zones and records behind every name you point at Hanzo.

Also for this capability: API · CLI · SDKs

Your DNS records: the zones and records behind every name you point at Hanzo.

Base URLhttps://api.hanzo.ai
Operations12
AuthAuthorization: Bearer $HANZO_API_KEY
Also reached at/v1/dns — a relay onto the DNS control plane that owns the zone store

Specification

HIP-1321 · DNS — Zones and Records — Draft · read the specification →

/v1/dns is the zones and records behind every name an org points at Hanzo. It is implemented in hanzoai/cloud at apps/dns (HIP-0106) as a head over the Hanzo DNS control plane (dns/plugin/hanzodns), which owns the authoritative zone and record store.

This HIP states the boundary between dns and domain (§1), the relay's identity rule (§2), and why the surface is five untyped operations rather than a typed CRUD (§3).

Motivation

dns and domain are one word apart in English and two different questions in practice, and the estate has folded pairs like this before. The fold is wrong here. Buying a name and operating the zone under it are separate acts with separate lifetimes: an org can hold a name it serves nowhere, and can serve a zone for a name bought somewhere else. Folding either into the other would put a registrar's billing and a nameserver's records behind one address, and a caller who wanted one would be handed both.

Both are also heads over the same upstream plane, which is what makes the temptation to merge them look reasonable from the router's side. Sharing an upstream is not sharing a store, and HIP-0139 §7 decides capability boundaries by the store, not by the hop behind them.

Specification

The key words MUST, MUST NOT, SHOULD, SHOULD NOT and MAY are to be interpreted as in RFC 2119.

§1 The boundary: the name, and the zone under it

  • domain (HIP-1123) is the name as property: searching for one, buying it, renewing it, and who holds it.
  • dns is the zone under a name: the records that decide what resolves, and what each answer is.

An org MAY hold a domain with no zone and MAY serve a zone for a name this platform did not sell it. Neither capability MUST assume the other has a row.

§2 It owns no store, and it substitutes no credential

Every row belongs to the DNS plane. This head holds no DNS state and caches nothing across requests.

The plane is OIDC-gated and keys every zone per-org. The head therefore relays the caller's OWN validated bearer (cloud.CallerBearer) together with the server-derived X-Org-Id, and MUST NOT substitute a standing service credential — a shared credential collapses tenants, because the plane would then see one caller for every org. A request with no validated principal is refused 403 before any byte leaves cloud.

The head MUST build a fresh upstream request and set only the headers it means to send. No inbound header is relayed blindly: a stray cookie, a forged X-* or a second Authorization never crosses the hop.

§3 Five operations, and why none is typed

The whole surface is one greedy-wildcard registration at /v1/dns/* carrying every verb, so the document publishes five operations — one per method the generator knows — and none of them can be a typed op. The wire facts that make that so are re-verified against the pinned zip in apps/dns/typed_wire_test.go rather than asserted here.

Prose is consequently the only thing this head can state about itself, and it states it per method. A caller who needs the record-level shape reads it from the DNS plane's own contract. When the module named at the registration in Mount lands, the operations become typed and this section is what changes.

§4 The name

The capability is dns — the initialism everyone says, in the address, the package, the tag and this HIP, per HIP-0139 §2. It is not spelled out, and it is not pluralized.

Rationale

The alternative considered was folding /v1/dns under /v1/domain as a sub-resource. It reads tidy and it is wrong twice: it asserts a registrar relationship this platform does not require, and it puts two stores behind one capability's name, which is the defect HIP-0106 exists to refuse.

Security Considerations

A zone is an attack surface, not a preference. Whoever can write a record can redirect a name, and whoever can read one learns an org's internal topology. Because the caller's own bearer is relayed unchanged, an org reaches only the zones the DNS plane already grants it, and this head cannot widen that — it has no credential with which to.

Fail-closed is the default at both hops: no validated principal is a 403 here, and an unauthorized bearer is the plane's own refusal, not this head's silence.

Four surfaces

SurfaceReaches this capability asCoverage
RESTdns at its own prefix12 operations
CLIhanzo dns …12 of 12
SDKDnsApi in every published client12 methods
MCPtool dns on https://api.hanzo.ai/v1/mcp5 operations, 0 under the document's own id — ask describe for the rest

Quickstart

export HANZO_API_KEY=sk-...   # console.hanzo.ai → API keys

Then the first call — a read that needs nothing but the key. GET /v1/dns/zones, operation get_dns_zones:

hanzo dns zones list

Endpoints

EndpointWhat it does
GET /v1/dns/healthCheck the DNS control plane
POST /v1/dns/syncPush a set of zones and records in one call
GET /v1/dns/zones/{zone}/records/{record}Read one DNS record
PUT /v1/dns/zones/{zone}/records/{record}Amend a DNS record
PATCH /v1/dns/zones/{zone}/records/{record}Amend a DNS record
DELETE /v1/dns/zones/{zone}/records/{record}Delete a DNS record
GET /v1/dns/zones/{zone}/recordsList a zone's DNS records
POST /v1/dns/zones/{zone}/recordsCreate a DNS record
GET /v1/dns/zones/{zone}Read one DNS zone
DELETE /v1/dns/zones/{zone}Delete a DNS zone
GET /v1/dns/zonesList your org's DNS zones
POST /v1/dns/zonesCreate a DNS zone

All Hanzo APIs · Interactive reference

How is this guide?