DNSSEC of the account’s domains, with the same fields and answers whatever the domain’s extension. The state tells you what to send, so no trial and error is needed:
- Read the state:
GET /client/domains/{domain}/dnssecsays whether DNSSEC issupported, therecord_typethe domain takes, theoperationsavailable right now and thealgorithms/digest_typesit accepts. - Turn it on: if
enableis inoperations, the zone is signed for you (typically a domain using our DNS service): callPOST …/dnssec/enable, no record needed. Otherwise add your records withPOST …/dnssec/records, in the formrecord_typenames:ds(key_tag,algorithm,digest_type,digest) ordnskey(flags,protocol,algorithm,public_key), using the values your DNS provider gives you. - Check the result: every call answers with the refreshed state.
pending: truemeans the change was accepted but is not applied yet: read the state again until it isfalse.
DELETE …/dnssec/records removes one record, DELETE …/dnssec removes them all (DNSSEC off). Success bodies are {"data": …}; errors use the standard error envelope (ApiError, see Errors).
Get the DNSSEC state of a domain #
GET
/client/domains/{domain}/dnssec
Start here: the state says what the domain accepts, so the other calls
need no guessing. supported: false (never an error) means DNSSEC
cannot be managed for this domain. Otherwise record_type names the
record form it takes, operations the calls available right now,
algorithms and digest_types the values it accepts, and active
whether DNSSEC is on. Read live on every call.
DNSSEC can be changed only while the domain is active. For any other
status operations is empty and blocked_reason says why; the records
are still read while the registry holds the domain (grace, redemption,
transferring away), and are null when it does not (not registered
yet, or no longer ours).
- Authentication: bearer Token
- Rate limit: 30 req/min per user
Parameters
Path
-
domaininteger requiredThe domain ID
Responses
-
200The domain’s DNSSEC state.
Response body
application/json-
dataobject10 properties
-
supportedbooleantruewhen DNSSEC can be managed for this domain through this API.falseis not an error: DNSSEC is not offered for this domain here, the other fields are then empty and every other DNSSEC call answersdnssec_not_supported. -
record_typestring | nullThe record form this domain takes;nullwhen notsupported.ds: the hash of your key, as your DNS provider shows it (key_tag,algorithm,digest_type,digest).dnskey: the key itself (flags,protocol,algorithm,public_key). Send records in this form only: the other one is refused withinvalid_request.Allowed valuesdsdnskey -
operationsarray of stringThe calls available on this domain right now.add:POST …/dnssec/records.remove:DELETE …/dnssec/records.disable:DELETE …/dnssec(removes every record: DNSSEC off).enable:POST …/dnssec/enable, listed only where the zone is signed for you (typically a domain using our DNS service), which then takes no record. Empty when notsupported, when the domain is notactive(seeblocked_reason), and it can be empty while a change is still being applied (pending: true).Allowed valuesaddremovedisableenable -
algorithmsarray of integerThe algorithm numbers (IANA) this domain accepts inalgorithm, as plain integers:5RSA/SHA-1,7RSASHA1-NSEC3-SHA1,8RSA/SHA-256,10RSA/SHA-512,13ECDSA P-256/SHA-256,14ECDSA P-384/SHA-384,15Ed25519,16Ed448. Often a subset of these. Empty when notsupported.Allowed values5781013141516 -
digest_typesarray of integerdsdomains only (absent fordnskey): the digest type numbers accepted indigest_type, as plain integers:1SHA-1,2SHA-256,4SHA-384.Allowed values124 -
recordsarray of object | nullThe DNSSEC records on file for the domain, each with the fields of the domain’srecord_typeonly. Empty when there is none, and on a zone signed for you, which lists no record (seeactive).nullwhen a change was accepted but the records could not be read back right after it (read the state again), and when the domain is not held at the registry: a domain that is not registered yet, or no longer ours (blocked_reasonis then set). A domain in grace, redemption or transferring away is still read.7 properties
-
key_tagintegerdsonly: the key tag, 0-65535. -
flagsintegerdnskeyonly:257(KSK, the usual one) or256(ZSK). -
protocolintegerdnskeyonly: always3. -
algorithmintegerBoth forms: the DNSSEC algorithm number (IANA), one of the domain’salgorithms. -
digest_typeintegerdsonly: the digest type, one of the domain’sdigest_types. -
digeststringdsonly: the digest, hexadecimal, upper case. -
public_keystringdnskeyonly: the public key, Base64, without whitespace.
-
-
activeboolean | nullWhether DNSSEC is on for the domain. Usually the same asrecordsnot being empty; it also covers a zone signed for you (which lists no record) and DS records set outside this API.nullwhen notsupported, or whenrecordsisnull. -
pendingbooleantruewhen a change was accepted but is not applied yet:recordsandactivestill show the situation before it. PollGET …/dnssecuntil it isfalse; no need to send the change again. -
pending_messagestring | nullA short customer-readable note about the pending change, when there is one; otherwisenull. -
blocked_reasonobject | nullWhy no change can be made right now, ornullwhen changes are possible. Set when the domain’s status is notactive: DNSSEC is changed only on an active domain, like the nameservers and the contacts.operationsis then empty and every change answers403 domain_not_active.2 properties
-
codestringThe code a change would be refused with.Allowed valuesdomain_not_active -
messagestringThe reason, readable by a customer.
-
-
-
cURL
curl 'https://portal.supporthost.com/api/v1/client/domains/{domain}/dnssec' \
-H "Authorization: Bearer $API_TOKEN" \
-H 'Accept: application/json'
PHP
<?php
$ch = curl_init('https://portal.supporthost.com/api/v1/client/domains/{domain}/dnssec');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('API_TOKEN'),
'Accept: application/json',
],
]);
$body = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($status >= 400) {
// Error envelope: {"error": {"code": "...", "message": "...", "fields": {...}}}
echo $status . ' ' . ($body['error']['code'] ?? '') . ': ' . ($body['error']['message'] ?? '') . "\n";
} else {
print_r($body);
}
Node.js
// Save as a .mjs file (ES module, Node 18+): it uses top-level await.
const response = await fetch('https://portal.supporthost.com/api/v1/client/domains/{domain}/dnssec', {
headers: {
Authorization: `Bearer ${process.env.API_TOKEN}`,
Accept: 'application/json',
},
});
console.log(await response.json());
200
{
"data": {
"supported": true,
"record_type": "ds",
"operations": [
"add",
"remove",
"disable"
],
"algorithms": [
8,
13,
15
],
"digest_types": [
2,
4
],
"records": [
{
"key_tag": 12345,
"flags": 257,
"protocol": 3,
"algorithm": 13,
"digest_type": 2,
"digest": "E2D3C916F6DEEAC73294E8268FB5885044A833FC5459588F4A9184CFC41A5766",
"public_key": "mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ=="
}
],
"active": true,
"pending": false,
"pending_message": null,
"blocked_reason": null
}
}
Error responses share one format: see Errors.
Disable DNSSEC #
DELETE
/client/domains/{domain}/dnssec
Offered when disable is in operations: removes every DNSSEC record
of the domain, or stops the signing of a zone signed for you. Answers
with the refreshed state.
- Authentication: bearer Token
- Rate limit: 20 req/min per user
Parameters
Path
-
domaininteger requiredThe domain ID
Responses
-
200The domain’s DNSSEC state after the change.
Response body
application/json-
dataobject10 properties
-
supportedbooleantruewhen DNSSEC can be managed for this domain through this API.falseis not an error: DNSSEC is not offered for this domain here, the other fields are then empty and every other DNSSEC call answersdnssec_not_supported. -
record_typestring | nullThe record form this domain takes;nullwhen notsupported.ds: the hash of your key, as your DNS provider shows it (key_tag,algorithm,digest_type,digest).dnskey: the key itself (flags,protocol,algorithm,public_key). Send records in this form only: the other one is refused withinvalid_request.Allowed valuesdsdnskey -
operationsarray of stringThe calls available on this domain right now.add:POST …/dnssec/records.remove:DELETE …/dnssec/records.disable:DELETE …/dnssec(removes every record: DNSSEC off).enable:POST …/dnssec/enable, listed only where the zone is signed for you (typically a domain using our DNS service), which then takes no record. Empty when notsupported, when the domain is notactive(seeblocked_reason), and it can be empty while a change is still being applied (pending: true).Allowed valuesaddremovedisableenable -
algorithmsarray of integerThe algorithm numbers (IANA) this domain accepts inalgorithm, as plain integers:5RSA/SHA-1,7RSASHA1-NSEC3-SHA1,8RSA/SHA-256,10RSA/SHA-512,13ECDSA P-256/SHA-256,14ECDSA P-384/SHA-384,15Ed25519,16Ed448. Often a subset of these. Empty when notsupported.Allowed values5781013141516 -
digest_typesarray of integerdsdomains only (absent fordnskey): the digest type numbers accepted indigest_type, as plain integers:1SHA-1,2SHA-256,4SHA-384.Allowed values124 -
recordsarray of object | nullThe DNSSEC records on file for the domain, each with the fields of the domain’srecord_typeonly. Empty when there is none, and on a zone signed for you, which lists no record (seeactive).nullwhen a change was accepted but the records could not be read back right after it (read the state again), and when the domain is not held at the registry: a domain that is not registered yet, or no longer ours (blocked_reasonis then set). A domain in grace, redemption or transferring away is still read.7 properties
-
key_tagintegerdsonly: the key tag, 0-65535. -
flagsintegerdnskeyonly:257(KSK, the usual one) or256(ZSK). -
protocolintegerdnskeyonly: always3. -
algorithmintegerBoth forms: the DNSSEC algorithm number (IANA), one of the domain’salgorithms. -
digest_typeintegerdsonly: the digest type, one of the domain’sdigest_types. -
digeststringdsonly: the digest, hexadecimal, upper case. -
public_keystringdnskeyonly: the public key, Base64, without whitespace.
-
-
activeboolean | nullWhether DNSSEC is on for the domain. Usually the same asrecordsnot being empty; it also covers a zone signed for you (which lists no record) and DS records set outside this API.nullwhen notsupported, or whenrecordsisnull. -
pendingbooleantruewhen a change was accepted but is not applied yet:recordsandactivestill show the situation before it. PollGET …/dnssecuntil it isfalse; no need to send the change again. -
pending_messagestring | nullA short customer-readable note about the pending change, when there is one; otherwisenull. -
blocked_reasonobject | nullWhy no change can be made right now, ornullwhen changes are possible. Set when the domain’s status is notactive: DNSSEC is changed only on an active domain, like the nameservers and the contacts.operationsis then empty and every change answers403 domain_not_active.2 properties
-
codestringThe code a change would be refused with.Allowed valuesdomain_not_active -
messagestringThe reason, readable by a customer.
-
-
-
-
401unauthenticatedApiError -
403client_token_requiredtoken_not_api_enabledtoken_not_client_scopedclient_access_revokedclient_cancelledip_not_allowedip_whitelist_misconfiguredforbiddendomain_not_activeApiError -
404client_not_foundnot_foundApiError -
409dnssec_conflictApiError -
422dnssec_not_supporteddnssec_refusedApiError -
429rate_limitedApiError -
502upstream_errorApiError
cURL
curl -X DELETE 'https://portal.supporthost.com/api/v1/client/domains/{domain}/dnssec' \
-H "Authorization: Bearer $API_TOKEN" \
-H 'Accept: application/json'
PHP
<?php
$ch = curl_init('https://portal.supporthost.com/api/v1/client/domains/{domain}/dnssec');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('API_TOKEN'),
'Accept: application/json',
],
]);
$body = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($status >= 400) {
// Error envelope: {"error": {"code": "...", "message": "...", "fields": {...}}}
echo $status . ' ' . ($body['error']['code'] ?? '') . ': ' . ($body['error']['message'] ?? '') . "\n";
} else {
print_r($body);
}
Node.js
const response = await fetch('https://portal.supporthost.com/api/v1/client/domains/{domain}/dnssec', {
method: 'DELETE',
headers: {
Authorization: `Bearer ${process.env.API_TOKEN}`,
Accept: 'application/json',
},
});
console.log(await response.json());
200
{
"data": {
"supported": true,
"record_type": "ds",
"operations": [
"add",
"remove",
"disable"
],
"algorithms": [
8,
13,
15
],
"digest_types": [
2,
4
],
"records": [
{
"key_tag": 12345,
"flags": 257,
"protocol": 3,
"algorithm": 13,
"digest_type": 2,
"digest": "E2D3C916F6DEEAC73294E8268FB5885044A833FC5459588F4A9184CFC41A5766",
"public_key": "mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ=="
}
],
"active": true,
"pending": false,
"pending_message": null,
"blocked_reason": null
}
}
Error responses share one format: see Errors.
Add a DNSSEC record #
POST
/client/domains/{domain}/dnssec/records
Offered when add is in operations. Send the fields of the domain’s
record_type, with the values your DNS provider gives you. For ds:
{"key_tag": 12345, "algorithm": 13, "digest_type": 2, "digest": "E2D3C916F6DEEAC73294E8268FB5885044A833FC5459588F4A9184CFC41A5766"}
For dnskey:
{"flags": 257, "protocol": 3, "algorithm": 13, "public_key": "mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ=="}
Answers with the refreshed state; pending: true means the change was
accepted but is not applied yet — read the state again until it is
false.
- Authentication: bearer Token
- Rate limit: 20 req/min per user
Parameters
Path
-
domaininteger requiredThe domain ID
Body application/json
required
-
key_tagintegerdsonly: the key tag, 0-65535.-
Minimum
0 -
Maximum
65535
-
Minimum
-
algorithminteger requiredBoth forms: the DNSSEC algorithm number (IANA), one of the domain’salgorithms. -
digest_typeintegerdsonly: the digest type, one of the domain’sdigest_types. -
digeststringdsonly: the digest, hexadecimal (case is ignored).-
Pattern
^[A-Fa-f0-9]+$ -
Max length
128
-
Pattern
-
public_keystringdnskeyonly: the public key, Base64. Whitespace is ignored.-
Max length
4096
-
Max length
-
flagsintegerdnskeyonly:257(KSK, the usual one) or256(ZSK).Allowed values256257 -
protocolintegerdnskeyonly: always3.Allowed values3
Responses
-
201The domain’s DNSSEC state after the change.
Response body
application/json-
dataobject10 properties
-
supportedbooleantruewhen DNSSEC can be managed for this domain through this API.falseis not an error: DNSSEC is not offered for this domain here, the other fields are then empty and every other DNSSEC call answersdnssec_not_supported. -
record_typestring | nullThe record form this domain takes;nullwhen notsupported.ds: the hash of your key, as your DNS provider shows it (key_tag,algorithm,digest_type,digest).dnskey: the key itself (flags,protocol,algorithm,public_key). Send records in this form only: the other one is refused withinvalid_request.Allowed valuesdsdnskey -
operationsarray of stringThe calls available on this domain right now.add:POST …/dnssec/records.remove:DELETE …/dnssec/records.disable:DELETE …/dnssec(removes every record: DNSSEC off).enable:POST …/dnssec/enable, listed only where the zone is signed for you (typically a domain using our DNS service), which then takes no record. Empty when notsupported, when the domain is notactive(seeblocked_reason), and it can be empty while a change is still being applied (pending: true).Allowed valuesaddremovedisableenable -
algorithmsarray of integerThe algorithm numbers (IANA) this domain accepts inalgorithm, as plain integers:5RSA/SHA-1,7RSASHA1-NSEC3-SHA1,8RSA/SHA-256,10RSA/SHA-512,13ECDSA P-256/SHA-256,14ECDSA P-384/SHA-384,15Ed25519,16Ed448. Often a subset of these. Empty when notsupported.Allowed values5781013141516 -
digest_typesarray of integerdsdomains only (absent fordnskey): the digest type numbers accepted indigest_type, as plain integers:1SHA-1,2SHA-256,4SHA-384.Allowed values124 -
recordsarray of object | nullThe DNSSEC records on file for the domain, each with the fields of the domain’srecord_typeonly. Empty when there is none, and on a zone signed for you, which lists no record (seeactive).nullwhen a change was accepted but the records could not be read back right after it (read the state again), and when the domain is not held at the registry: a domain that is not registered yet, or no longer ours (blocked_reasonis then set). A domain in grace, redemption or transferring away is still read.7 properties
-
key_tagintegerdsonly: the key tag, 0-65535. -
flagsintegerdnskeyonly:257(KSK, the usual one) or256(ZSK). -
protocolintegerdnskeyonly: always3. -
algorithmintegerBoth forms: the DNSSEC algorithm number (IANA), one of the domain’salgorithms. -
digest_typeintegerdsonly: the digest type, one of the domain’sdigest_types. -
digeststringdsonly: the digest, hexadecimal, upper case. -
public_keystringdnskeyonly: the public key, Base64, without whitespace.
-
-
activeboolean | nullWhether DNSSEC is on for the domain. Usually the same asrecordsnot being empty; it also covers a zone signed for you (which lists no record) and DS records set outside this API.nullwhen notsupported, or whenrecordsisnull. -
pendingbooleantruewhen a change was accepted but is not applied yet:recordsandactivestill show the situation before it. PollGET …/dnssecuntil it isfalse; no need to send the change again. -
pending_messagestring | nullA short customer-readable note about the pending change, when there is one; otherwisenull. -
blocked_reasonobject | nullWhy no change can be made right now, ornullwhen changes are possible. Set when the domain’s status is notactive: DNSSEC is changed only on an active domain, like the nameservers and the contacts.operationsis then empty and every change answers403 domain_not_active.2 properties
-
codestringThe code a change would be refused with.Allowed valuesdomain_not_active -
messagestringThe reason, readable by a customer.
-
-
-
-
401unauthenticatedApiError -
403client_token_requiredtoken_not_api_enabledtoken_not_client_scopedclient_access_revokedclient_cancelledip_not_allowedip_whitelist_misconfiguredforbiddendomain_not_activeApiError -
404client_not_foundnot_foundApiError -
409dnssec_duplicate_recorddnssec_conflictApiError -
422dnssec_not_supporteddnssec_invalid_recorddnssec_limit_reacheddnssec_refusedinvalid_requestunprocessableApiError -
429rate_limitedApiError -
502upstream_errorApiError
cURL
curl -X POST 'https://portal.supporthost.com/api/v1/client/domains/{domain}/dnssec/records' \
-H "Authorization: Bearer $API_TOKEN" \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"key_tag": 12345,
"algorithm": 13,
"digest_type": 2,
"digest": "E2D3C916F6DEEAC73294E8268FB5885044A833FC5459588F4A9184CFC41A5766"
}'
PHP
<?php
$ch = curl_init('https://portal.supporthost.com/api/v1/client/domains/{domain}/dnssec/records');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('API_TOKEN'),
'Accept: application/json',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'key_tag' => 12345,
'algorithm' => 13,
'digest_type' => 2,
'digest' => 'E2D3C916F6DEEAC73294E8268FB5885044A833FC5459588F4A9184CFC41A5766',
]),
]);
$body = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($status >= 400) {
// Error envelope: {"error": {"code": "...", "message": "...", "fields": {...}}}
echo $status . ' ' . ($body['error']['code'] ?? '') . ': ' . ($body['error']['message'] ?? '') . "\n";
} else {
print_r($body);
}
Node.js
const response = await fetch('https://portal.supporthost.com/api/v1/client/domains/{domain}/dnssec/records', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.API_TOKEN}`,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"key_tag": 12345,
"algorithm": 13,
"digest_type": 2,
"digest": "E2D3C916F6DEEAC73294E8268FB5885044A833FC5459588F4A9184CFC41A5766"
}),
});
console.log(await response.json());
201
{
"data": {
"supported": true,
"record_type": "ds",
"operations": [
"add",
"remove",
"disable"
],
"algorithms": [
8,
13,
15
],
"digest_types": [
2,
4
],
"records": [
{
"key_tag": 12345,
"flags": 257,
"protocol": 3,
"algorithm": 13,
"digest_type": 2,
"digest": "E2D3C916F6DEEAC73294E8268FB5885044A833FC5459588F4A9184CFC41A5766",
"public_key": "mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ=="
}
],
"active": true,
"pending": false,
"pending_message": null,
"blocked_reason": null
}
}
Error responses share one format: see Errors.
Remove a DNSSEC record #
DELETE
/client/domains/{domain}/dnssec/records
Offered when remove is in operations. Name the record as it appears
in records: all four fields for ds
({"key_tag": 12345, "algorithm": 13, "digest_type": 2, "digest": "E2D3C916F6DEEAC73294E8268FB5885044A833FC5459588F4A9184CFC41A5766"}),
the public_key alone for dnskey
({"public_key": "mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ=="}).
Answers with the refreshed state.
- Authentication: bearer Token
- Rate limit: 20 req/min per user
Parameters
Path
-
domaininteger requiredThe domain ID
Query
-
key_taginteger-
Minimum
0 -
Maximum
65535
-
Minimum
-
algorithminteger -
digest_typeinteger -
digeststring-
Pattern
^[A-Fa-f0-9]+$ -
Max length
128
-
Pattern
-
public_keystring-
Max length
4096
-
Max length
Responses
-
200The domain’s DNSSEC state after the change.
Response body
application/json-
dataobject10 properties
-
supportedbooleantruewhen DNSSEC can be managed for this domain through this API.falseis not an error: DNSSEC is not offered for this domain here, the other fields are then empty and every other DNSSEC call answersdnssec_not_supported. -
record_typestring | nullThe record form this domain takes;nullwhen notsupported.ds: the hash of your key, as your DNS provider shows it (key_tag,algorithm,digest_type,digest).dnskey: the key itself (flags,protocol,algorithm,public_key). Send records in this form only: the other one is refused withinvalid_request.Allowed valuesdsdnskey -
operationsarray of stringThe calls available on this domain right now.add:POST …/dnssec/records.remove:DELETE …/dnssec/records.disable:DELETE …/dnssec(removes every record: DNSSEC off).enable:POST …/dnssec/enable, listed only where the zone is signed for you (typically a domain using our DNS service), which then takes no record. Empty when notsupported, when the domain is notactive(seeblocked_reason), and it can be empty while a change is still being applied (pending: true).Allowed valuesaddremovedisableenable -
algorithmsarray of integerThe algorithm numbers (IANA) this domain accepts inalgorithm, as plain integers:5RSA/SHA-1,7RSASHA1-NSEC3-SHA1,8RSA/SHA-256,10RSA/SHA-512,13ECDSA P-256/SHA-256,14ECDSA P-384/SHA-384,15Ed25519,16Ed448. Often a subset of these. Empty when notsupported.Allowed values5781013141516 -
digest_typesarray of integerdsdomains only (absent fordnskey): the digest type numbers accepted indigest_type, as plain integers:1SHA-1,2SHA-256,4SHA-384.Allowed values124 -
recordsarray of object | nullThe DNSSEC records on file for the domain, each with the fields of the domain’srecord_typeonly. Empty when there is none, and on a zone signed for you, which lists no record (seeactive).nullwhen a change was accepted but the records could not be read back right after it (read the state again), and when the domain is not held at the registry: a domain that is not registered yet, or no longer ours (blocked_reasonis then set). A domain in grace, redemption or transferring away is still read.7 properties
-
key_tagintegerdsonly: the key tag, 0-65535. -
flagsintegerdnskeyonly:257(KSK, the usual one) or256(ZSK). -
protocolintegerdnskeyonly: always3. -
algorithmintegerBoth forms: the DNSSEC algorithm number (IANA), one of the domain’salgorithms. -
digest_typeintegerdsonly: the digest type, one of the domain’sdigest_types. -
digeststringdsonly: the digest, hexadecimal, upper case. -
public_keystringdnskeyonly: the public key, Base64, without whitespace.
-
-
activeboolean | nullWhether DNSSEC is on for the domain. Usually the same asrecordsnot being empty; it also covers a zone signed for you (which lists no record) and DS records set outside this API.nullwhen notsupported, or whenrecordsisnull. -
pendingbooleantruewhen a change was accepted but is not applied yet:recordsandactivestill show the situation before it. PollGET …/dnssecuntil it isfalse; no need to send the change again. -
pending_messagestring | nullA short customer-readable note about the pending change, when there is one; otherwisenull. -
blocked_reasonobject | nullWhy no change can be made right now, ornullwhen changes are possible. Set when the domain’s status is notactive: DNSSEC is changed only on an active domain, like the nameservers and the contacts.operationsis then empty and every change answers403 domain_not_active.2 properties
-
codestringThe code a change would be refused with.Allowed valuesdomain_not_active -
messagestringThe reason, readable by a customer.
-
-
-
-
401unauthenticatedApiError -
403client_token_requiredtoken_not_api_enabledtoken_not_client_scopedclient_access_revokedclient_cancelledip_not_allowedip_whitelist_misconfiguredforbiddendomain_not_activeApiError -
404client_not_foundnot_foundApiError -
409dnssec_conflictApiError -
422dnssec_not_supporteddnssec_operation_not_supporteddnssec_record_not_founddnssec_refusedinvalid_requestunprocessableApiError -
429rate_limitedApiError -
502upstream_errorApiError
cURL
curl -X DELETE 'https://portal.supporthost.com/api/v1/client/domains/{domain}/dnssec/records' \
-H "Authorization: Bearer $API_TOKEN" \
-H 'Accept: application/json'
PHP
<?php
$ch = curl_init('https://portal.supporthost.com/api/v1/client/domains/{domain}/dnssec/records');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('API_TOKEN'),
'Accept: application/json',
],
]);
$body = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($status >= 400) {
// Error envelope: {"error": {"code": "...", "message": "...", "fields": {...}}}
echo $status . ' ' . ($body['error']['code'] ?? '') . ': ' . ($body['error']['message'] ?? '') . "\n";
} else {
print_r($body);
}
Node.js
const response = await fetch('https://portal.supporthost.com/api/v1/client/domains/{domain}/dnssec/records', {
method: 'DELETE',
headers: {
Authorization: `Bearer ${process.env.API_TOKEN}`,
Accept: 'application/json',
},
});
console.log(await response.json());
200
{
"data": {
"supported": true,
"record_type": "ds",
"operations": [
"add",
"remove",
"disable"
],
"algorithms": [
8,
13,
15
],
"digest_types": [
2,
4
],
"records": [
{
"key_tag": 12345,
"flags": 257,
"protocol": 3,
"algorithm": 13,
"digest_type": 2,
"digest": "E2D3C916F6DEEAC73294E8268FB5885044A833FC5459588F4A9184CFC41A5766",
"public_key": "mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ=="
}
],
"active": true,
"pending": false,
"pending_message": null,
"blocked_reason": null
}
}
Error responses share one format: see Errors.
Switch DNSSEC on #
POST
/client/domains/{domain}/dnssec/enable
For a domain whose zone is signed for you (typically one using our DNS
service): enable is then in operations, and no record is needed.
On any other domain DNSSEC is turned on by adding records, and this
call answers dnssec_operation_not_supported. Answers with the
refreshed state.
- Authentication: bearer Token
- Rate limit: 20 req/min per user
Parameters
Path
-
domaininteger requiredThe domain ID
Responses
-
200The domain’s DNSSEC state after the change.
Response body
application/json-
dataobject10 properties
-
supportedbooleantruewhen DNSSEC can be managed for this domain through this API.falseis not an error: DNSSEC is not offered for this domain here, the other fields are then empty and every other DNSSEC call answersdnssec_not_supported. -
record_typestring | nullThe record form this domain takes;nullwhen notsupported.ds: the hash of your key, as your DNS provider shows it (key_tag,algorithm,digest_type,digest).dnskey: the key itself (flags,protocol,algorithm,public_key). Send records in this form only: the other one is refused withinvalid_request.Allowed valuesdsdnskey -
operationsarray of stringThe calls available on this domain right now.add:POST …/dnssec/records.remove:DELETE …/dnssec/records.disable:DELETE …/dnssec(removes every record: DNSSEC off).enable:POST …/dnssec/enable, listed only where the zone is signed for you (typically a domain using our DNS service), which then takes no record. Empty when notsupported, when the domain is notactive(seeblocked_reason), and it can be empty while a change is still being applied (pending: true).Allowed valuesaddremovedisableenable -
algorithmsarray of integerThe algorithm numbers (IANA) this domain accepts inalgorithm, as plain integers:5RSA/SHA-1,7RSASHA1-NSEC3-SHA1,8RSA/SHA-256,10RSA/SHA-512,13ECDSA P-256/SHA-256,14ECDSA P-384/SHA-384,15Ed25519,16Ed448. Often a subset of these. Empty when notsupported.Allowed values5781013141516 -
digest_typesarray of integerdsdomains only (absent fordnskey): the digest type numbers accepted indigest_type, as plain integers:1SHA-1,2SHA-256,4SHA-384.Allowed values124 -
recordsarray of object | nullThe DNSSEC records on file for the domain, each with the fields of the domain’srecord_typeonly. Empty when there is none, and on a zone signed for you, which lists no record (seeactive).nullwhen a change was accepted but the records could not be read back right after it (read the state again), and when the domain is not held at the registry: a domain that is not registered yet, or no longer ours (blocked_reasonis then set). A domain in grace, redemption or transferring away is still read.7 properties
-
key_tagintegerdsonly: the key tag, 0-65535. -
flagsintegerdnskeyonly:257(KSK, the usual one) or256(ZSK). -
protocolintegerdnskeyonly: always3. -
algorithmintegerBoth forms: the DNSSEC algorithm number (IANA), one of the domain’salgorithms. -
digest_typeintegerdsonly: the digest type, one of the domain’sdigest_types. -
digeststringdsonly: the digest, hexadecimal, upper case. -
public_keystringdnskeyonly: the public key, Base64, without whitespace.
-
-
activeboolean | nullWhether DNSSEC is on for the domain. Usually the same asrecordsnot being empty; it also covers a zone signed for you (which lists no record) and DS records set outside this API.nullwhen notsupported, or whenrecordsisnull. -
pendingbooleantruewhen a change was accepted but is not applied yet:recordsandactivestill show the situation before it. PollGET …/dnssecuntil it isfalse; no need to send the change again. -
pending_messagestring | nullA short customer-readable note about the pending change, when there is one; otherwisenull. -
blocked_reasonobject | nullWhy no change can be made right now, ornullwhen changes are possible. Set when the domain’s status is notactive: DNSSEC is changed only on an active domain, like the nameservers and the contacts.operationsis then empty and every change answers403 domain_not_active.2 properties
-
codestringThe code a change would be refused with.Allowed valuesdomain_not_active -
messagestringThe reason, readable by a customer.
-
-
-
-
401unauthenticatedApiError -
403client_token_requiredtoken_not_api_enabledtoken_not_client_scopedclient_access_revokedclient_cancelledip_not_allowedip_whitelist_misconfiguredforbiddendomain_not_activeApiError -
404client_not_foundnot_foundApiError -
409dnssec_conflictApiError -
422dnssec_not_supporteddnssec_operation_not_supporteddnssec_refusedApiError -
429rate_limitedApiError -
502upstream_errorApiError
cURL
curl -X POST 'https://portal.supporthost.com/api/v1/client/domains/{domain}/dnssec/enable' \
-H "Authorization: Bearer $API_TOKEN" \
-H 'Accept: application/json'
PHP
<?php
$ch = curl_init('https://portal.supporthost.com/api/v1/client/domains/{domain}/dnssec/enable');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('API_TOKEN'),
'Accept: application/json',
],
]);
$body = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($status >= 400) {
// Error envelope: {"error": {"code": "...", "message": "...", "fields": {...}}}
echo $status . ' ' . ($body['error']['code'] ?? '') . ': ' . ($body['error']['message'] ?? '') . "\n";
} else {
print_r($body);
}
Node.js
const response = await fetch('https://portal.supporthost.com/api/v1/client/domains/{domain}/dnssec/enable', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.API_TOKEN}`,
Accept: 'application/json',
},
});
console.log(await response.json());
200
{
"data": {
"supported": true,
"record_type": "ds",
"operations": [
"add",
"remove",
"disable"
],
"algorithms": [
8,
13,
15
],
"digest_types": [
2,
4
],
"records": [
{
"key_tag": 12345,
"flags": 257,
"protocol": 3,
"algorithm": 13,
"digest_type": 2,
"digest": "E2D3C916F6DEEAC73294E8268FB5885044A833FC5459588F4A9184CFC41A5766",
"public_key": "mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ=="
}
],
"active": true,
"pending": false,
"pending_message": null,
"blocked_reason": null
}
}
Error responses share one format: see Errors.