REST API overview and authentication
The DTM REST API is the programmatic surface behind everything: the web UI and the Terraform provider both use it. Anything you can do in the UI, you can do over the API.
- Base URL:
https://<dtm-node>:8443 - Auth: JWT bearer token on
Authorization: Bearer <token> - Content type:
application/jsonfor request and response bodies
Authentication
Section titled “Authentication”Start by logging in:
curl -sk -X POST https://dtm.internal:8443/api/v1/auth/login \ -H "Content-Type: application/json" \ -d '{"username": "admin", "password": "<your-password>"}'{ "user_id": "user-123", "username": "admin", "role": "admin", "refresh_token": "3f2c..."}The login response sets the JWT as an HttpOnly cookie (this is what browsers and the web UI use) and returns a refresh token in the body. Scripts and API clients exchange the refresh token for a bearer token:
curl -sk -X POST https://dtm.internal:8443/api/v1/auth/refresh \ -H "Content-Type: application/json" \ -d '{"refresh_token": "3f2c..."}'{ "token": "eyJ...", "refresh_token": "9a1b...", "user_id": "user-123", "username": "admin", "role": "admin"}Send the token on every subsequent request:
export DTM_TOKEN="eyJ..."curl -sk https://dtm.internal:8443/api/v1/zones \ -H "Authorization: Bearer $DTM_TOKEN"Service-account tokens (for automation)
Section titled “Service-account tokens (for automation)”Machines should not log in like people. A service account issues a long-lived token bound to one role, made for Terraform, CI, and scripts:
curl -sk -X POST https://dtm.internal:8443/api/v1/service-accounts \ -H "Authorization: Bearer $DTM_TOKEN" \ -H "X-DTM-CSRF: 1" \ -d '{"name": "terraform-ci", "role": "editor", "expires_in_days": 365}'- The token (
dtmsat_...) is returned once at creation and stored only as a hash; put it straight into your secret store. Use it exactly like a login token:Authorization: Bearer dtmsat_...(plusX-DTM-CSRF: 1on writes and on the sensitive GETs:/api/v1/backup,/api/v1/audit/export, the zone exports, and/api/v1/debug/tail). roleisadmin,editor, orreadonly;expires_in_daysis optional (0or omitted = no expiry, maximum 3650).- Zone scoping (optional
zone_idsarray): confine the token’s writes to the listed zones, fail-closed. Scope narrows the role, never widens it: a scopedadmintoken is still confined, and outside its zones every state-changing request answers403(including zone create, the cross-zone bulk import, and every non-zone surface such as forwarders, health checks, and TSIG keys). Reads are not zone-filtered. Blank entries are rejected; scope is preserved across rotation. This is what makes a per-team pipeline token genuinely least-privileged. - Revoke with
POST /api/v1/service-accounts/{id}/revoke; revocation and expiry are checked on every request, with no caching. List, get, delete, and a version-gated rotate (POST /api/v1/service-accounts/{id}/rotate) round out the admin-only management surface. - Managing DTM with Terraform? The
dtm_service_accountresource creates the account and mints its token through an ephemeral resource, so the secret goes to your secret store (for example Key Vault) and never lands in Terraform state. See provider setup.
Roles (RBAC)
Section titled “Roles (RBAC)”Every user has one of three roles. The API enforces them per endpoint.
| Role | Can do |
|---|---|
readonly |
List and read only. |
editor |
All DNS data-plane writes: zones, records, health checks, forwarders, stub zones, blocklist, subnet mappings, TSIG keys, and zone import. Plus reading the audit log. |
admin |
Everything: user management, cluster operations, backup and restore, and all runtime configuration. |
A request that exceeds the token’s role returns 403 Forbidden. See
users and access for creating users and assigning roles, and
Entra ID SSO for single sign-on.
Check whether SSO is configured
Section titled “Check whether SSO is configured”curl -sk https://dtm.internal:8443/api/v1/auth/entra/status# {"configured": true}The API is served over HTTPS. In production, DTM presents a certificate you
trust; point your clients at the real hostname. The -k flag in these examples
skips verification for convenience against a dev cluster with a self-signed
certificate. Do not skip verification in production.
Public endpoints
Section titled “Public endpoints”A few endpoints are intentionally unauthenticated because they are consumed by infrastructure that cannot carry a bearer token:
GET /healthz- liveness (always200if the process is up).GET /readyz- readiness (200only when the node is ready to serve).GET /metrics- Prometheus metrics. See observability.
Gate these at the network layer (NSG / firewall) to control who can reach them.
Where to go next
Section titled “Where to go next”- Zones and records: manage DNS over the API, with import and export.
- Health, forwarding and users: health checks, forwarders, the blocklist, and user management.
- Endpoint reference: the full endpoint list grouped by area.