Nameservers, contacts, EPP code, transfer lock, WHOIS privacy and auto-renew.
These calls belong to the client API and are addressed by the numeric domain id returned by GET /reseller/domains/{name} (field data.id), not by the name. Success bodies are {"data": …}; errors use the same error envelope as every other call.
List your domains #
GET
/client/domains
Every domain of the account, paginated, nearest expiration first, with
cancelled, transferred-away and pending-delete domains last. Filter by search (part of the name), status,
expiring_within_days or auto_renew.
Each item carries the numeric id the other Domain management calls are
addressed by. Read-only.
- Authentication: bearer Token
- Rate limit: 120 req/min per user
Parameters
Query
-
searchstringPart of a domain name, e.g.example. -
statusstringOnly domains in this status, e.g.active. -
expiring_within_daysintegerOnly domains expiring within this many days (already expired ones included). -
auto_renewstringOnly domains with auto-renewonoroff. -
per_pageintegerDomains per page, 1–100. Defaults to this server’s page size. -
pageintegerPage number, from 1.
Responses
-
200A page of your domains.
Response body
application/json-
dataarray of object16 properties
-
idinteger -
client_idinteger -
sldstring -
tld_extensionstring | null -
namestring -
display_namestring -
statusstring -
auto_renewboolean -
registration_datestring | null -
expiration_datestring | null -
registration_period_yearsinteger -
currency_codestring | null -
last_synced_atstring | null -
registrant_verificationobject | nullOwner (registrant) email verification as last read from the registrar, or null when it was never read or the registrar does not report it.statusisnot_required,pending,verifiedorsuspended; while it ispendingorsuspendedthe owner must click the link the registrar emailed toemail. This is the state as last read, not a live answer: it is refreshed only for Active domains, so on any other status it may be stale.3 properties
-
statusstring -
emailstring -
deadlinestring | null
-
-
tldobject2 properties
-
idinteger | null -
extensionstring | null
-
-
supported_actionsarray of string | null
-
-
linksobject4 properties
-
firststring | null -
laststring | null -
prevstring | null -
nextstring | null
-
-
metaobject8 properties
-
current_pageinteger -
frominteger | null -
last_pageinteger -
linksarray of object3 properties
-
urlstring | null -
labelstring -
activeboolean
-
-
pathstring -
per_pageinteger -
tointeger | null -
totalinteger
-
-
cURL
curl 'https://portal.supporthost.com/api/v1/client/domains' \
-H "Authorization: Bearer $API_TOKEN" \
-H 'Accept: application/json'
PHP
<?php
$ch = curl_init('https://portal.supporthost.com/api/v1/client/domains');
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', {
headers: {
Authorization: `Bearer ${process.env.API_TOKEN}`,
Accept: 'application/json',
},
});
console.log(await response.json());
200
{
"data": [
{
"id": 1042,
"client_id": 318,
"sld": "example",
"tld_extension": ".com",
"name": "example.com",
"display_name": "example.com",
"status": "active",
"auto_renew": false,
"registration_date": "2026-09-15T00:00:00+02:00",
"expiration_date": "2027-09-15T00:00:00+02:00",
"registration_period_years": 1,
"currency_code": "EUR",
"last_synced_at": "2026-09-27T06:00:12+02:00",
"registrant_verification": {
"status": "pending",
"email": "owner@example.com",
"deadline": "2026-10-09T10:00:00+00:00"
},
"tld": {
"id": 3,
"extension": ".com"
},
"supported_actions": [
"renew",
"get_epp",
"lock",
"unlock",
"update_nameservers",
"update_contact",
"enable_whois_privacy",
"disable_whois_privacy"
]
}
],
"links": {
"first": "https://billing.example.com/api/v1/client/domains?page=1",
"last": "https://billing.example.com/api/v1/client/domains?page=2",
"prev": null,
"next": "https://billing.example.com/api/v1/client/domains?page=2"
},
"meta": {
"current_page": 1,
"from": 1,
"last_page": 2,
"links": [
{
"url": "https://billing.example.com/api/v1/client/domains?page=1",
"label": "1",
"active": true
}
],
"path": "https://billing.example.com/api/v1/client/domains",
"per_page": 25,
"to": 25,
"total": 38
}
}
Error responses share one format: see Errors.
Get a domain #
GET
/client/domains/{domain}
One of your domains with its dates, status, auto-renew flag and, in
supported_actions, the management operations its registry supports
in the domain’s current status.
By default the data may be refreshed from the registry when it is
stale; pass fresh=1 to force a live refresh first (slower).
- Authentication: bearer Token
- Rate limit: 120 req/min per user
Parameters
Path
-
domaininteger requiredThe domain ID
Query
-
freshbooleanSet to1to refresh the domain from the registry before answering.
Responses
-
200Response body
application/json-
dataobject16 properties
-
idinteger -
client_idinteger -
sldstring -
tld_extensionstring | null -
namestring -
display_namestring -
statusstring -
auto_renewboolean -
registration_datestring | null -
expiration_datestring | null -
registration_period_yearsinteger -
currency_codestring | null -
last_synced_atstring | null -
registrant_verificationobject | nullOwner (registrant) email verification as last read from the registrar, or null when it was never read or the registrar does not report it.statusisnot_required,pending,verifiedorsuspended; while it ispendingorsuspendedthe owner must click the link the registrar emailed toemail. This is the state as last read, not a live answer: it is refreshed only for Active domains, so on any other status it may be stale.3 properties
-
statusstring -
emailstring -
deadlinestring | null
-
-
tldobject2 properties
-
idinteger | null -
extensionstring | null
-
-
supported_actionsarray of string | null
-
-
cURL
curl 'https://portal.supporthost.com/api/v1/client/domains/{domain}' \
-H "Authorization: Bearer $API_TOKEN" \
-H 'Accept: application/json'
PHP
<?php
$ch = curl_init('https://portal.supporthost.com/api/v1/client/domains/{domain}');
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
const response = await fetch('https://portal.supporthost.com/api/v1/client/domains/{domain}', {
headers: {
Authorization: `Bearer ${process.env.API_TOKEN}`,
Accept: 'application/json',
},
});
console.log(await response.json());
200
{
"data": {
"id": 1042,
"client_id": 318,
"sld": "example",
"tld_extension": ".com",
"name": "example.com",
"display_name": "example.com",
"status": "active",
"auto_renew": false,
"registration_date": "2026-09-15T00:00:00+02:00",
"expiration_date": "2027-09-15T00:00:00+02:00",
"registration_period_years": 1,
"currency_code": "EUR",
"last_synced_at": "2026-09-27T06:00:12+02:00",
"registrant_verification": {
"status": "pending",
"email": "owner@example.com",
"deadline": "2026-10-09T10:00:00+00:00"
},
"tld": {
"id": 3,
"extension": ".com"
},
"supported_actions": [
"renew",
"get_epp",
"lock",
"unlock",
"update_nameservers",
"update_contact",
"enable_whois_privacy",
"disable_whois_privacy"
]
}
}
Error responses share one format: see Errors.
Get the nameservers #
GET
/client/domains/{domain}/nameservers
The nameservers currently set at the registry, read live. Read-only.
- Authentication: bearer Token
- Rate limit: 120 req/min per user
Parameters
Path
-
domaininteger requiredThe domain ID
Responses
-
200Response body
application/json-
dataobject1 property
-
nameserversarray of string
-
-
-
401unauthenticatedApiError -
403client_token_requiredtoken_not_api_enabledtoken_not_client_scopedclient_access_revokedclient_cancelledip_not_allowedip_whitelist_misconfiguredforbiddenApiError -
404client_not_foundnot_foundApiError -
422invalid_requestunprocessableApiError -
429rate_limitedApiError
cURL
curl 'https://portal.supporthost.com/api/v1/client/domains/{domain}/nameservers' \
-H "Authorization: Bearer $API_TOKEN" \
-H 'Accept: application/json'
PHP
<?php
$ch = curl_init('https://portal.supporthost.com/api/v1/client/domains/{domain}/nameservers');
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
const response = await fetch('https://portal.supporthost.com/api/v1/client/domains/{domain}/nameservers', {
headers: {
Authorization: `Bearer ${process.env.API_TOKEN}`,
Accept: 'application/json',
},
});
console.log(await response.json());
200
{
"data": {
"nameservers": [
"ns1.example.net",
"ns2.example.net"
]
}
}
Error responses share one format: see Errors.
Change the nameservers #
PUT
/client/domains/{domain}/nameservers
Replaces the domain’s nameservers at the registry with the list you
send (2 to 13 host names). completed: false means the registry
accepted the change but applies it later; message explains.
Free of charge. Refused with 403 domain_not_active when the domain’s status does not
allow it (e.g. expired).
- Authentication: bearer Token
- Rate limit: 120 req/min per user
Parameters
Path
-
domaininteger requiredThe domain ID
Body application/json
required
-
nameserversarray of string required2 to 13 nameserver host names, all different. The list replaces the current one.-
Min items
2 -
Max items
13 - Unique items
-
Pattern
^(?=.{1,253}$)([a-z0-9](?:[a-z0-9\-]{0,61}[a-z0-9])?)(\.[a-z0-9](?:[a-z0-9\-]{0,61}[a-z0-9])?)+$ -
Max length
253
-
Min items
Responses
-
200Response body
application/json-
dataobject2 properties
-
completedboolean -
messagestring
-
-
-
401unauthenticatedApiError -
403client_token_requiredtoken_not_api_enabledtoken_not_client_scopedclient_access_revokedclient_cancelledip_not_allowedip_whitelist_misconfiguredforbiddendomain_not_activeApiError -
404client_not_foundnot_foundApiError -
422invalid_requestunprocessableApiError -
429rate_limitedApiError
cURL
curl -X PUT 'https://portal.supporthost.com/api/v1/client/domains/{domain}/nameservers' \
-H "Authorization: Bearer $API_TOKEN" \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"nameservers": [
"ns1.example.net",
"ns2.example.net",
"ns3.example.net"
]
}'
PHP
<?php
$ch = curl_init('https://portal.supporthost.com/api/v1/client/domains/{domain}/nameservers');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('API_TOKEN'),
'Accept: application/json',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'nameservers' => [
'ns1.example.net',
'ns2.example.net',
'ns3.example.net',
],
]),
]);
$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}/nameservers', {
method: 'PUT',
headers: {
Authorization: `Bearer ${process.env.API_TOKEN}`,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"nameservers": [
"ns1.example.net",
"ns2.example.net",
"ns3.example.net"
]
}),
});
console.log(await response.json());
200
{
"data": {
"completed": true,
"message": "Nameservers updated."
}
}
Error responses share one format: see Errors.
Get a contact #
GET
/client/domains/{domain}/contacts
One contact of the domain, read live from the registry: the registrant
by default, or the role named by type. The response is keyed by that
role and also lists, in required_types, the roles this domain uses.
- Authentication: bearer Token
- Rate limit: 120 req/min per user
Parameters
Path
-
domaininteger requiredThe domain ID
Query
-
typestringThe contact role:registrant(default),admin,techorbilling. Must be one of the roles this domain uses.
Responses
-
200Response body
application/json-
dataobject1 property
-
required_typesarray
-
-
-
401unauthenticatedApiError -
403client_token_requiredtoken_not_api_enabledtoken_not_client_scopedclient_access_revokedclient_cancelledip_not_allowedip_whitelist_misconfiguredforbiddenApiError -
404client_not_foundnot_foundApiError -
422invalid_requestunprocessableApiError -
429rate_limitedApiError
cURL
curl 'https://portal.supporthost.com/api/v1/client/domains/{domain}/contacts' \
-H "Authorization: Bearer $API_TOKEN" \
-H 'Accept: application/json'
PHP
<?php
$ch = curl_init('https://portal.supporthost.com/api/v1/client/domains/{domain}/contacts');
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
const response = await fetch('https://portal.supporthost.com/api/v1/client/domains/{domain}/contacts', {
headers: {
Authorization: `Bearer ${process.env.API_TOKEN}`,
Accept: 'application/json',
},
});
console.log(await response.json());
200
{
"data": {
"required_types": [
"registrant",
"admin",
"tech"
]
}
}
Error responses share one format: see Errors.
Update a contact #
PUT
/client/domains/{domain}/contacts
Updates one contact of the domain at the registry: the registrant by
default, or the role named by type. Send the full contact, not only
the fields that change.
For the registrant, the registry-specific fields some TLDs require are
sent at the top level, next to first_name; which keys are required
depends on the TLD and on this server’s configuration, and a missing
one answers 422 naming it.
Free of charge. completed: false means the registry accepted the
change but applies it later; message explains.
- Authentication: bearer Token
- Rate limit: 120 req/min per user
Parameters
Path
-
domaininteger requiredThe domain ID
Body application/json
required
-
typestringThe contact to update:registrant(the default),admin,techorbilling. Only the roles this domain’s registry uses are accepted;GET /client/domains/{domain}/contactslists them inrequired_types.Allowed valuesregistrantadmintechbilling -
first_namestring required-
Max length
100
-
Max length
-
last_namestring required-
Max length
100
-
Max length
-
organizationstring | nullCompany name. For the registrant, some TLDs require it and some refuse it.-
Max length
200
-
Max length
-
emailstring required-
Format
email -
Max length
200
-
Format
-
phonestring requiredInternational format+CC.NUMBER, e.g.+39.0212345678. You may instead send a local number here together withphone_country_code(ISO country, e.g.IT).-
Pattern
^\+[0-9]{1,3}\.[0-9]{1,14}$ -
Max length
30
-
Pattern
-
street1string required-
Max length
200
-
Max length
-
street2string | null-
Max length
200
-
Max length
-
citystring required-
Max length
100
-
Max length
-
state_provincestring | null-
Max length
100
-
Max length
-
postal_codestring required-
Max length
20
-
Max length
-
country_codestring requiredISO 3166-1 alpha-2 country code, e.g.IT.-
Min length
2 -
Max length
2
-
Min length
Responses
-
200Response body
application/json-
dataobject2 properties
-
completedboolean -
messagestring
-
-
-
401unauthenticatedApiError -
403client_token_requiredtoken_not_api_enabledtoken_not_client_scopedclient_access_revokedclient_cancelledip_not_allowedip_whitelist_misconfiguredforbiddendomain_not_activeApiError -
404client_not_foundnot_foundApiError -
422invalid_requestunprocessableApiError -
429rate_limitedApiError
cURL
curl -X PUT 'https://portal.supporthost.com/api/v1/client/domains/{domain}/contacts' \
-H "Authorization: Bearer $API_TOKEN" \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"type": "registrant",
"first_name": "Mario",
"last_name": "Rossi",
"organization": "Example Srl",
"email": "mario.rossi@example.com",
"phone": "+39.0212345678",
"street1": "Via Roma 1",
"city": "Milano",
"state_province": "MI",
"postal_code": "20121",
"country_code": "IT"
}'
PHP
<?php
$ch = curl_init('https://portal.supporthost.com/api/v1/client/domains/{domain}/contacts');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('API_TOKEN'),
'Accept: application/json',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'type' => 'registrant',
'first_name' => 'Mario',
'last_name' => 'Rossi',
'organization' => 'Example Srl',
'email' => 'mario.rossi@example.com',
'phone' => '+39.0212345678',
'street1' => 'Via Roma 1',
'city' => 'Milano',
'state_province' => 'MI',
'postal_code' => '20121',
'country_code' => 'IT',
]),
]);
$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}/contacts', {
method: 'PUT',
headers: {
Authorization: `Bearer ${process.env.API_TOKEN}`,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"type": "registrant",
"first_name": "Mario",
"last_name": "Rossi",
"organization": "Example Srl",
"email": "mario.rossi@example.com",
"phone": "+39.0212345678",
"street1": "Via Roma 1",
"city": "Milano",
"state_province": "MI",
"postal_code": "20121",
"country_code": "IT"
}),
});
console.log(await response.json());
200
{
"data": {
"completed": true,
"message": "Contact updated."
}
}
Error responses share one format: see Errors.
Get the transfer lock state #
GET
/client/domains/{domain}/lock-state
Whether the registry transfer lock is on, read live, and in supported
which of lock / unlock this domain’s registry allows. Read-only.
- Authentication: bearer Token
- Rate limit: 120 req/min per user
Parameters
Path
-
domaininteger requiredThe domain ID
Responses
-
200Response body
application/json-
dataobject2 properties
-
lockedboolean -
supportedarray of string
-
-
-
401unauthenticatedApiError -
403client_token_requiredtoken_not_api_enabledtoken_not_client_scopedclient_access_revokedclient_cancelledip_not_allowedip_whitelist_misconfiguredforbiddenApiError -
404client_not_foundnot_foundApiError -
422invalid_requestunprocessableApiError -
429rate_limitedApiError
cURL
curl 'https://portal.supporthost.com/api/v1/client/domains/{domain}/lock-state' \
-H "Authorization: Bearer $API_TOKEN" \
-H 'Accept: application/json'
PHP
<?php
$ch = curl_init('https://portal.supporthost.com/api/v1/client/domains/{domain}/lock-state');
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
const response = await fetch('https://portal.supporthost.com/api/v1/client/domains/{domain}/lock-state', {
headers: {
Authorization: `Bearer ${process.env.API_TOKEN}`,
Accept: 'application/json',
},
});
console.log(await response.json());
200
{
"data": {
"locked": true,
"supported": [
"lock",
"unlock"
]
}
}
Error responses share one format: see Errors.
Get the WHOIS privacy state #
GET
/client/domains/{domain}/whois-privacy-state
Whether WHOIS privacy is subscribed on the domain (subscribed),
whether the registry reports it active (registrarEnabled, read live),
whether enabling it is free or paid (optionPricing) and which of
enable / disable the registry supports (supported). Read-only.
- Authentication: bearer Token
- Rate limit: 120 req/min per user
Parameters
Path
-
domaininteger requiredThe domain ID
Responses
-
200Response body
application/json-
dataobject4 properties
-
subscribedboolean -
registrarEnabledboolean -
optionPricingstringAllowed valuesunknownfreepaid -
supportedarray of string
-
-
-
401unauthenticatedApiError -
403client_token_requiredtoken_not_api_enabledtoken_not_client_scopedclient_access_revokedclient_cancelledip_not_allowedip_whitelist_misconfiguredforbiddenApiError -
404client_not_foundnot_foundApiError -
422invalid_requestunprocessableApiError -
429rate_limitedApiError
cURL
curl 'https://portal.supporthost.com/api/v1/client/domains/{domain}/whois-privacy-state' \
-H "Authorization: Bearer $API_TOKEN" \
-H 'Accept: application/json'
PHP
<?php
$ch = curl_init('https://portal.supporthost.com/api/v1/client/domains/{domain}/whois-privacy-state');
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
const response = await fetch('https://portal.supporthost.com/api/v1/client/domains/{domain}/whois-privacy-state', {
headers: {
Authorization: `Bearer ${process.env.API_TOKEN}`,
Accept: 'application/json',
},
});
console.log(await response.json());
200
{
"data": {
"subscribed": true,
"registrarEnabled": true,
"optionPricing": "free",
"supported": [
"enable_whois_privacy",
"disable_whois_privacy"
]
}
}
Error responses share one format: see Errors.
Turn auto-renew on or off #
POST
/client/domains/{domain}/auto-renew
With auto-renew on, the domain is renewed automatically before it expires. Turning it off also removes the domain from an open renewal invoice, if it had one. It cannot be turned off on a domain included with a hosting service: that domain renews with the service.
- Authentication: bearer Token
- Rate limit: 120 req/min per user
Parameters
Path
-
domaininteger requiredThe domain ID
Body application/json
required
-
valuestring required1to turn auto-renew on,0to turn it off.Allowed values01
Responses
-
200Response body
application/json-
dataobject1 property
-
auto_renewboolean
-
-
-
401unauthenticatedApiError -
403client_token_requiredtoken_not_api_enabledtoken_not_client_scopedclient_access_revokedclient_cancelledip_not_allowedip_whitelist_misconfiguredforbiddendomain_not_activeApiError -
404client_not_foundnot_foundApiError -
422invalid_requestunprocessableApiError -
429rate_limitedApiError
cURL
curl -X POST 'https://portal.supporthost.com/api/v1/client/domains/{domain}/auto-renew' \
-H "Authorization: Bearer $API_TOKEN" \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"value": "0"
}'
PHP
<?php
$ch = curl_init('https://portal.supporthost.com/api/v1/client/domains/{domain}/auto-renew');
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([
'value' => '0',
]),
]);
$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}/auto-renew', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.API_TOKEN}`,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"value": "0"
}),
});
console.log(await response.json());
200
{
"data": {
"auto_renew": false
}
}
Error responses share one format: see Errors.
Enable the transfer lock #
POST
/client/domains/{domain}/lock
Turns on the registry transfer lock, which blocks transfers of the
domain to another registrar. Free of charge. completed: false means
the registry applies it later.
- Authentication: bearer Token
- Rate limit: 120 req/min per user
Parameters
Path
-
domaininteger requiredThe domain ID
Responses
-
200Response body
application/json-
dataobject2 properties
-
completedboolean -
messagestring
-
-
-
401unauthenticatedApiError -
403client_token_requiredtoken_not_api_enabledtoken_not_client_scopedclient_access_revokedclient_cancelledip_not_allowedip_whitelist_misconfiguredforbiddendomain_not_activeApiError -
404client_not_foundnot_foundApiError -
422invalid_requestunprocessableApiError -
429rate_limitedApiError
cURL
curl -X POST 'https://portal.supporthost.com/api/v1/client/domains/{domain}/lock' \
-H "Authorization: Bearer $API_TOKEN" \
-H 'Accept: application/json'
PHP
<?php
$ch = curl_init('https://portal.supporthost.com/api/v1/client/domains/{domain}/lock');
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}/lock', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.API_TOKEN}`,
Accept: 'application/json',
},
});
console.log(await response.json());
200
{
"data": {
"completed": true,
"message": "Transfer lock enabled."
}
}
Error responses share one format: see Errors.
Disable the transfer lock #
POST
/client/domains/{domain}/unlock
Turns off the registry transfer lock so the domain can be transferred
away. Free of charge. completed: false means the registry applies it
later.
- Authentication: bearer Token
- Rate limit: 120 req/min per user
Parameters
Path
-
domaininteger requiredThe domain ID
Responses
-
200Response body
application/json-
dataobject2 properties
-
completedboolean -
messagestring
-
-
-
401unauthenticatedApiError -
403client_token_requiredtoken_not_api_enabledtoken_not_client_scopedclient_access_revokedclient_cancelledip_not_allowedip_whitelist_misconfiguredforbiddendomain_not_activeApiError -
404client_not_foundnot_foundApiError -
422invalid_requestunprocessableApiError -
429rate_limitedApiError
cURL
curl -X POST 'https://portal.supporthost.com/api/v1/client/domains/{domain}/unlock' \
-H "Authorization: Bearer $API_TOKEN" \
-H 'Accept: application/json'
PHP
<?php
$ch = curl_init('https://portal.supporthost.com/api/v1/client/domains/{domain}/unlock');
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}/unlock', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.API_TOKEN}`,
Accept: 'application/json',
},
});
console.log(await response.json());
200
{
"data": {
"completed": true,
"message": "Transfer lock disabled."
}
}
Error responses share one format: see Errors.
Get the EPP code #
POST
/client/domains/{domain}/epp
Retrieves the transfer authorisation (EPP) code. Depending on the
registry the code is returned in code (delivered_via: screen) or
emailed to the registrant (delivered_via: email, code: null).
A POST because it has side effects: some registries generate a new code on every request.
- Authentication: bearer Token
- Rate limit: 120 req/min per user
Parameters
Path
-
domaininteger requiredThe domain ID
Responses
-
200Response body
application/json-
dataobject3 properties
-
delivered_viastring -
codestring | null -
messagestring | null
-
-
-
401unauthenticatedApiError -
403client_token_requiredtoken_not_api_enabledtoken_not_client_scopedclient_access_revokedclient_cancelledip_not_allowedip_whitelist_misconfiguredforbiddendomain_not_activeApiError -
404client_not_foundnot_foundApiError -
422invalid_requestunprocessableApiError -
429rate_limitedApiError
cURL
curl -X POST 'https://portal.supporthost.com/api/v1/client/domains/{domain}/epp' \
-H "Authorization: Bearer $API_TOKEN" \
-H 'Accept: application/json'
PHP
<?php
$ch = curl_init('https://portal.supporthost.com/api/v1/client/domains/{domain}/epp');
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}/epp', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.API_TOKEN}`,
Accept: 'application/json',
},
});
console.log(await response.json());
200
{
"data": {
"delivered_via": "screen",
"code": "EXAMPLE-EPP-7Hq2",
"message": "Give this code to the new registrar to authorise the transfer."
}
}
Error responses share one format: see Errors.
Release the domain to another registrar #
POST
/client/domains/{domain}/release
Hands the domain over to another registrar, identified by its tag. Some
registries move a domain this way instead of with a transfer code: .uk
domains (including .co.uk, .org.uk and the other .uk extensions) leave
by a tag change, often called the IPS tag. Ask the receiving registrar
for its tag and send it as tag; letters, digits and hyphens, case is
ignored.
Only for a domain whose status is active: any other status answers
403 domain_not_active. A domain whose registry does not release by tag answers
422 domain_release_not_supported: use the EPP code
(POST /client/domains/{domain}/epp) to transfer it instead.
Irreversible from our side: once the receiving registrar has the domain, it is no longer managed from this account and cannot be taken back from here. Check the tag before sending it.
- Authentication: bearer Token
- Rate limit: 10 req/min per user
Parameters
Path
-
domaininteger requiredThe domain ID
Body application/json
required
-
tagstring requiredThe tag of the registrar receiving the domain, as that registrar gives it to you: letters, digits and hyphens, up to 32 characters. Case is ignored. The release is irreversible from our side, so check it before sending.-
Pattern
^[A-Za-z0-9\-]+$ -
Max length
32
-
Pattern
Responses
-
200Response body
application/json-
dataobject2 properties
-
completedboolean -
messagestring
-
-
-
401unauthenticatedApiError -
403client_token_requiredtoken_not_api_enabledtoken_not_client_scopedclient_access_revokedclient_cancelledip_not_allowedip_whitelist_misconfiguredforbiddendomain_not_activeApiError -
404client_not_foundnot_foundApiError -
422domain_release_not_supportedregistrar_errorinvalid_requestunprocessableApiError -
429rate_limitedApiError
cURL
curl -X POST 'https://portal.supporthost.com/api/v1/client/domains/{domain}/release' \
-H "Authorization: Bearer $API_TOKEN" \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"tag": "EXAMPLE-REGISTRAR"
}'
PHP
<?php
$ch = curl_init('https://portal.supporthost.com/api/v1/client/domains/{domain}/release');
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([
'tag' => 'EXAMPLE-REGISTRAR',
]),
]);
$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}/release', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.API_TOKEN}`,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"tag": "EXAMPLE-REGISTRAR"
}),
});
console.log(await response.json());
200
{
"data": {
"completed": true,
"message": "Your domain has been released to the receiving registrar."
}
}
Error responses share one format: see Errors.
Enable WHOIS privacy #
POST
/client/domains/{domain}/whois-privacy/enable
Hides the owner’s details from public WHOIS. When the service is free
it is enabled at once (enabled: true). When it is paid, an invoice is
issued and returned (enabled: false, invoice_id, invoice):
privacy is enabled once that invoice is paid.
- Authentication: bearer Token
- Rate limit: 120 req/min per user
Parameters
Path
-
domaininteger requiredThe domain ID
Responses
-
200Response body
application/json-
dataobject3 properties
-
enabledboolean -
invoice_idinteger | null -
invoiceobject | null47 properties
-
idinteger -
client_idinteger -
clientobject4 properties
-
idinteger -
firstnamestring -
lastnamestring -
companystring | null
-
-
typestring -
related_invoice_idinteger | null -
related_invoiceobject3 properties
-
idinteger | null -
invoice_numberstring | null -
display_numberstring | null
-
-
invoice_numberstring | null -
display_numberstring -
statusstring -
currency_codestring -
exchange_ratestring -
gateway_idinteger | null -
client_namestring | null -
client_companystring | null -
client_emailstring | null -
client_addressstring | null -
client_citystring | null -
client_statestring | null -
client_countrystring | null -
client_postcodestring | null -
client_vat_numberstring | null -
client_tax_exemptboolean -
client_custom_fieldsAny of
Option 1 object
Option 2 map of any
-
-
business_namestring | null -
business_addressstring | null -
business_vat_numberstring | null -
subtotalstring | number -
tax1_namestring | null -
tax1_ratestring | number -
tax1_amountstring | number -
tax2_namestring | null -
tax2_ratestring | number -
tax2_amountstring | number -
tax_overrideboolean -
totalstring | number -
credit_appliedstring | number -
balancestring | number -
datestring | null -
due_datestring | null -
paid_datestring | null -
itemsarray of object12 properties
-
idinteger -
invoice_idinteger -
descriptionstring -
qtystring -
unit_pricestring -
taxableboolean -
amountstring -
source_typestring | null -
source_idinteger | null -
sort_orderinteger -
created_atstring -
updated_atstring
-
-
transactionsarray of object16 properties
-
idinteger -
client_idinteger -
clientobject4 properties
-
idinteger -
firstnamestring -
lastnamestring -
companystring | null
-
-
invoice_idinteger | null -
related_transaction_idinteger | null -
related_transactionobject4 properties
-
idinteger | null -
amountstring | null -
typestring | null -
datestring | null
-
-
amountstring -
currency_codestring -
gatewaystring | null -
transaction_idstring | null -
exchange_ratestring -
typestring -
descriptionstring | null -
datestring -
created_atstring -
updated_atstring
-
-
collection_held_atstring | null -
collection_hold_reasonstring | null -
extensionsstring -
created_atstring -
updated_atstring
-
-
-
-
401unauthenticatedApiError -
403client_token_requiredtoken_not_api_enabledtoken_not_client_scopedclient_access_revokedclient_cancelledip_not_allowedip_whitelist_misconfiguredforbiddendomain_not_activeApiError -
404client_not_foundnot_foundApiError -
422invalid_requestunprocessableApiError -
429rate_limitedApiError
cURL
curl -X POST 'https://portal.supporthost.com/api/v1/client/domains/{domain}/whois-privacy/enable' \
-H "Authorization: Bearer $API_TOKEN" \
-H 'Accept: application/json'
PHP
<?php
$ch = curl_init('https://portal.supporthost.com/api/v1/client/domains/{domain}/whois-privacy/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}/whois-privacy/enable', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.API_TOKEN}`,
Accept: 'application/json',
},
});
console.log(await response.json());
200
{
"data": {
"enabled": false,
"invoice_id": 20871,
"invoice": {
"id": 20871,
"client_id": 318,
"client": {
"id": 318,
"firstname": "Mario",
"lastname": "Rossi",
"company": "Example Srl"
},
"type": "invoice",
"related_invoice_id": 20790,
"related_invoice": {
"id": 20790,
"invoice_number": "1498",
"display_number": "1498"
},
"invoice_number": "1532",
"display_number": "1532",
"status": "unpaid",
"currency_code": "EUR",
"exchange_rate": "1.00000",
"gateway_id": 1,
"client_name": "Mario Rossi",
"client_company": "Example Srl",
"client_email": "mario.rossi@example.com",
"client_address": "Via Roma 1",
"client_city": "Milano",
"client_state": "MI",
"client_country": "IT",
"client_postcode": "20121",
"client_vat_number": "IT01234567890",
"client_tax_exempt": false,
"client_custom_fields": {
"fiscal_code": "RSSMRA80A01F205X"
},
"business_name": "Example Hosting Srl",
"business_address": "Via Milano 10, 20121 Milano, Italy",
"business_vat_number": "IT09876543210",
"subtotal": "4.90",
"tax1_name": "VAT",
"tax1_rate": "22.000",
"tax1_amount": "1.08",
"tax2_name": null,
"tax2_rate": "0.000",
"tax2_amount": "0.00",
"tax_override": false,
"total": "5.98",
"credit_applied": "0.00",
"balance": "5.98",
"date": "2026-09-27T00:00:00+02:00",
"due_date": "2026-10-04T00:00:00+02:00",
"paid_date": null,
"items": [
{
"id": 48213,
"invoice_id": 20871,
"description": "WHOIS privacy - example.com",
"qty": "1.00",
"unit_price": "4.90",
"taxable": true,
"amount": "4.90",
"source_type": "domain_option",
"source_id": 1042,
"sort_order": 0,
"created_at": "2026-09-27T10:15:32+02:00",
"updated_at": "2026-09-27T10:15:32+02:00"
}
],
"transactions": [
{
"id": 7730,
"client_id": 318,
"client": {
"id": 318,
"firstname": "Mario",
"lastname": "Rossi",
"company": "Example Srl"
},
"invoice_id": 20871,
"related_transaction_id": 7729,
"related_transaction": {
"id": 7729,
"amount": "5.98",
"type": "payment",
"date": "2026-09-20T09:12:31+02:00"
},
"amount": "5.98",
"currency_code": "EUR",
"gateway": "bank_transfer",
"transaction_id": "TRX-20260927-0042",
"exchange_rate": "1.00000",
"type": "payment",
"description": "Payment of invoice 1532",
"date": "2026-09-27T11:02:44+02:00",
"created_at": "2026-09-27T11:02:44+02:00",
"updated_at": "2026-09-27T11:02:44+02:00"
}
],
"collection_held_at": null,
"collection_hold_reason": null,
"extensions": [],
"created_at": "2026-09-27T10:15:32+02:00",
"updated_at": "2026-09-27T10:15:32+02:00"
}
}
}
Error responses share one format: see Errors.
Disable WHOIS privacy #
POST
/client/domains/{domain}/whois-privacy/disable
Shows the owner’s details in public WHOIS again, where the registry allows it.
- Authentication: bearer Token
- Rate limit: 120 req/min per user
Parameters
Path
-
domaininteger requiredThe domain ID
Responses
-
200Response body
application/json-
dataobject1 property
-
enabledboolean
-
-
-
401unauthenticatedApiError -
403client_token_requiredtoken_not_api_enabledtoken_not_client_scopedclient_access_revokedclient_cancelledip_not_allowedip_whitelist_misconfiguredforbiddendomain_not_activeApiError -
404client_not_foundnot_foundApiError -
422invalid_requestunprocessableApiError -
429rate_limitedApiError
cURL
curl -X POST 'https://portal.supporthost.com/api/v1/client/domains/{domain}/whois-privacy/disable' \
-H "Authorization: Bearer $API_TOKEN" \
-H 'Accept: application/json'
PHP
<?php
$ch = curl_init('https://portal.supporthost.com/api/v1/client/domains/{domain}/whois-privacy/disable');
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}/whois-privacy/disable', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.API_TOKEN}`,
Accept: 'application/json',
},
});
console.log(await response.json());
200
{
"data": {
"enabled": false
}
}
Error responses share one format: see Errors.