Health, forwarding and users over the API
This page covers the operational endpoints with curl examples. All need a
bearer token; see the API overview.
Health checks
Section titled “Health checks”# Listcurl -sk https://dtm.internal:8443/api/v1/healthchecks \ -H "Authorization: Bearer $DTM_TOKEN"
# Create a monitor-only check (status metrics, no DNS effect)curl -sk -X POST https://dtm.internal:8443/api/v1/healthchecks \ -H "Authorization: Bearer $DTM_TOKEN" \ -H "X-DTM-CSRF: 1" \ -H "Content-Type: application/json" \ -d '{ "name": "web-check", "protocol": "http", "target": "10.0.1.10:80", "interval_seconds": 15, "timeout_seconds": 5, "failure_threshold": 3, "http_config": {"path": "/healthz", "expected_status": [200]} }'A check created directly on /api/v1/healthchecks is monitor-only: it
probes and reports status (the dtm_health_check_status metric and the Health
Checks page) but never gates any record’s DNS answers. To make answers
health-aware, put a health_check_template on the record instead; see
health checks.
For HTTP/HTTPS checks, http_config can also carry authentication (headers,
oauth2, mtls, managed_identity) to probe secured backends; see
authenticated health probes.
Script checks
("protocol": "script", admin-only and disabled by default) carry a
script_config with the command and args to run. An optional
script_config.timeout_seconds overrides the top-level probe timeout for the
script run; like the top-level value, it must not exceed interval_seconds.
From v1.0.5, script_config can instead name a
managed script with script_id, and optionally
script_version and script_hash; without a version, the check pins the latest
one when you save it. A script_config with both a command and a script_id
is refused.
In the audit log, args values are masked (they routinely carry credentials)
while the command itself is recorded verbatim.
Check current status:
# One checkcurl -sk https://dtm.internal:8443/api/v1/healthchecks/<id>/status \ -H "Authorization: Bearer $DTM_TOKEN"
# All checks on this nodecurl -sk https://dtm.internal:8443/api/v1/health/status \ -H "Authorization: Bearer $DTM_TOKEN"Forwarders and stub zones
Section titled “Forwarders and stub zones”# Default forwarder (where unmatched queries go)curl -sk -X PUT https://dtm.internal:8443/api/v1/forwarders/default \ -H "Authorization: Bearer $DTM_TOKEN" \ -H "X-DTM-CSRF: 1" \ -H "Content-Type: application/json" \ -d '{"upstreams": ["168.63.129.16"], "enabled": true}'
# Conditional forwarder for one domaincurl -sk -X POST https://dtm.internal:8443/api/v1/forwarders \ -H "Authorization: Bearer $DTM_TOKEN" \ -H "X-DTM-CSRF: 1" \ -H "Content-Type: application/json" \ -d '{"domain": "corp.contoso.com.", "upstreams": ["10.0.0.1:53"], "comment": "AD DNS"}'
# Stub zonecurl -sk -X POST https://dtm.internal:8443/api/v1/stub-zones \ -H "Authorization: Bearer $DTM_TOKEN" \ -H "X-DTM-CSRF: 1" \ -H "Content-Type: application/json" \ -d '{"domain": "partner.local.", "hints": ["10.5.0.1:53"]}'See forwarders and stub zones for the concepts.
Blocklist
Section titled “Blocklist”curl -sk -X PUT https://dtm.internal:8443/api/v1/blocklist \ -H "Authorization: Bearer $DTM_TOKEN" \ -H "X-DTM-CSRF: 1" \ -H "Content-Type: application/json" \ -d '{"domains": ["doubleclick.net", "trackers.example"]}'User management requires the admin role. See users and access.
# List users (password hashes are stripped)curl -sk https://dtm.internal:8443/api/v1/users \ -H "Authorization: Bearer $DTM_TOKEN"
# Create a user (password >= 16 chars; role admin|editor|readonly)curl -sk -X POST https://dtm.internal:8443/api/v1/users \ -H "Authorization: Bearer $DTM_TOKEN" \ -H "X-DTM-CSRF: 1" \ -H "Content-Type: application/json" \ -d '{"username": "alice", "password": "long-enough-password-1234", "role": "editor"}'
# Update a user's role / enabled / passwordcurl -sk -X PUT https://dtm.internal:8443/api/v1/users/<id> \ -H "Authorization: Bearer $DTM_TOKEN" \ -H "X-DTM-CSRF: 1" \ -H "Content-Type: application/json" \ -d '{"role": "readonly", "enabled": true}'Cluster membership
Section titled “Cluster membership”# List nodes with status, region, addresscurl -sk https://dtm.internal:8443/api/v1/nodes \ -H "Authorization: Bearer $DTM_TOKEN"
# This node's own infocurl -sk https://dtm.internal:8443/api/v1/nodes/self \ -H "Authorization: Bearer $DTM_TOKEN"Restart a node’s service
Section titled “Restart a node’s service”Added in v1.0.7. Restart the DTM service on one node without touching its virtual machine, for example when a setting takes effect only after a restart. The Lifecycle page’s Restart service card does the same for the node the console is connected to. Send the request to the node you want to restart:
curl -sk -X POST https://<node>:8443/api/v1/lifecycle/restart \ -H "Authorization: Bearer $DTM_TOKEN" \ -H "X-DTM-CSRF: 1"202 means the restart has started; the answer is sent before the node shuts
down. The node stops reporting ready, waits out its drain grace so traffic
moves to the other nodes, stops, starts again and rejoins the cluster, while
the other nodes keep answering. Wait for it to report ready before you restart
the next one.
It is refused with 409, naming the reason, when:
- no other node in the cluster answers its readiness check, so the restart would leave nothing to answer DNS. A single-node deployment is always refused: restart its virtual machine in a maintenance window instead.
- the node is already shutting down or restarting;
- its service started less than a minute ago;
- a node swap is in progress.
A 503 means the restart is not available on that node.
Only an admin can restart a node, and each restart is recorded in the audit log.
Audit log
Section titled “Audit log”curl -sk "https://dtm.internal:8443/api/v1/audit?limit=100" \ -H "Authorization: Bearer $DTM_TOKEN"Optional filters: user_id, user_name, resource, resource_id, action,
plus from / to time bounds (RFC 3339 or YYYY-MM-DD). limit defaults
to 50. Readable by editor and admin. GET /api/v1/audit/export streams
the same data as NDJSON for archival; like the other export and backup GETs
it requires the X-DTM-CSRF: 1 header, so include it in any scheduled job:
curl -sk https://<dtm>:8443/api/v1/audit/export \ -H "Authorization: Bearer $DTM_TOKEN" \ -H "X-DTM-CSRF: 1"The stored audit log is bounded: entries beyond the configured retention are pruned oldest-first (see audit log retention). If you need audit evidence beyond that window, schedule the NDJSON export to immutable storage you control, for example a nightly job writing to an Azure Storage container with an immutability policy.
Entry shape
Section titled “Entry shape”Each entry’s before and after are the changed object, base64-encoded inside
the JSON. Probe secrets and other credentials are masked, as everywhere else in
the audit log. The same encoding is used in the support bundle and in the
AUDIT lines in the node’s system log.
A zone delete keeps a copy of its records
Section titled “A zone delete keeps a copy of its records”Added in v1.0.7. Deleting a zone removes all its records. The zone’s
delete entry carries a copy of them in a records array, with probe secrets
masked:
- The first 1,000 records, up to 4 MiB of them, are copied in full. Any after
that are listed by id in
omitted_record_ids. record_countis the number of records the zone held, andrecords_sha256is a SHA-256 fingerprint of all of them as DTM encoded them for the entry. Use it to check that two entries describe the same set; it cannot be recomputed from a zone export.
To keep every record of a larger zone in full, export the zone
(GET /api/v1/zones/{id}/export, see the API reference)
before you delete it.
Long entries in the system log
Section titled “Long entries in the system log”Changed in v1.0.7. An AUDIT line in the node’s system log that would be
longer than 32 KiB is written as numbered parts instead. Each part is an
AUDIT line with "stream":"dtm-audit-part", the entry’s id, its part
number, the number of parts and base64 data; the first part also carries
the total bytes and a sha256 of the whole line. Decode each part’s data
and join the parts in order to get back the ordinary "stream":"dtm-audit"
line. Shorter entries are written as before.
curl -sk https://dtm.internal:8443/api/v1/stats \ -H "Authorization: Bearer $DTM_TOKEN"# {"zones": 5, "records": 42, "nodes": 3, "users": 2}For the complete endpoint list, see the endpoint reference.