Domain Pricing and Settings
The seven endpoints behind the overall rules of selling domains: recovery, add-on fees, automatic pricing and premium.
Overview
These endpoints look not at one extension but at the overall rules of selling domains: how long and at what cost an expired domain can be recovered, what DNS management or WHOIS privacy costs, whether prices are set automatically, and whether premium domains are sold at all.
An extension's own price and features live elsewhere; the settings here work above them. The one exception is the recovery fee: name an extension and it is written for that one only.
Reference
A WHOIS Query
Runs a WHOIS query for a domain and returns the raw output.
domain was empty.curl -G 'https://panel.example.com/api/v1/admin/products/domain/whois' \
-H "Authorization: Bearer $API_KEY" \
-d domain=example.comconst url = new URL('https://panel.example.com/api/v1/admin/products/domain/whois');
url.searchParams.set('domain', 'example.com');
const res = await fetch(url, { headers: { Authorization: `Bearer ${apiKey}` } });
const body = await res.json();$url = 'https://panel.example.com/api/v1/admin/products/domain/whois?' . http_build_query(['domain' => 'example.com']);
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// The query goes out to a remote server: it can be slow and it can be rate limited.
$response = Api::Products()->GetDomainWhois([], ['domain' => 'example.com']);
$free = $response['data']['available'] ?? false;Grace and Redemption Fees
Sets how long an expired domain can be recovered and what that costs.
curl -X PUT 'https://panel.example.com/api/v1/admin/products/domain/grace-redemption' \
-H "Authorization: Bearer $API_KEY" \
-H 'Content-Type: application/json' \
-d '{"grace":{"duration":30,"fees":{"USD":{"fee":0,"status":false}}},"redemption":{"duration":30,"fees":{"USD":{"fee":80,"status":true}}}}'const res = await fetch('https://panel.example.com/api/v1/admin/products/domain/grace-redemption', {
method: 'PUT',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
grace: { duration: 30, fees: { USD: { fee: 0, status: false } } },
redemption: { duration: 30, fees: { USD: { fee: 80, status: true } } },
}),
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/products/domain/grace-redemption');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'redemption' => [
'duration' => 30,
'fees' => ['USD' => ['fee' => 80, 'status' => true]],
],
]),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// Giving an extension writes the setting for THAT one only; the global default stays.
Api::Products()->SetDomainGraceRedemption([
'extension' => 'com',
'redemption' => [
'duration' => 30,
'fees' => ['USD' => ['fee' => 80, 'status' => true]],
],
]);Domain Add-on Fees
Sets the fee for DNS management, forwarding, WHOIS privacy and the transfer code.
dns_manage, forwarding, whois_privacy or epp_code.curl -X PUT 'https://panel.example.com/api/v1/admin/products/domain/addon-pricing' \
-H "Authorization: Bearer $API_KEY" \
-H 'Content-Type: application/json' \
-d '{"type":"whois_privacy","fees":{"USD":{"fee":5,"status":true}}}'const res = await fetch('https://panel.example.com/api/v1/admin/products/domain/addon-pricing', {
method: 'PUT',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
type: 'whois_privacy',
fees: { USD: { fee: 5, status: true } },
}),
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/products/domain/addon-pricing');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'type' => 'whois_privacy',
'fees' => ['USD' => ['fee' => 5, 'status' => true]],
]),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// The fee is the same on every extension; which extension OFFERS it lives on the TLD record.
Api::Products()->SetDomainAddonPricing([
'type' => 'whois_privacy',
'fees' => ['USD' => ['fee' => 5, 'status' => true]],
]);The Automatic Pricing State
Returns whether automatic pricing is on and what the profit margin is.
curl 'https://panel.example.com/api/v1/admin/products/domain/auto-pricing' \
-H "Authorization: Bearer $API_KEY"const res = await fetch('https://panel.example.com/api/v1/admin/products/domain/auto-pricing', {
headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/products/domain/auto-pricing');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);$response = Api::Products()->GetDomainAutoPricing();Setting Automatic Pricing
Turns automatic pricing on or off, or changes the margin and reprices.
status or pricing.status branch.pricing branch; writing it reprices every auto-priced extension at once.update is neither of the two values.curl -X PUT 'https://panel.example.com/api/v1/admin/products/domain/auto-pricing' \
-H "Authorization: Bearer $API_KEY" \
-H 'Content-Type: application/json' \
-d '{"update":"pricing","rate":20}'const res = await fetch('https://panel.example.com/api/v1/admin/products/domain/auto-pricing', {
method: 'PUT',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ update: 'pricing', rate: 20 }),
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/products/domain/auto-pricing');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode(['update' => 'pricing', 'rate' => 20]),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// Writing the margin reprices EVERY auto-priced extension there and then.
Api::Products()->SetDomainAutoPricing([
'update' => 'pricing',
'rate' => 20,
]);Premium Domain Settings
Returns whether premium domain sales are on and what the price tiers are.
curl 'https://panel.example.com/api/v1/admin/products/domain/premium' \
-H "Authorization: Bearer $API_KEY"const res = await fetch('https://panel.example.com/api/v1/admin/products/domain/premium', {
headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/products/domain/premium');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);$response = Api::Products()->GetDomainPremium();Writing the Premium Settings
Turns premium sales on or off, or writes the price tiers.
status or pricing.status branch.pricing branch; the list is written whole.update is neither of the two values.curl -X PUT 'https://panel.example.com/api/v1/admin/products/domain/premium' \
-H "Authorization: Bearer $API_KEY" \
-H 'Content-Type: application/json' \
-d '{"update":"pricing","fees":[{"amount":100,"markup":10},{"amount":1000,"markup":5}]}'const res = await fetch('https://panel.example.com/api/v1/admin/products/domain/premium', {
method: 'PUT',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
update: 'pricing',
fees: [
{ amount: 100, markup: 10 },
{ amount: 1000, markup: 5 },
],
}),
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/products/domain/premium');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'update' => 'pricing',
'fees' => [
['amount' => 100, 'markup' => 10],
['amount' => 1000, 'markup' => 5],
],
]),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// The tier list is written whole: a missing tier is deleted.
Api::Products()->SetDomainPremium([
'update' => 'pricing',
'fees' => [
['amount' => 100, 'markup' => 10],
['amount' => 1000, 'markup' => 5],
],
]);Pitfalls
Writing the profit margin does not only store a setting: every extension with automatic pricing on is repriced at the same moment. The change reaches the storefront immediately, with no cron to wait for. Move the margin in small steps and read the result from the extension detail.
The automatic pricing and premium endpoints run a single branch chosen by update. A field sent on the wrong branch is ignored without a word: sending the margin on the status branch changes nothing and raises no error. Always confirm through the read endpoint.
The add-on fee is written here, shared by every extension. Whether an extension offers that feature at all sits on its own record. A feature you priced but no extension offers is never paid for, so check both together.
The query goes to a remote server: it can be slow, it can hit a rate limit, and the text that comes back is formatted differently by every registry. If you are writing a bulk check, set a timeout and use the available field rather than parsing the raw output.
Related Articles
Thanks for your feedback!
Our support team is here around the clock for anything you can't find above.