Registering is three calls: check the name, register it, then read its state until the registry has finished. The same pattern covers transfers, renewals and restores.
Check availability
Ask whether the name is free and what it costs you. Nothing is reserved or charged.
Check a domain name #
GET
/reseller/domains/check
Tells you whether name can be registered, with your register and
transfer price for the TLD’s minimum term. Use it before
POST /reseller/domains/register or /transfer.
available is null when the registry could not be asked right now:
retry later. A name already held on this server is reported as not
available. Nothing is reserved or charged.
A definite answer is reused for up to 2 minutes, so asking again for
the same name costs no registry lookup; register and transfer always
check afresh before charging.
- Authentication: bearer Token
- Rate limit: 300 req/min per account
Parameters
Query
-
namestring required-
Max length
255
-
Max length
Responses
-
200Availability and price.
Response body
application/json-
dataobject6 properties
-
namestring -
availableboolean | null -
currencystring -
register_pricenumber | null -
transfer_pricenumber | null -
min_yearsinteger
-
-
-
401Missing, invalid or expired token. MessageError -
403not_resellercredit_disabledforbiddenip_not_allowedip_whitelist_misconfiguredResellerError -
422invalid_requestinvalid_domaintld_not_sellableResellerError -
429Rate limit exceeded. Retry after the number of seconds inRetry-After. MessageError
cURL
curl 'https://portal.supporthost.com/api/v1/reseller/domains/check?name=example.com' \
-H "Authorization: Bearer $API_TOKEN" \
-H 'Accept: application/json'
PHP
Install Guzzle once: composer require guzzlehttp/guzzle
<?php
require 'vendor/autoload.php';
$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://portal.supporthost.com/api/v1/reseller/domains/check?name=example.com', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('API_TOKEN'),
'Accept' => 'application/json',
],
]);
echo $response->getBody();
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/reseller/domains/check?name=example.com', {
headers: {
Authorization: `Bearer ${process.env.API_TOKEN}`,
Accept: 'application/json',
},
});
console.log(await response.json());
200
{
"data": {
"name": "example.com",
"available": true,
"currency": "EUR",
"register_price": 11.1699999999999999289457264239899814128875732421875,
"transfer_price": 11.1699999999999999289457264239899814128875732421875,
"min_years": 1
}
}
Error responses share one format: see Errors.
available is null when the registry could not be asked right now: retry later rather than treating it as taken. The check counts towards the reseller reads limit (300 calls per minute, shared by your whole account), so do not call it on every keystroke of a search box.
Register the domain
Send the name, the owner contact (registrant) and, optionally, the term in years and the nameservers. The price is debited from your credit before the registry is contacted, and refunded automatically if the registry refuses. Send an Idempotency-Key so a network retry can never register or charge twice (see Idempotency).
Register a domain #
POST
/reseller/domains/register
Registers an available name, paid from your credit at your net price.
Check availability and price first with GET /reseller/domains/check.
yearsdefaults to the TLD’s minimum term;GET /reseller/pricinglists the terms you can buy.nameservers(2–5 host names) is optional: omitted, the default nameservers configured on this server are used.registrantis the owner contact. The phone is+CC.NNNN(e.g.+39.0212345678), or a local number plusphone_country_code(ISO country, e.g.IT).extra_fieldsis an object of string values for the registry-specific data some TLDs require (entity type, tax codes, language…). Which keys are required depends on the TLD and on this server’s configuration, and some are only required depending on another field’s answer. Send a checkbox as"1". Keys the TLD does not declare are ignored. A missing or invalid field answers422 invalid_contact, whosefieldsmap names every field to fix.sourceis optional: your platform’s own additional fields, as your platform holds them, for this server to translate intoextra_fields. A key you send inextra_fieldswins over a translated one.
Side effects: the charge is taken from your credit before the registry
is contacted, and refunded automatically if the registry refuses. On
424 registrar_unknown the registry did not confirm the outcome and the
charge is NOT refunded while it is reconciled: do not retry with a new
Idempotency-Key.
- Authentication: bearer Token
- Rate limit: 30 req/min per account
Parameters
Header
-
Idempotency-KeystringOptional. 1–255 printable ASCII characters, scoped to your account. A retry with the same key and the same request returns the stored response byte for byte (withIdempotent-Replayed: true) and never charges twice. The same key with a different request answers422 idempotency_key_reused; while the first request is still running,409 idempotency_in_progress(retry afterretry_afterseconds). Keys are kept for 30 days. See Idempotency in the introduction.-
Min length
1 -
Max length
255
-
Min length
Body application/json
required
-
namestring requiredThe domain to register, e.g.example.com. A Unicode (IDN) name is accepted only on a TLD that supports it, and is converted to its ASCII form; otherwise422 invalid_domain.-
Max length
255
-
Max length
-
yearsintegerRegistration term. Defaults to the TLD’s minimum; must be one of theregistertermsGET /reseller/pricinglists for the TLD, otherwise422 invalid_years(withallowed_years).-
Minimum
1
-
Minimum
-
nameserversarray of string2 to 5 nameserver host names. Optional: when omitted, the default nameservers configured on this server are used.-
Min items
2 -
Max items
5 -
Pattern
^[A-Za-z0-9.\-]+$ -
Max length
255
-
Min items
-
registrantobject requiredThe owner contact of the domain, the only contact these calls take. The registrar fills the other roles the TLD needs (admin, tech, billing) on its own: most copy the registrant, some use contacts of their own. Change a role afterwards with the client API contacts update.11 properties
-
first_namestring required-
Max length
100
-
Max length
-
last_namestring required-
Max length
100
-
Max length
-
organizationstring | nullCompany name. Some TLDs require it and some refuse it: either case answers422 invalid_contact.-
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 withregistrant.phone_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. When the TLD listsregistrant_countriesinGET /reseller/pricing, it must be one of them, otherwise422 invalid_contactbefore any credit is taken.-
Min length
2 -
Max length
2
Allowed valuesAFALDZADAOAIAQAGSAAR240 more values
AMAWAUATAZBSBHBDBBBEBZBJBMBTBYBOBABWBRBNBGBFBIKHCMCACVBQCZTDCLCNCYVACOKMCDCGKPKRCRCIHRCUCWDKDMECEGSVAEEREESZETFJPHFIFRGAGMGEGSDEGHJMJPGIDJJOGRGDGLGPGUGTGGGNGQGWGYGFHTHNINIDIRIQIEISBVCXNFIMKYCCCKFKFOHMMPMHUMPNSBTCVIVGAXILITJEKZKEKGKIXKKWLALSLVLBLRLYLILTLUMKMGMWMYMVMLMTMAMQMRMUYTMXFMMDMCMNMEMSMZMMNANRNPNINENGNUNONCNZOMNLPKPWPAPGPYPEPFPLPTPRQAHKMOGBCFDORERORWRUEHKNLCMFVCBLPMWSASSMSHSNRSSCSLSGSXSYSKSISOESLKUSSSZASDSRSJSECHSTTJTWTZTFPSIOTHTLTGTKTOTTTNTRTMTVUAUGHUUYUZVUVEVNWFYEZMZW -
Min length
-
-
extra_fieldsmap of stringRegistry-specific data some TLDs require (e.g. entity type, tax codes, language). Which keys are required depends on the TLD and on this server’s configuration, and some are only required depending on the answer to another field. Values are strings: send a checkbox as"1". Keys the TLD does not declare are ignored. A missing or invalid field answers422 invalid_contactwith afieldsmap naming each field to fix. -
sourceobjectOptional. The additional domain fields of your own platform, sent as your platform holds them, for this server to translate intoextra_fields. A registrar module generated by this server fills it in: you do not need it when you sendextra_fieldsyourself. A key you send inextra_fieldsalways wins over a translated one.5 properties
-
platformstringYour platform, lower case:whmcs,hostbill.-
Pattern
^[a-z][a-z0-9-]*$ -
Max length
32
-
Pattern
-
versionstring | nullYour platform’s own version, e.g.8.13.1: field names differ between versions.-
Max length
50
-
Max length
-
module_versionstring | nullVersion of the registrar module sending the request.-
Max length
50
-
Max length
-
fieldsmap of stringThe platform’s additional fields, name => value, exactly as the platform holds them (e.g."Legal Type": "Companies/one man companies"). At most 50, values up to 255 characters. -
translatedarray of stringTheextra_fieldskeys your module translated itself fromsource.fields. This server’s own translation wins over them; keys not listed here are yours and win over it.-
Max items
100 -
Max length
64
-
Max items
-
Responses
-
200Registered.
Idempotent-Replayedstring response headertruewhen this response is the replay of an earlier request with the same Idempotency-Key.
Response body
application/json-
dataobject3 properties
-
statestring-
Value
completed
-
Value
-
domainobject8 properties
-
idinteger -
namestring -
statusstringAllowed valuespendingpending_registrationpending_transferactiveexpiredgraceredemptionpending_deletetransferring_awaytransferred_awaytransfer_failedcancelledfraud -
registration_datestring | null -
expiration_datestring | null -
next_due_datestring | null -
auto_renewboolean -
transferobject2 properties
-
pendingboolean -
failedboolean
-
-
-
chargesarray of object8 properties
-
idinteger -
actionstringAllowed valuesregistertransferrenewrestoregrace_feeredemption_fee -
yearsinteger -
currencystring -
netnumber -
taxnumber -
grossnumber -
statusstringAllowed valuespendingbillableinvoicedrefunded
-
-
-
202Accepted — completes laterAccepted but not completed yet: the registry has taken the request and will finish it later. Your credit has already been debited; the charges stay
pendinguntil the operation completes (then they are billed on your next monthly invoice) and are refunded automatically if it fails. PollGET /reseller/domains/{name}untilstatusleavespending_registration/pending_transfer(a failed transfer showstransfer.failed: true).Idempotent-Replayedstring response headertruewhen this response is the replay of an earlier request with the same Idempotency-Key.
Response body
application/json-
dataobject3 properties
-
statestring-
Value
pending
-
Value
-
domainobject8 properties
-
idinteger -
namestring -
statusstringAllowed valuespendingpending_registrationpending_transferactiveexpiredgraceredemptionpending_deletetransferring_awaytransferred_awaytransfer_failedcancelledfraud -
registration_datestring | null -
expiration_datestring | null -
next_due_datestring | null -
auto_renewboolean -
transferobject2 properties
-
pendingboolean -
failedboolean
-
-
-
chargesarray of object8 properties
-
idinteger -
actionstringAllowed valuesregistertransferrenewrestoregrace_feeredemption_fee -
yearsinteger -
currencystring -
netnumber -
taxnumber -
grossnumber -
statusstringAllowed valuespendingbillableinvoicedrefunded
-
-
-
401Missing, invalid or expired token. MessageError -
402insufficient_creditResellerError -
403not_resellercredit_disabledforbiddenip_not_allowedip_whitelist_misconfiguredResellerError -
409operation_in_progressidempotency_in_progressResellerError -
422invalid_requestinvalid_contactinvalid_domaintld_not_sellableinvalid_yearsdomain_unavailableregistration_data_missingregistrar_errorinvalid_idempotency_keyidempotency_key_reusedResellerError -
424registrar_unknownResellerError -
429Rate limit exceeded. Retry after the number of seconds inRetry-After. MessageError -
500operation_failedResellerError -
503whois_unavailableResellerError
cURL
# Idempotency-Key is optional: a retry with the same key is never processed twice.
curl -X POST 'https://portal.supporthost.com/api/v1/reseller/domains/register' \
-H "Authorization: Bearer $API_TOKEN" \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: 00000000-0000-4000-8000-000000000000' \
-d '{
"name": "example.com",
"years": 1,
"nameservers": [
"ns1.example.net",
"ns2.example.net"
],
"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
require 'vendor/autoload.php';
$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'https://portal.supporthost.com/api/v1/reseller/domains/register', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('API_TOKEN'),
'Accept' => 'application/json',
// Optional: a retry with the same key is never processed twice.
'Idempotency-Key' => '00000000-0000-4000-8000-000000000000',
],
'json' => [
'name' => 'example.com',
'years' => 1,
'nameservers' => [
'ns1.example.net',
'ns2.example.net',
],
'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',
],
],
]);
echo $response->getBody();
Node.js
const response = await fetch('https://portal.supporthost.com/api/v1/reseller/domains/register', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.API_TOKEN}`,
Accept: 'application/json',
'Content-Type': 'application/json',
// Optional: a retry with the same key is never processed twice.
'Idempotency-Key': '00000000-0000-4000-8000-000000000000',
},
body: JSON.stringify({
"name": "example.com",
"years": 1,
"nameservers": [
"ns1.example.net",
"ns2.example.net"
],
"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": {
"state": "completed",
"domain": {
"id": 1042,
"name": "example.com",
"status": "active",
"registration_date": "2026-09-15",
"expiration_date": "2027-09-15",
"next_due_date": "2027-09-15",
"auto_renew": false,
"transfer": {
"pending": false,
"failed": false
}
},
"charges": [
{
"id": 5310,
"action": "register",
"years": 1,
"currency": "EUR",
"net": 11.1699999999999999289457264239899814128875732421875,
"tax": 2.45999999999999996447286321199499070644378662109375,
"gross": 13.6300000000000007815970093361102044582366943359375,
"status": "billable"
}
]
}
}
202
{
"data": {
"state": "pending",
"domain": {
"id": 1042,
"name": "example.com",
"status": "pending_registration",
"registration_date": "2026-09-15",
"expiration_date": "2027-09-15",
"next_due_date": "2027-09-15",
"auto_renew": false,
"transfer": {
"pending": false,
"failed": false
}
},
"charges": [
{
"id": 5310,
"action": "register",
"years": 1,
"currency": "EUR",
"net": 11.1699999999999999289457264239899814128875732421875,
"tax": 2.45999999999999996447286321199499070644378662109375,
"gross": 13.6300000000000007815970093361102044582366943359375,
"status": "pending"
}
]
}
}
Error responses share one format: see Errors.
.it extra fields
Some TLDs need registry-specific data, sent in extra_fields as an object of string values; checkboxes are sent as "1". Keys a TLD does not declare are ignored. .com, .net and .org need none; .it needs these:
Key | Meaning | Required |
|---|---|---|
entity_type | Registrant type: 1 natural person (Italian or foreign) · 2 company · 3 sole proprietorship / freelancer · 4 non-profit organisation · 5 public entity · 6 other entity · 7 foreign entity (equivalent to 2–6, not natural persons) | Always |
codice_fiscale | Italian tax code or ID document number; 5–36 letters, digits, dots, hyphens or spaces | When entity_type is 1 |
partita_iva | VAT number / numeric tax code; exactly 11 digits | When entity_type is 2 to 6 |
tax_code_estero | Foreign tax code; 2–36 letters, digits, dots, hyphens or spaces | When entity_type is 7 |
consent_publishing | Consent to publish the registrant’s data in the WHOIS; send "1" | When entity_type is not 1 or 3; optional otherwise |
accept_terms | Acceptance of the .it registration rules; send "1" | Always |
For example, a company:
"extra_fields": {
"entity_type": "2",
"partita_iva": "01234567890",
"consent_publishing": "1",
"accept_terms": "1"
}
organization is accepted on all four sandbox TLDs but required on none.
When the contact is refused
A missing or invalid registrant or extra field answers 422 with the code invalid_contact. Its fields map names every field to fix, with the messages for each, so you can show them next to your form fields:
{
"error": {
"code": "invalid_contact",
"message": "The registrant contact or the extension fields are not valid.",
"fields": {
"registrant.phone": ["The phone must be in the format +CC.NUMBER."],
"extra_fields.partita_iva": ["The VAT number must be 11 digits."]
}
}
}
Other request problems answer invalid_request with the same fields map. The exact messages are examples: branch on the keys, not on the text.
Wait for the pending state
A money-moving call answers with one of three state values: completed (200, done), pending (202, the registry has taken the request and will finish it later) or, on renew and restore only, not_settled (202, see below). A register call answers either 200 ("state": "completed", the domain is registered) or 202 ("state": "pending"). With 202 your credit is already debited; the charge stays pending until the operation completes, then it is billed on your next monthly invoice.
If an accepted operation fails later, what happens to the money depends on the operation. A register or transfer that ends up failed is refunded automatically. Renew and restore follow different rules: see Refunds on renew and restore. In every case, do not retry with a new Idempotency-Key.
Poll the domain by name until status leaves pending_registration (or pending_transfer). This call reads the state stored on SupportHost and never contacts the registry, so it is cheap; polling every minute or so is plenty.
Get a domain by name #
GET
/reseller/domains/{name}
Returns the current state of one of your domains: status, dates,
auto-renew and whether a transfer is pending or failed. The id in the
response is the one the Domain management calls are addressed by.
Use it to poll an operation that answered 202. It reads the state
stored on this server and never contacts the registry, so it is cheap
to call.
- Authentication: bearer Token
- Rate limit: 300 req/min per account
Parameters
Path
-
namestring required
Responses
-
200The domain.
Response body
application/json-
dataobject8 properties
-
idinteger -
namestring -
statusstringAllowed valuespendingpending_registrationpending_transferactiveexpiredgraceredemptionpending_deletetransferring_awaytransferred_awaytransfer_failedcancelledfraud -
registration_datestring | null -
expiration_datestring | null -
next_due_datestring | null -
auto_renewboolean -
transferobject2 properties
-
pendingboolean -
failedboolean
-
-
-
-
401Missing, invalid or expired token. MessageError -
403not_resellercredit_disabledforbiddenip_not_allowedip_whitelist_misconfiguredResellerError -
404not_foundResellerError -
429Rate limit exceeded. Retry after the number of seconds inRetry-After. MessageError
cURL
curl 'https://portal.supporthost.com/api/v1/reseller/domains/{name}' \
-H "Authorization: Bearer $API_TOKEN" \
-H 'Accept: application/json'
PHP
<?php
require 'vendor/autoload.php';
$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://portal.supporthost.com/api/v1/reseller/domains/{name}', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('API_TOKEN'),
'Accept' => 'application/json',
],
]);
echo $response->getBody();
Node.js
const response = await fetch('https://portal.supporthost.com/api/v1/reseller/domains/{name}', {
headers: {
Authorization: `Bearer ${process.env.API_TOKEN}`,
Accept: 'application/json',
},
});
console.log(await response.json());
200
{
"data": {
"id": 1042,
"name": "example.com",
"status": "active",
"registration_date": "2026-09-15",
"expiration_date": "2027-09-15",
"next_due_date": "2027-09-15",
"auto_renew": false,
"transfer": {
"pending": false,
"failed": false
}
}
}
Error responses share one format: see Errors.
A successful registration ends in active. A failed transfer shows "transfer": {"failed": true}. The response id is the numeric id the Domain management calls use.
Renew a domain
Renew an active domain, or one in grace (which also pays the TLD’s grace fee). A domain in redemption answers 409 restore_required: restore it first. If the domain already has an open renewal invoice, your credit pays that invoice instead of creating a charge (paid_invoice_id, paid_invoice_covers).
Renew a domain #
POST
/reseller/domains/{name}/renew
Adds years to an active or grace domain, paid from your credit. A
domain in grace also pays the TLD’s grace fee (a separate grace_fee
charge). A domain in redemption must be restored first
(409 restore_required).
If the domain already has an open renewal invoice for that term, your
credit pays that invoice instead of creating a charge: charges is then
empty and paid_invoice_id / paid_invoice_covers name the invoice and
the domains it renewed (an invoice can cover several of your domains;
paid_invoice_covers_truncated: true means the list was cut at 50).
- Authentication: bearer Token
- Rate limit: 30 req/min per account
Parameters
Path
-
namestring required
Header
-
Idempotency-KeystringOptional. 1–255 printable ASCII characters, scoped to your account. A retry with the same key and the same request returns the stored response byte for byte (withIdempotent-Replayed: true) and never charges twice. The same key with a different request answers422 idempotency_key_reused; while the first request is still running,409 idempotency_in_progress(retry afterretry_afterseconds). Keys are kept for 30 days. See Idempotency in the introduction.-
Min length
1 -
Max length
255
-
Min length
Body application/json
required
-
yearsinteger requiredYears to add. Must be one of therenewtermsGET /reseller/pricinglists for the TLD, otherwise422 invalid_years(withallowed_years).-
Minimum
1 -
Maximum
999
-
Minimum
Responses
-
200Renewed.
Idempotent-Replayedstring response headertruewhen this response is the replay of an earlier request with the same Idempotency-Key.
Response body
application/json-
dataobject6 properties
-
statestring-
Value
completed
-
Value
-
domainobject8 properties
-
idinteger -
namestring -
statusstringAllowed valuespendingpending_registrationpending_transferactiveexpiredgraceredemptionpending_deletetransferring_awaytransferred_awaytransfer_failedcancelledfraud -
registration_datestring | null -
expiration_datestring | null -
next_due_datestring | null -
auto_renewboolean -
transferobject2 properties
-
pendingboolean -
failedboolean
-
-
-
chargesarray of object8 properties
-
idinteger -
actionstringAllowed valuesregistertransferrenewrestoregrace_feeredemption_fee -
yearsinteger -
currencystring -
netnumber -
taxnumber -
grossnumber -
statusstringAllowed valuespendingbillableinvoicedrefunded
-
-
paid_invoice_idinteger -
paid_invoice_coversarray of string -
paid_invoice_covers_truncatedboolean
-
-
202Accepted — completes laterAccepted but not confirmed yet.
pending: the registrar has not confirmed the operation; your credit has already been used, and its charges staypendinguntil the domain’s dates move, then they are billed (pollGET /reseller/domains/{name}and watchexpiration_date/next_due_date).not_settled: your credit was applied to an open renewal invoice that it did not fully pay, so the domain is NOT renewed yet. In neither case is anything refunded automatically: if the operation did not happen, support follows up. Do not retry with a new Idempotency-Key.Idempotent-Replayedstring response headertruewhen this response is the replay of an earlier request with the same Idempotency-Key.
Response body
application/json-
dataobject6 properties
-
statestringAllowed valuespendingnot_settled -
domainobject8 properties
-
idinteger -
namestring -
statusstringAllowed valuespendingpending_registrationpending_transferactiveexpiredgraceredemptionpending_deletetransferring_awaytransferred_awaytransfer_failedcancelledfraud -
registration_datestring | null -
expiration_datestring | null -
next_due_datestring | null -
auto_renewboolean -
transferobject2 properties
-
pendingboolean -
failedboolean
-
-
-
chargesarray of object8 properties
-
idinteger -
actionstringAllowed valuesregistertransferrenewrestoregrace_feeredemption_fee -
yearsinteger -
currencystring -
netnumber -
taxnumber -
grossnumber -
statusstringAllowed valuespendingbillableinvoicedrefunded
-
-
paid_invoice_idinteger -
paid_invoice_coversarray of string -
paid_invoice_covers_truncatedboolean
-
-
401Missing, invalid or expired token. MessageError -
402insufficient_creditResellerError -
403not_resellercredit_disabledforbiddenip_not_allowedip_whitelist_misconfiguredResellerError -
404not_foundResellerError -
409restore_requiredrenewal_in_progressoperation_in_progressidempotency_in_progressResellerError -
422invalid_requestinvalid_yearsdomain_not_renewableregistrar_errorinvalid_idempotency_keyidempotency_key_reusedResellerError -
424registrar_unknownResellerError -
429Rate limit exceeded. Retry after the number of seconds inRetry-After. MessageError
cURL
# Idempotency-Key is optional: a retry with the same key is never processed twice.
curl -X POST 'https://portal.supporthost.com/api/v1/reseller/domains/{name}/renew' \
-H "Authorization: Bearer $API_TOKEN" \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: 00000000-0000-4000-8000-000000000000' \
-d '{
"years": 1
}'
PHP
<?php
require 'vendor/autoload.php';
$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'https://portal.supporthost.com/api/v1/reseller/domains/{name}/renew', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('API_TOKEN'),
'Accept' => 'application/json',
// Optional: a retry with the same key is never processed twice.
'Idempotency-Key' => '00000000-0000-4000-8000-000000000000',
],
'json' => [
'years' => 1,
],
]);
echo $response->getBody();
Node.js
const response = await fetch('https://portal.supporthost.com/api/v1/reseller/domains/{name}/renew', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.API_TOKEN}`,
Accept: 'application/json',
'Content-Type': 'application/json',
// Optional: a retry with the same key is never processed twice.
'Idempotency-Key': '00000000-0000-4000-8000-000000000000',
},
body: JSON.stringify({
"years": 1
}),
});
console.log(await response.json());
200
{
"data": {
"state": "completed",
"domain": {
"id": 1042,
"name": "example.com",
"status": "active",
"registration_date": "2026-09-15",
"expiration_date": "2028-09-15",
"next_due_date": "2028-09-15",
"auto_renew": false,
"transfer": {
"pending": false,
"failed": false
}
},
"charges": [
{
"id": 5311,
"action": "renew",
"years": 1,
"currency": "EUR",
"net": 11.1699999999999999289457264239899814128875732421875,
"tax": 2.45999999999999996447286321199499070644378662109375,
"gross": 13.6300000000000007815970093361102044582366943359375,
"status": "billable"
}
],
"paid_invoice_id": 20790,
"paid_invoice_covers": [
"example.com",
"example.net"
],
"paid_invoice_covers_truncated": true
}
}
202
{
"data": {
"state": "pending",
"domain": {
"id": 1042,
"name": "example.com",
"status": "active",
"registration_date": "2026-09-15",
"expiration_date": "2027-09-15",
"next_due_date": "2027-09-15",
"auto_renew": false,
"transfer": {
"pending": false,
"failed": false
}
},
"charges": [
{
"id": 5311,
"action": "renew",
"years": 1,
"currency": "EUR",
"net": 11.1699999999999999289457264239899814128875732421875,
"tax": 2.45999999999999996447286321199499070644378662109375,
"gross": 13.6300000000000007815970093361102044582366943359375,
"status": "pending"
}
],
"paid_invoice_id": 20790,
"paid_invoice_covers": [
"example.com",
"example.net"
],
"paid_invoice_covers_truncated": true
}
}
Error responses share one format: see Errors.
Refunds on renew and restore
- Refused at once (
422 registrar_error): the amount charged is refunded automatically. - Accepted (
202,pendingornot_settled): never refunded automatically. If the operation does not happen, SupportHost follows up. Poll the domain and watchexpiration_date/next_due_datemove; do not retry with a new Idempotency-Key.
When the invoice is not settled
Rarely, the open renewal invoice is paid from your credit but still does not reach Paid, because its balance grew in the meantime. The call then answers 202 with "state": "not_settled", an empty charges list, and paid_invoice_id / paid_invoice_covers for the payment that was made. The domain is not renewed yet, and nothing is refunded automatically: SupportHost follows up. Do not retry with a new Idempotency-Key; contact support if you need it settled sooner.
Transfer a domain in
The body is the register body plus auth_code, the EPP code from the current registrar; years is not accepted, a transfer buys the TLD’s minimum term. The same extra_fields rules apply. Most transfers answer 202 and take from hours to several days: poll as above. A name that is not registered answers 422 domain_not_registered and nothing is charged.
Transfer a domain in #
POST
/reseller/domains/transfer
Starts the transfer of a registered name to your account, paid from your
credit at your net transfer price. The body is the register body plus
auth_code (the EPP code from the current registrar); years is not
accepted, a transfer always buys the TLD’s minimum term.
registrant, nameservers and extra_fields follow the same rules as
POST /reseller/domains/register, including the per-TLD extra_fields
and the 422 invalid_contact answer with its fields map.
Most transfers answer 202: the registry and the losing registrar take
from hours to several days to complete one. The charge is refunded
automatically if the transfer fails.
- Authentication: bearer Token
- Rate limit: 30 req/min per account
Parameters
Header
-
Idempotency-KeystringOptional. 1–255 printable ASCII characters, scoped to your account. A retry with the same key and the same request returns the stored response byte for byte (withIdempotent-Replayed: true) and never charges twice. The same key with a different request answers422 idempotency_key_reused; while the first request is still running,409 idempotency_in_progress(retry afterretry_afterseconds). Keys are kept for 30 days. See Idempotency in the introduction.-
Min length
1 -
Max length
255
-
Min length
Body application/json
required
-
namestring requiredThe domain to transfer in, e.g.example.org.-
Max length
255
-
Max length
-
nameserversarray of string2 to 5 nameserver host names. Optional: when omitted, the default nameservers configured on this server are used.-
Min items
2 -
Max items
5 -
Pattern
^[A-Za-z0-9.\-]+$ -
Max length
255
-
Min items
-
registrantobject requiredThe owner contact of the domain, the only contact these calls take. The registrar fills the other roles the TLD needs (admin, tech, billing) on its own: most copy the registrant, some use contacts of their own. Change a role afterwards with the client API contacts update.11 properties
-
first_namestring required-
Max length
100
-
Max length
-
last_namestring required-
Max length
100
-
Max length
-
organizationstring | nullCompany name. Some TLDs require it and some refuse it: either case answers422 invalid_contact.-
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 withregistrant.phone_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. When the TLD listsregistrant_countriesinGET /reseller/pricing, it must be one of them, otherwise422 invalid_contactbefore any credit is taken.-
Min length
2 -
Max length
2
Allowed valuesAFALDZADAOAIAQAGSAAR240 more values
AMAWAUATAZBSBHBDBBBEBZBJBMBTBYBOBABWBRBNBGBFBIKHCMCACVBQCZTDCLCNCYVACOKMCDCGKPKRCRCIHRCUCWDKDMECEGSVAEEREESZETFJPHFIFRGAGMGEGSDEGHJMJPGIDJJOGRGDGLGPGUGTGGGNGQGWGYGFHTHNINIDIRIQIEISBVCXNFIMKYCCCKFKFOHMMPMHUMPNSBTCVIVGAXILITJEKZKEKGKIXKKWLALSLVLBLRLYLILTLUMKMGMWMYMVMLMTMAMQMRMUYTMXFMMDMCMNMEMSMZMMNANRNPNINENGNUNONCNZOMNLPKPWPAPGPYPEPFPLPTPRQAHKMOGBCFDORERORWRUEHKNLCMFVCBLPMWSASSMSHSNRSSCSLSGSXSYSKSISOESLKUSSSZASDSRSJSECHSTTJTWTZTFPSIOTHTLTGTKTOTTTNTRTMTVUAUGHUUYUZVUVEVNWFYEZMZW -
Min length
-
-
extra_fieldsmap of stringRegistry-specific data some TLDs require (e.g. entity type, tax codes, language). Which keys are required depends on the TLD and on this server’s configuration, and some are only required depending on the answer to another field. Values are strings: send a checkbox as"1". Keys the TLD does not declare are ignored. A missing or invalid field answers422 invalid_contactwith afieldsmap naming each field to fix. -
sourceobjectOptional. The additional domain fields of your own platform, sent as your platform holds them, for this server to translate intoextra_fields. A registrar module generated by this server fills it in: you do not need it when you sendextra_fieldsyourself. A key you send inextra_fieldsalways wins over a translated one.5 properties
-
platformstringYour platform, lower case:whmcs,hostbill.-
Pattern
^[a-z][a-z0-9-]*$ -
Max length
32
-
Pattern
-
versionstring | nullYour platform’s own version, e.g.8.13.1: field names differ between versions.-
Max length
50
-
Max length
-
module_versionstring | nullVersion of the registrar module sending the request.-
Max length
50
-
Max length
-
fieldsmap of stringThe platform’s additional fields, name => value, exactly as the platform holds them (e.g."Legal Type": "Companies/one man companies"). At most 50, values up to 255 characters. -
translatedarray of stringTheextra_fieldskeys your module translated itself fromsource.fields. This server’s own translation wins over them; keys not listed here are yours and win over it.-
Max items
100 -
Max length
64
-
Max items
-
-
auth_codestring requiredThe transfer authorisation (EPP) code, obtained from the domain’s current registrar. Always required, whatever the TLD: the panel does not know reliably which registries transfer without one, so it never starts a transfer without it.-
Max length
255
-
Max length
Responses
-
200Transferred.
Idempotent-Replayedstring response headertruewhen this response is the replay of an earlier request with the same Idempotency-Key.
Response body
application/json-
dataobject3 properties
-
statestring-
Value
completed
-
Value
-
domainobject8 properties
-
idinteger -
namestring -
statusstringAllowed valuespendingpending_registrationpending_transferactiveexpiredgraceredemptionpending_deletetransferring_awaytransferred_awaytransfer_failedcancelledfraud -
registration_datestring | null -
expiration_datestring | null -
next_due_datestring | null -
auto_renewboolean -
transferobject2 properties
-
pendingboolean -
failedboolean
-
-
-
chargesarray of object8 properties
-
idinteger -
actionstringAllowed valuesregistertransferrenewrestoregrace_feeredemption_fee -
yearsinteger -
currencystring -
netnumber -
taxnumber -
grossnumber -
statusstringAllowed valuespendingbillableinvoicedrefunded
-
-
-
202Accepted — completes laterAccepted but not completed yet: the registry has taken the request and will finish it later. Your credit has already been debited; the charges stay
pendinguntil the operation completes (then they are billed on your next monthly invoice) and are refunded automatically if it fails. PollGET /reseller/domains/{name}untilstatusleavespending_registration/pending_transfer(a failed transfer showstransfer.failed: true).Idempotent-Replayedstring response headertruewhen this response is the replay of an earlier request with the same Idempotency-Key.
Response body
application/json-
dataobject3 properties
-
statestring-
Value
pending
-
Value
-
domainobject8 properties
-
idinteger -
namestring -
statusstringAllowed valuespendingpending_registrationpending_transferactiveexpiredgraceredemptionpending_deletetransferring_awaytransferred_awaytransfer_failedcancelledfraud -
registration_datestring | null -
expiration_datestring | null -
next_due_datestring | null -
auto_renewboolean -
transferobject2 properties
-
pendingboolean -
failedboolean
-
-
-
chargesarray of object8 properties
-
idinteger -
actionstringAllowed valuesregistertransferrenewrestoregrace_feeredemption_fee -
yearsinteger -
currencystring -
netnumber -
taxnumber -
grossnumber -
statusstringAllowed valuespendingbillableinvoicedrefunded
-
-
-
401Missing, invalid or expired token. MessageError -
402insufficient_creditResellerError -
403not_resellercredit_disabledforbiddenip_not_allowedip_whitelist_misconfiguredResellerError -
409operation_in_progressidempotency_in_progressResellerError -
422invalid_requestinvalid_contactinvalid_domaintld_not_sellableinvalid_yearsdomain_unavailabledomain_not_registeredregistration_data_missingregistrar_errorinvalid_idempotency_keyidempotency_key_reusedResellerError -
424registrar_unknownResellerError -
429Rate limit exceeded. Retry after the number of seconds inRetry-After. MessageError -
500operation_failedResellerError -
503whois_unavailableResellerError
cURL
# Idempotency-Key is optional: a retry with the same key is never processed twice.
curl -X POST 'https://portal.supporthost.com/api/v1/reseller/domains/transfer' \
-H "Authorization: Bearer $API_TOKEN" \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: 00000000-0000-4000-8000-000000000000' \
-d '{
"name": "example.org",
"auth_code": "kX7#p2Qz9w",
"nameservers": [
"ns1.example.net",
"ns2.example.net"
],
"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
require 'vendor/autoload.php';
$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'https://portal.supporthost.com/api/v1/reseller/domains/transfer', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('API_TOKEN'),
'Accept' => 'application/json',
// Optional: a retry with the same key is never processed twice.
'Idempotency-Key' => '00000000-0000-4000-8000-000000000000',
],
'json' => [
'name' => 'example.org',
'auth_code' => 'kX7#p2Qz9w',
'nameservers' => [
'ns1.example.net',
'ns2.example.net',
],
'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',
],
],
]);
echo $response->getBody();
Node.js
const response = await fetch('https://portal.supporthost.com/api/v1/reseller/domains/transfer', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.API_TOKEN}`,
Accept: 'application/json',
'Content-Type': 'application/json',
// Optional: a retry with the same key is never processed twice.
'Idempotency-Key': '00000000-0000-4000-8000-000000000000',
},
body: JSON.stringify({
"name": "example.org",
"auth_code": "kX7#p2Qz9w",
"nameservers": [
"ns1.example.net",
"ns2.example.net"
],
"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": {
"state": "completed",
"domain": {
"id": 1043,
"name": "example.org",
"status": "active",
"registration_date": "2021-05-03",
"expiration_date": "2027-05-03",
"next_due_date": "2027-05-03",
"auto_renew": false,
"transfer": {
"pending": false,
"failed": false
}
},
"charges": [
{
"id": 5312,
"action": "transfer",
"years": 1,
"currency": "EUR",
"net": 11.1699999999999999289457264239899814128875732421875,
"tax": 2.45999999999999996447286321199499070644378662109375,
"gross": 13.6300000000000007815970093361102044582366943359375,
"status": "billable"
}
]
}
}
202
{
"data": {
"state": "pending",
"domain": {
"id": 1043,
"name": "example.org",
"status": "pending_transfer",
"registration_date": null,
"expiration_date": null,
"next_due_date": null,
"auto_renew": false,
"transfer": {
"pending": true,
"failed": false
}
},
"charges": [
{
"id": 5312,
"action": "transfer",
"years": 1,
"currency": "EUR",
"net": 11.1699999999999999289457264239899814128875732421875,
"tax": 2.45999999999999996447286321199499070644378662109375,
"gross": 13.6300000000000007815970093361102044582366943359375,
"status": "pending"
}
]
}
}
Error responses share one format: see Errors.
Restore from redemption
Recovers a domain in redemption and renews it for one year. It is charged as a one-year renewal plus the TLD’s redemption fee. No body. Like a renewal, a restore that pays an open renewal invoice can end in not_settled; refunds follow the same rules as a renewal.
Restore a domain from redemption #
POST
/reseller/domains/{name}/restore
Recovers a domain in redemption and renews it for one year, paid from
your credit: a restore charge priced as a one-year renewal, plus the
TLD’s redemption fee as a separate redemption_fee charge.
No body. Like renew, it pays an open renewal invoice for the domain
instead when there is one (paid_invoice_* fields, empty charges).
- Authentication: bearer Token
- Rate limit: 30 req/min per account
Parameters
Path
-
namestring required
Header
-
Idempotency-KeystringOptional. 1–255 printable ASCII characters, scoped to your account. A retry with the same key and the same request returns the stored response byte for byte (withIdempotent-Replayed: true) and never charges twice. The same key with a different request answers422 idempotency_key_reused; while the first request is still running,409 idempotency_in_progress(retry afterretry_afterseconds). Keys are kept for 30 days. See Idempotency in the introduction.-
Min length
1 -
Max length
255
-
Min length
Responses
-
200Restored.
Idempotent-Replayedstring response headertruewhen this response is the replay of an earlier request with the same Idempotency-Key.
Response body
application/json-
dataobject6 properties
-
statestring-
Value
completed
-
Value
-
domainobject8 properties
-
idinteger -
namestring -
statusstringAllowed valuespendingpending_registrationpending_transferactiveexpiredgraceredemptionpending_deletetransferring_awaytransferred_awaytransfer_failedcancelledfraud -
registration_datestring | null -
expiration_datestring | null -
next_due_datestring | null -
auto_renewboolean -
transferobject2 properties
-
pendingboolean -
failedboolean
-
-
-
chargesarray of object8 properties
-
idinteger -
actionstringAllowed valuesregistertransferrenewrestoregrace_feeredemption_fee -
yearsinteger -
currencystring -
netnumber -
taxnumber -
grossnumber -
statusstringAllowed valuespendingbillableinvoicedrefunded
-
-
paid_invoice_idinteger -
paid_invoice_coversarray of string -
paid_invoice_covers_truncatedboolean
-
-
202Accepted — completes laterAccepted but not confirmed yet.
pending: the registrar has not confirmed the operation; your credit has already been used, and its charges staypendinguntil the domain’s dates move, then they are billed (pollGET /reseller/domains/{name}and watchexpiration_date/next_due_date).not_settled: your credit was applied to an open renewal invoice that it did not fully pay, so the domain is NOT renewed yet. In neither case is anything refunded automatically: if the operation did not happen, support follows up. Do not retry with a new Idempotency-Key.Idempotent-Replayedstring response headertruewhen this response is the replay of an earlier request with the same Idempotency-Key.
Response body
application/json-
dataobject6 properties
-
statestringAllowed valuespendingnot_settled -
domainobject8 properties
-
idinteger -
namestring -
statusstringAllowed valuespendingpending_registrationpending_transferactiveexpiredgraceredemptionpending_deletetransferring_awaytransferred_awaytransfer_failedcancelledfraud -
registration_datestring | null -
expiration_datestring | null -
next_due_datestring | null -
auto_renewboolean -
transferobject2 properties
-
pendingboolean -
failedboolean
-
-
-
chargesarray of object8 properties
-
idinteger -
actionstringAllowed valuesregistertransferrenewrestoregrace_feeredemption_fee -
yearsinteger -
currencystring -
netnumber -
taxnumber -
grossnumber -
statusstringAllowed valuespendingbillableinvoicedrefunded
-
-
paid_invoice_idinteger -
paid_invoice_coversarray of string -
paid_invoice_covers_truncatedboolean
-
-
401Missing, invalid or expired token. MessageError -
402insufficient_creditResellerError -
403not_resellercredit_disabledforbiddenip_not_allowedip_whitelist_misconfiguredResellerError -
404not_foundResellerError -
409renewal_in_progressoperation_in_progressidempotency_in_progressResellerError -
422domain_not_restorableregistrar_errorinvalid_idempotency_keyidempotency_key_reusedResellerError -
424registrar_unknownResellerError -
429Rate limit exceeded. Retry after the number of seconds inRetry-After. MessageError
cURL
# Idempotency-Key is optional: a retry with the same key is never processed twice.
curl -X POST 'https://portal.supporthost.com/api/v1/reseller/domains/{name}/restore' \
-H "Authorization: Bearer $API_TOKEN" \
-H 'Accept: application/json' \
-H 'Idempotency-Key: 00000000-0000-4000-8000-000000000000'
PHP
<?php
require 'vendor/autoload.php';
$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'https://portal.supporthost.com/api/v1/reseller/domains/{name}/restore', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('API_TOKEN'),
'Accept' => 'application/json',
// Optional: a retry with the same key is never processed twice.
'Idempotency-Key' => '00000000-0000-4000-8000-000000000000',
],
]);
echo $response->getBody();
Node.js
const response = await fetch('https://portal.supporthost.com/api/v1/reseller/domains/{name}/restore', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.API_TOKEN}`,
Accept: 'application/json',
// Optional: a retry with the same key is never processed twice.
'Idempotency-Key': '00000000-0000-4000-8000-000000000000',
},
});
console.log(await response.json());
200
{
"data": {
"state": "completed",
"domain": {
"id": 1042,
"name": "example.com",
"status": "active",
"registration_date": "2026-09-15",
"expiration_date": "2028-09-15",
"next_due_date": "2028-09-15",
"auto_renew": false,
"transfer": {
"pending": false,
"failed": false
}
},
"charges": [
{
"id": 5313,
"action": "restore",
"years": 1,
"currency": "EUR",
"net": 11.1699999999999999289457264239899814128875732421875,
"tax": 2.45999999999999996447286321199499070644378662109375,
"gross": 13.6300000000000007815970093361102044582366943359375,
"status": "billable"
}
],
"paid_invoice_id": 20790,
"paid_invoice_covers": [
"example.com",
"example.net"
],
"paid_invoice_covers_truncated": true
}
}
202
{
"data": {
"state": "pending",
"domain": {
"id": 1042,
"name": "example.com",
"status": "redemption",
"registration_date": "2026-09-15",
"expiration_date": "2027-09-15",
"next_due_date": "2027-09-15",
"auto_renew": false,
"transfer": {
"pending": false,
"failed": false
}
},
"charges": [
{
"id": 5313,
"action": "restore",
"years": 1,
"currency": "EUR",
"net": 11.1699999999999999289457264239899814128875732421875,
"tax": 2.45999999999999996447286321199499070644378662109375,
"gross": 13.6300000000000007815970093361102044582366943359375,
"status": "pending"
}
],
"paid_invoice_id": 20790,
"paid_invoice_covers": [
"example.com",
"example.net"
],
"paid_invoice_covers_truncated": true
}
}
Error responses share one format: see Errors.
Manage the domain
Nameservers, contacts, the EPP code, the transfer lock, WHOIS privacy and auto-renew are in Domain management. Those calls are addressed by the numeric id from GET /reseller/domains/{name}, not by the name. For example, to change the nameservers:
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 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-
successboolean -
dataobject2 properties
-
completedboolean -
messagestring
-
-
-
401Missing, invalid or expired token. MessageError -
403The token is not valid for this account, or its user lacks the required permission. When the token has an IP whitelist, a caller outside it is refused with{"success": false, "message": "IP not allowed"}, and a whitelist that cannot be read with{"success": false, "message": "IP whitelist misconfigured"}(ClientError). ClientError -
404The domain does not exist or belongs to another account. ClientError -
422Validation failed (ValidationError), or the registrar refused the operation or could not be reached (ClientError). ValidationError or ClientError -
429Rate limit exceeded. Retry after the number of seconds inRetry-After. MessageError
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
require 'vendor/autoload.php';
$client = new GuzzleHttp\Client();
$response = $client->request('PUT', 'https://portal.supporthost.com/api/v1/client/domains/{domain}/nameservers', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('API_TOKEN'),
'Accept' => 'application/json',
],
'json' => [
'nameservers' => [
'ns1.example.net',
'ns2.example.net',
'ns3.example.net',
],
],
]);
echo $response->getBody();
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
{
"success": true,
"data": {
"completed": true,
"message": "Nameservers updated."
}
}
Error responses share one format: see Errors.
Nameservers can also be set at registration with nameservers (2 to 5 host names); when omitted, SupportHost’s default nameservers are used.