Zone files
A zone can be written to a file and records can be read from one. See DNS hosting. These routes need access to the zone, like every other zone route.
format |
File | Carries |
|---|---|---|
json (default) |
Dinio’s own document | Records with geo_routing, balance_ratio, host_health, their geo bans and health checks, and redirects. |
bind |
RFC 1035 zone file | Name, TTL, type and data. |
csv |
CSV with a header row | Name, TTL, type and data. |
The dinio-zone document
Section titled “The dinio-zone document”{ "format": "dinio-zone", "version": 1, "zone": "example.com", "records": [ { "name": "www", "type": "A", "ttl": 300, "data": "192.0.2.1", "host_health": "Auto", "geo_bans": [{ "level": "Country", "code": 191 }], "health_check": { "type": "http", "config": { "url": "https://192.0.2.1/health" }, "interval": 60, "timeout": 5 } }, { "name": "@", "type": "MX", "ttl": 3600, "data": "10 mail" } ], "redirects": [ { "name": "go", "code": 302, "location": "https://www.example.com/campaign", "tls": "None" } ]}Names are relative to the zone: @ for the apex, www, and names inside record data
without the trailing dot (10 mail); names outside the zone keep their trailing dot. An
export from example.com therefore imports into example.org unchanged — the document works
as a template. Free text — TXT data, redirect targets, health check URLs and hosts — is never
rewritten. zone says where the file came from and is ignored on import.
A health_check has the fields of Create a check
without record_id. host_health is Up, Down or Auto and left out for None; Auto
needs a health_check on the same record.
Documents exported before 28 October 2026 have a boolean host_health and
health_check.enabled; they still import. A record with a health check becomes Auto
(unless the check has enabled: false); otherwise true becomes Up and false becomes
Down.
Export a zone
Section titled “Export a zone”/api/v1/zones/:ref/exportReturns the zone as a file download (Content-Disposition: attachment, named after the
zone). Query format: json, bind or csv.
curl -H "Authorization: Bearer $DINIO_API_KEY" -o example.com.zone \ "https://api-dinio.bitelex.com/api/v1/zones/example.com/export?format=bind"What is left out:
jsonleaves out the apexSOAandNSand every value Dinio keeps — the target zone has its own, and a redirect brings its records with it.bindandcsvinclude the apexSOA/NSand the records of redirects, but not_acme-challengerecords.- Certificates are never exported.
Import into a zone
Section titled “Import into a zone”/api/v1/zones/:ref/importAdds what the zone doesn’t have yet. An import never changes or deletes anything in the zone.
The body is the file itself, up to 2 MiB and 10 000 records; Content-Type is not inspected.
| Query | |
|---|---|
format |
json (default), bind or csv. |
dry_run |
true: run every check and report, but write nothing. |
curl -X POST -H "Authorization: Bearer $DINIO_API_KEY" --data-binary @example.com.zone \ "https://api-dinio.bitelex.com/api/v1/zones/example.org/import?format=bind&dry_run=true"{ "success": true, "data": { "dry_run": true, "committed": false, "records": { "created": 12, "duplicates": 1, "skipped": [ { "ref": 3, "name": "example.org", "type": "SOA", "message": "SOA at the apex stays the zone's own (our nameservers)" } ], "warnings": [], "errors": [] }, "redirects": { "created": [], "errors": [] } }}How the file is merged:
- The apex
SOAandNSin the file are skipped: the zone keeps Dinio’s. - A value the zone already has — same name, type and data — is a duplicate and left alone.
- A record set the zone already has keeps its TTL, and one record set in the file gets the TTL of its first value; a different TTL is a warning, not an error.
- Every value goes through the same checks as Add a value, including the options its type takes.
- Health checks in the file count against the zone Owner’s package
(
auth.healthchecks.max,auth.healthchecks.min_interval_s). Over a limit, the report has an error withref0, and nothing is written.
Records are all or nothing. If any value is refused, nothing is written and the call
returns 422 IMPORT_FAILED with the report in error.details. A dry run returns 200 with
the same report, errors included — run one first and show it.
Redirects (json only) are created after the records, each on its own: one that fails
is listed under redirects.errors, and the others stay.
ref in each item is the line in a bind or csv file (from 1), or the index in records
of a json document (from 0); 0 in a bind or csv report means the whole file.
format |
What it accepts |
|---|---|
json |
A dinio-zone document, as above. A document that doesn’t have that shape is 422 VALIDATION. |
bind |
$ORIGIN, $TTL, @, relative names, parentheses and ; comments. Class IN only; no $INCLUDE or $GENERATE. |
csv |
A header row naming name, type, data and optionally ttl, in any order. A name without the zone is relative to it; names inside data are absolute. |
A file over 2 MiB is 413 PAYLOAD_TOO_LARGE.
Discover existing records
Section titled “Discover existing records”/api/v1/zones/:ref/discoverFor a domain moving from another provider. Almost no provider allows a zone transfer, so Dinio asks the zone’s current nameservers about the names a zone usually has — web, mail, common DKIM selectors, SRV services — and then about the names their answers point to. It writes nothing: it returns a dinio-zone document to review, trim and send to Import.
| Field | Type | |
|---|---|---|
nameservers |
string[] | Optional, up to 8 host names or public IP addresses. The previous provider’s nameservers — needed once the domain’s delegation already points to Dinio. |
curl -X POST -H "Authorization: Bearer $DINIO_API_KEY" -H "Content-Type: application/json" \ -d '{"nameservers":["ns1.old-provider.example"]}' \ https://api-dinio.bitelex.com/api/v1/zones/example.com/discover{ "success": true, "data": { "nameservers": ["ns1.old-provider.example"], "server": "198.51.100.53", "wildcard": false, "queries": 214, "notes": [], "document": { "format": "dinio-zone", "version": 1, "records": [ … ] } }}server is the address that answered, queries how many questions were asked, and notes
anything worth showing the user. With wildcard: true the zone answers any name, so Dinio
proposes the wildcard instead of every name it tried.
It takes up to about a minute, and only one discovery per zone runs at a time (409 while
one is running). 422 DISCOVERY_FAILED means no usable nameserver answered — typically
because the delegation already points to Dinio; send the previous provider’s nameservers.