Domain Management
Domain management is done through the /api/v1/domains/ endpoint. The
following sections describe how to create, list, modify, and delete domains
using JSON objects and how to export domain data in zonefile format.
All operations are subject to rate limiting. For details, see Rate Limits.
Domain Field Reference
A JSON object representing a domain has the following structure:
{
"created": "2018-09-18T16:36:16.510368Z",
"keys": [
{
"dnskey": "257 3 13 WFRl60...",
"ds": [
"6006 13 2 f34b75...",
"6006 13 4 2fdcf8..."
],
"flags": 257, # deprecated
"keytype": "csk", # deprecated
"managed": true
},
...
],
"minimum_ttl": 900,
"name": "example.com",
"published": "2018-09-18T17:21:38.348112Z",
"status": {
"checked": "2018-09-19T08:12:03.081274Z",
"nameserver_status": "correctly_delegated",
"nameservers": ["ns1.desec.io.", "ns2.desec.org."],
"secure_since": "2018-09-18T19:02:27.629012Z",
"security_status": "secure"
},
"touched": "2018-09-18T17:21:38.348112Z",
"zonefile": "import-me.example A 127.0.0.1 ..."
}
Field details:
created- Access mode:
read-only
Timestamp of domain creation, in ISO 8601 format (e.g.
2013-01-29T12:34:56.000000Z).keys- Access mode:
read-only
Array with DNSSEC public key information. Each entry contains
DNSKEYandDSrecord contents. For delegation of DNSSEC-secured domains, the parent domain should publish the combined list ofDSrecords. (This usually involves telling your registrar/registry about those records, and they will publish them for you.)Notes:
Keys are returned immediately after domain creation, and when retrieving a specific domain. In contrast, when listing all domains, the
keysfield is omitted for performance reasons.The
managedfield differentiates keys managed by deSEC (true) from any additional keys the user may have added (false, see DNSKEY caveat).DSvalues are calculated for each applicable key by applying hash algorithms 2 (SHA-256) and 4 (SHA-384), respectively. For keys not suitable for delegation (indicated by the first field containing an even number, such as256), thedsfield is[]. The selection of hash algorithms may change as best practices evolve.
minimum_ttl- Access mode:
read-only
Smallest TTL that can be used in an RRset. The value is set automatically by the server.
If you would like to use lower TTL values, you can apply for an exception by contacting support. We reserve the right to reject applications at our discretion.
name- Access mode:
read, write-once (upon domain creation)
Domain name. Restrictions on what is a valid domain name apply on a per-user basis. In general, a domain name consists of lowercase alphanumeric characters as well as hyphens
-and underscores_(except at the beginning of the name). The maximum length is 191.Internationalized domain names (IDN) currently are supported through their Punycode representation only (labels beginning with
xn--). Converters are available on the net, for example at https://www.punycoder.com/.published- Access mode:
read-only
Timestamp of when the domain’s DNS records have last been published, in ISO 8601 format (e.g.
2013-01-29T12:34:56.000000Z).As we publish record modifications immediately, this indicates the point in time of the last successful write request to a domain’s
rrsets/endpoint.
status- Access mode:
read-only
What we found when checking how the domain is delegated. We check every domain at least once a day, and you can ask for a re-check (see Checking a Domain’s Delegation). The object has the following fields:
checkedTimestamp of the most recent check, or
nullif the domain has not been checked yet.nameserver_statusTo which nameservers the parent zone delegates the domain:
correctly_delegated: to deSEC’s,multi_provider: to deSEC’s and others,other_provider: to other nameservers only,not_delegated: not at all,error: this could not be determined.
nullif the domain has not been checked yet.nameserversThe nameservers the parent zone delegates the domain to, as observed in the most recent check. Empty if the domain has not been checked yet, or is not delegated.
secure_sinceTimestamp since when the domain has been observed to be securely delegated to us (delegated to our nameservers, with DS records in the parent zone that let resolvers validate it), or
nullif it is not. Securely delegated domains raise your domain limit (seelimit_domainsandsecure_domainsin Retrieve Account Information).A check that could not be completed (
error) does not reset this value.security_statusWhether the delegation is secured with DNSSEC:
secure: yes,insecure: no, as the parent zone has no DS records for the domain (or is not signed itself),misconfigured: DNSSEC validation fails, so validating resolvers cannot resolve the domain. This is usually caused by outdated DS records,error: this could not be determined.
nullif the domain has not been checked yet, or if it is not delegated.
Domains under domains that we offer for registration ourselves (such as
dedyn.io) are delegated and secured by us automatically, and are therefore not checked. Theirsecure_sinceisnull, but they always count as securely delegated.touched- Access mode:
read-only
Timestamp of when the domain’s DNS records have last been touched. Equal to the maximum of the domain’s
publishedfield and all RRsettouchedvalues.This usually is the same as
published, unless there have been RRset write operations that did not trigger publication, such as rewriting an RRset with identical values.zonefile- Access mode:
write-only, no read
Optionally, includes a string in zonefile format with record data to be imported during domain creation.
Note that not everything given in the zonefile will be imported. Record types that are automatically managed by the deSEC API such as RRSIG, CDNSKEY, CDS, etc. will be silently ignored. Records with names that fall outside of the domain that is created will also be silently ignored.
Also, NS record at the apex and any DNSKEY records will be silently ignored; instead, NS records pointing to deSEC’s name servers and DNSKEY records for freshly generated keys will be created.
Record types that are not supported by the API will raise an error, as will records with invalid content. If an error occurs during the import of the zonefile, the domain will not be created.
Creating a Domain
To create a new domain, issue a POST request to the /api/v1/domains/
endpoint, like this:
curl https://desec.io/api/v1/domains/ \
--header "Authorization: Token {secret}" \
--header "Content-Type: application/json" --data @- <<< \
'{"name": "example.com"}'
This operation requires the perm_create_domain permission on the token.
Only the name field is mandatory.
Upon success, the response status code will be 201 Created, with the
domain object contained in the response body. If an improper request was
sent, 400 Bad Request is returned. This can happen when the request
payload was malformed, or when the requested domain name is unavailable
(because it conflicts with another user’s zone) or invalid (due to policy, see
below).
If you have reached the maximum number of domains for your account, the API
responds with 403 Forbidden. If you find yourself affected by this limit
although you have a legitimate use case, please contact our support.
Domains that we offer for registration ourselves, such as those directly under
dedyn.io, are limited to one per account. Attempting to register a second
one returns 400 Bad Request; delete the one you have if you would like a
different name.
Restrictions on what is a valid domain name apply. In particular, domains
listed on the Public Suffix List such as co.uk cannot be registered.
(If you operate a public suffix and would like to host it with deSEC, that’s
certainly possible; please contact support.) Also, domains ending with
.internal cannot be registered.
Under domains that we offer for registration ourselves, such as dedyn.io,
only direct children like example.dedyn.io can be registered. Deeper names
such as sub.example.dedyn.io return 400 Bad Request; register
example.dedyn.io and manage them as records within it.
Furthermore, we may impose other restrictions on a per-user basis if necessary to enforce our Terms of Use.
Listing Domains
The /api/v1/domains/ endpoint responds to GET requests with an array of
domain objects. For example, you may issue the following command:
curl https://desec.io/api/v1/domains/ \
--header "Authorization: Token {secret}"
to retrieve an overview of the domains you own. Domains are returned in reverse chronological order of their creation, and DNSSEC keys are omitted.
The response status code in case of success is 200 OK. This is true also
if you do not own any domains; in this case, the response body will be an empty
JSON array.
Up to 500 items are returned at a time. If you have a larger number of domains configured, the use of Pagination is required.
Retrieving a Specific Domain
To retrieve a domain with a specific name, issue a GET request with the
name appended to the domains/ endpoint, like this:
curl https://desec.io/api/v1/domains/{name}/ \
--header "Authorization: Token {secret}"
This will return only one domain (i.e., the response is not a JSON array).
If you own a domain with that name, the API responds with 200 OK and
returns the domain object in the response body. Otherwise, the return status
code is 404 Not Found.
Checking a Domain’s Delegation
The domain’s status field (see status) is also available on
its own, by issuing a GET request to the domain’s status/ endpoint:
curl https://desec.io/api/v1/domains/{name}/status/ \
--header "Authorization: Token {secret}"
The response body is the status object. Unlike retrieving the domain, this is cheap enough to repeat while waiting for a check to finish (see below).
After changing your domain’s delegation or its DNSSEC setup (e.g. after giving
the DS records to your registrar), you can ask for a re-check by issuing a
POST request to the same endpoint:
curl -X POST https://desec.io/api/v1/domains/{name}/status/ \
--header "Authorization: Token {secret}"
If a check is needed, the API responds with 202 Accepted, and the domain
will be checked within a few seconds. The response body is the current status
object, with an additional requested field holding the server’s time of
the request. Once the check is done, the status object’s checked field
is at least that value. This includes checks that could not be completed:
their statuses are error.
If no check is needed, the API responds with 200 OK and the current status
object. This is the case when the domain was checked during the last minute,
and for domains under domains that we offer for registration ourselves (such
as dedyn.io), which are securely delegated by construction.
Re-checks are meant for interactive use, such as confirming a change you just
made, and thus require a login token (see Log In); the web interface
offers them next to each domain. For automation, please read the status
(GET) instead, which works with any token: our daily checks keep it up to
date. We appreciate feedback about use cases where this isn’t ideal.
Re-checks are subject to rate limiting (see Rate Limits). Every
POST request counts, including those answered with 200 OK. If our
checking service is temporarily unavailable, the API responds with
503 Service Unavailable.
Identifying the Responsible Domain for a DNS Name
If you have several domains which share a DNS suffix (i.e. one domain is a parent of the other), it is sometimes necessary to find out which domain is responsible for a given DNS name. (In DNS terminology, the responsible domain is also called the “authoritative zone”.)
The responsible domain for a given DNS query name (qname) can be retrieved
by applying a filter on the endpoint used for Listing Domains, like so:
curl https://desec.io/api/v1/domains/?owns_qname={qname} \
--header "Authorization: Token {secret}"
If your account has a domain that is responsible for the name qname, the
API returns a JSON array containing only that domain object in the response
body. Otherwise, the JSON array will be empty.
One use case of this is when requesting TLS certificates using the DNS
challenge mechanism, which requires placing a TXT record at a certain name
within the responsible domain.
Example
Let’s say you have the domains example.net, dev.example.net and
git.dev.example.net, and you would like to request a certificate for the
TLS server name www.dev.example.net. In this case, the TXT record
needs to be created with the name _acme-challenge.www.dev.example.net.
This DNS name belongs to the dev.example.net domain, and the record needs
to be created under that domain using the subname value
_acme-challenge.www (see Creating an RRset).
If dev.example.net was not configured as a domain in its own right, the
responsible domain would instead be the parent domain example.net. In
this case, the record would have to be configured there, with a subname
value of _acme-challenge.www.dev.
Finally, when requesting a certificate for git.dev.example.net, the
responsible domain for the corresponding DNS record is the one with this name,
and subname would just be _acme-challenge.
The above API request helps you answer this kind of question.
Exporting a Domain as Zonefile
To export domain data in zonefile format, send a GET request to the
zonefile endpoint of this domain, i.e. to /domains/{name}/zonefile/:
curl https://desec.io/api/v1/domains/{name}/zonefile/ \
--header "Authorization: Token {secret}"
Note that this will return a plain-text zonefile format without JSON formatting that includes all domain data except for DNSSEC-specific record types, e.g.:
; Zonefile for example.com exported from desec.io at 2022-08-26 16:03:18.258961+00:00
example.com. 1234 IN NS ns1.example.com.
example.com. 1234 IN NS ns2.example.com.
example.com. 300 IN SOA get.desec.io. get.desec.io. 2022082602 86400 3600 2419200 3600
Deleting a Domain
To delete a domain, send a DELETE request to the endpoint representing the
domain. This operation requires the perm_delete_domain permission on the
token, and no conflicting token scoping policies.
Upon success or if the domain did not exist in your account, the response
status code is 204 No Content.