Prices and availability for the reseller account: the net price table of every TLD you can sell, and a per-name availability check with its price.
Get your price list #
GET
/reseller/pricing
Your net prices for every TLD you can sell, in your account’s currency. This is also the list of TLDs available to you: a TLD that is not here cannot be registered or transferred through the API.
For each TLD, register and renew list every term you can buy
(years from min_years to max_years) with its price; transfer lists
only the minimum term, the one a transfer buys. grace_fee and
redemption_fee are added to a renewal in grace and to a restore;
null means none is charged. Prices are net of tax.
idn says whether the API accepts a Unicode name on the TLD (a Unicode
name on a TLD with idn: false is refused as invalid_domain); it is
not a statement about which scripts the registry supports.
registrant_countries lists the registrant countries (ISO codes) the
TLD accepts: a register or transfer with a registrant elsewhere is
refused as invalid_contact before any credit is taken. null means
the panel knows no country restriction, not that the registry has none.
A transfer always requires auth_code, whatever the TLD.
dnssec says whether DNSSEC can be managed on the TLD’s domains and in
which record form (ds or dnskey), so you know before registering.
It is a per-TLD capability: the truth for one domain, including whether
the zone is signed for you (enable), is the operations of that
domain’s DNSSEC state (GET /client/domains/{domain}/dnssec).
- Authentication: bearer Token
- Rate limit: 10 req/min per account
Responses
-
200Your price list.
Response body
application/json-
dataobject2 properties
-
currencystring -
tldsarray of object13 properties
-
extensionstring -
min_yearsinteger -
max_yearsinteger -
registerarray of object2 properties
-
yearsinteger -
pricenumber
-
-
renewarray of object2 properties
-
yearsinteger -
pricenumber
-
-
transferarray of object2 properties
-
yearsinteger -
pricenumber
-
-
grace_feenumber | null -
redemption_feenumber | null -
grace_daysinteger -
redemption_daysinteger -
idnboolean -
registrant_countriesarray of string | null -
dnssecobjectDNSSEC on the TLD’s domains. A per-TLD capability: the truth for one domain (including whetherenableis offered, a zone signed for you) is theoperationsof its DNSSEC state,GET /client/domains/{domain}/dnssec.2 properties
-
supportedbooleantruewhen DNSSEC can be managed through the API on this TLD’s domains. -
record_typestring | nullThe record form the TLD takes:ds(key_tag,algorithm,digest_type,digest) ordnskey(flags,protocol,algorithm,public_key);nullwhen notsupported.Allowed valuesdsdnskey
-
-
-
-
cURL
curl 'https://portal.supporthost.com/api/v1/reseller/pricing' \
-H "Authorization: Bearer $API_TOKEN" \
-H 'Accept: application/json'
PHP
<?php
$ch = curl_init('https://portal.supporthost.com/api/v1/reseller/pricing');
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/reseller/pricing', {
headers: {
Authorization: `Bearer ${process.env.API_TOKEN}`,
Accept: 'application/json',
},
});
console.log(await response.json());
200
{
"data": {
"currency": "EUR",
"tlds": [
{
"extension": ".com",
"min_years": 1,
"max_years": 10,
"register": [
{
"years": 1,
"price": 11.1699999999999999289457264239899814128875732421875
}
],
"renew": [
{
"years": 1,
"price": 11.1699999999999999289457264239899814128875732421875
}
],
"transfer": [
{
"years": 1,
"price": 11.1699999999999999289457264239899814128875732421875
}
],
"grace_fee": null,
"redemption_fee": 79.900000000000005684341886080801486968994140625,
"grace_days": 30,
"redemption_days": 30,
"idn": true,
"registrant_countries": null,
"dnssec": {
"supported": true,
"record_type": "ds"
}
}
]
}
}
Error responses share one format: see Errors.
Get a TLD's extra fields #
GET
/reseller/tlds/{tld}/extra-fields
The registry-specific data a TLD requires on POST /reseller/domains/register
and /transfer, in extra_fields (e.g. the entity type and tax codes of
.it). Read it to build your form instead of learning each field from a
422 invalid_contact. tld is the extension, with or without the dot
(it, .it, edu.it). A TLD with no extra fields answers an empty
fields list.
For each field: send it when visible_if holds (null: always); it is
mandatory when required is true, or when required_if holds. A
condition is {"field", "op", "value"} with op one of eq, ne
(value a string) or in, not_in (value a list of strings), or a
group {"all": [...]} / {"any": [...]} of conditions. field names
another extra field or a registrant field, compared as a string; a
field with no value counts as different for ne and not_in.
A select accepts only the value of one of its options. A text
with a pattern must match it: a Unicode regular expression, already
anchored, with no delimiters or flags (use it with the u flag). A ticked checkbox is sent
as its checked_value, "1"; a mandatory one must be ticked. Labels
and descriptions are English.
The answer is the same as the refusal a register would give: an unknown
TLD, and one not on your price list, answer 422 tld_not_sellable.
This describes what a NEW registration or transfer of the extension
needs, with its default registry connection. For an EXISTING domain the
authoritative set is the extra_fields of
GET /reseller/domains/{name}/contacts: a domain managed through
another registry connection can use different keys.
- Authentication: bearer Token
- Rate limit: 300 req/min per account
Parameters
Path
-
tldstring required
Responses
-
200The TLD’s extra fields.
Response body
application/json-
dataobject2 properties
-
extensionstringThe TLD, canonical: lower case, leading dot, Punycode. -
fieldsarray of objectIn the order the form shows them. Empty when the TLD needs no extra data.10 properties
-
keystringThe key to send inextra_fields. -
labelstring -
descriptionstring | null -
typestringThe input: freetext, aselectamongoptions, or acheckbox.Allowed valuestextselectcheckbox -
requiredbooleantruewhen the field is always mandatory (while visible). -
required_ifmap of any | nullWhenrequiredisfalse: the condition that makes the field mandatory, ornull(optional).{"field", "op", "value"}or a group{"all": […]}/{"any": […]}. -
visible_ifmap of any | nullThe condition under which the field is asked for, same form asrequired_if;null: always. Do not send a field whose condition does not hold. -
optionsarray of objectThe accepted values of aselect, in display order; empty for other types.2 properties
-
valuestring -
labelstring
-
-
patternstring | nullA Unicode regular expression the value must match, anchored (^…$), without delimiters or flags — usable as a JSON Schema / ECMA-262 pattern with theuflag, ornull. -
checked_valuestring | nullFor acheckbox, the value that ticks it:"1".nullfor other types.
-
-
-
-
401unauthenticatedApiError -
403client_token_requiredtoken_not_api_enabledtoken_not_client_scopedclient_access_revokedclient_cancelledip_not_allowedip_whitelist_misconfiguredforbiddennot_resellercredit_disabledApiError -
404client_not_foundApiError -
422tld_not_sellableApiError -
429rate_limitedApiError
cURL
curl 'https://portal.supporthost.com/api/v1/reseller/tlds/{tld}/extra-fields' \
-H "Authorization: Bearer $API_TOKEN" \
-H 'Accept: application/json'
PHP
<?php
$ch = curl_init('https://portal.supporthost.com/api/v1/reseller/tlds/{tld}/extra-fields');
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/reseller/tlds/{tld}/extra-fields', {
headers: {
Authorization: `Bearer ${process.env.API_TOKEN}`,
Accept: 'application/json',
},
});
console.log(await response.json());
200
{
"data": {
"extension": ".it",
"fields": [
{
"key": "entity_type",
"label": "Entity type",
"description": "The legal nature of the registrant.",
"type": "select",
"required": true,
"required_if": null,
"visible_if": null,
"options": [
{
"value": "1",
"label": "Italian and foreign natural persons"
}
],
"pattern": null,
"checked_value": null
}
]
}
}
Error responses share one format: see Errors.
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
-
-
-
401unauthenticatedApiError -
403client_token_requiredtoken_not_api_enabledtoken_not_client_scopedclient_access_revokedclient_cancelledip_not_allowedip_whitelist_misconfiguredforbiddennot_resellercredit_disabledApiError -
404client_not_foundApiError -
422invalid_requestinvalid_domaintld_not_sellableApiError -
429rate_limitedApiError
cURL
curl 'https://portal.supporthost.com/api/v1/reseller/domains/check?name=example.com' \
-H "Authorization: Bearer $API_TOKEN" \
-H 'Accept: application/json'
PHP
<?php
$ch = curl_init('https://portal.supporthost.com/api/v1/reseller/domains/check?name=example.com');
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/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.