Domain HTTP API
Check which domains are free and what each extension costs from any website, script or tool, with no key.
On this page
The domain search of the Domains page can be read from anywhere, such as a landing page with a domain checker, a pricing table or a script. It is a small, read-only API with two GET endpoints. There is no key and no sign in, any website can call it from the browser, and it answers with the prices a workspace pays. Every domain in an answer also carries a link that opens the Domains page with that domain searched, ready to buy.
The base address is https://api.modulify.ai/domains.
A service that needs DNS records on a domain bought here can hand its owner a link that fills them in for one-click approval, see Add records with a link.
Check a name
GET /availability checks whether domains are free and what they cost.
curl "https://api.modulify.ai/domains/availability?name=acme&tld=com"| Query | Value |
|---|---|
name |
Required. A name such as acme, or a full domain such as acme.com. A leading https://, a www. and anything after the domain are ignored. |
tld |
Optional. An extension such as com or co.uk, with or without its leading dot. It is added to the first part of name, so name=acme.com&tld=net checks acme.net. |
With a bare name, it checks the extensions Modulify features, such as .com, .net, .org, .co, .io and .ai. With an extension, on name or in tld, it checks that domain first and the featured extensions after it. Modulify sells the extensions Name.com registers, apart from those whose registry needs extra details Modulify cannot collect yet, such as .us or .eu.
{
"success": true,
"message": "Domains were searched successfully.",
"data": {
"Label": "acme",
"Requested": "acme.com",
"UnsupportedTld": null,
"Currency": "USD",
"Results": [
{
"Name": "acme.com",
"Tld": "com",
"Available": false,
"Premium": false,
"PriceCents": null,
"RenewalPriceCents": null,
"Years": 1,
"RenewalYears": 1,
"Currency": "USD",
"BuyUrl": "https://modulify.ai/dashboard/domains?name=acme&tld=com"
},
{
"Name": "acme.studio",
"Tld": "studio",
"Available": true,
"Premium": false,
"PriceCents": 2999,
"RenewalPriceCents": 3499,
"Years": 1,
"RenewalYears": 1,
"Currency": "USD",
"BuyUrl": "https://modulify.ai/dashboard/domains?name=acme&tld=studio"
}
]
},
"code": 200
}Treat a call as failed unless the HTTP status is ok and success is true, and read the answer from data. The envelope also carries version, the build of the API, which you can ignore.
| Field | Meaning |
|---|---|
Label |
The name that was checked, without its extension |
Requested |
The full domain you asked for, when its extension is on sale, otherwise null |
UnsupportedTld |
The extension you asked for when Modulify does not sell it, otherwise null. The results then cover the featured extensions |
Currency |
USD. Every price is in US cents |
Results |
One entry per domain, the one you asked for first |
Each entry in Results:
| Field | Meaning |
|---|---|
Name |
The full domain |
Tld |
Its extension |
Available |
false means Name.com says the name cannot be registered, almost always because someone has registered it. Otherwise it is true, and the name can be bought whenever PriceCents is set |
Premium |
true when the registry prices the name above its usual rate |
PriceCents |
What registering it costs for Years years. null when it is taken, or when it cannot be bought here right now: Name.com could not check it or gave no price for it, or the name has characters other than a to z, 0 to 9 and hyphens |
RenewalPriceCents |
What renewing it costs for RenewalYears years, or null when it is taken or not on sale |
Years |
The shortest term the extension is sold for, such as 2 for .ai |
RenewalYears |
The shortest term it renews for |
BuyUrl |
Opens the Domains page with this domain searched, see Link to a search |
An answer can be up to 10 minutes old, so a domain registered a moment ago can still show as available, and the answer is sent with Cache-Control: public, max-age=60. The price is worked out again when someone buys the domain, so what they pay is current.
List prices
GET /prices lists what each extension costs.
curl "https://api.modulify.ai/domains/prices?tlds=com,io,ai"| Query | Value |
|---|---|
tld |
One extension, such as com |
tlds |
Several extensions, separated by commas or spaces, up to 100 in one call |
featured |
true for the featured extensions only |
Leave them all out to list every extension on sale. The list is sorted by extension, apart from featured=true, which lists the featured extensions in the order a bare name is checked against them, starting with com.
{
"success": true,
"message": "Domain prices were listed successfully.",
"data": {
"Currency": "USD",
"Extensions": [
{
"Tld": "ai",
"Featured": true,
"Registration": { "PriceCents": 15998, "Years": 2 },
"Renewal": { "PriceCents": 15998, "Years": 2 }
},
{
"Tld": "com",
"Featured": true,
"Registration": { "PriceCents": 1299, "Years": 1 },
"Renewal": { "PriceCents": 1499, "Years": 1 }
}
]
},
"code": 200
}| Field | Meaning |
|---|---|
Tld |
The extension |
Featured |
true when a bare name is checked against it |
Registration |
PriceCents for registering a name for Years years, the shortest term the extension is sold for |
Renewal |
PriceCents for renewing it for Years years. Renewal is always there, and its PriceCents is null when Name.com gives no renewal price |
These are the prices of an ordinary name. A premium name costs more, and only Check a name gives its price. An extension you ask for that is not on sale is left out of Extensions, and asking for a single one that is not on sale returns 404, for example .local domains are not for sale! The answer is sent with Cache-Control: public, max-age=300.
From a website
Both endpoints answer every origin, so a page can call them straight from the browser. They take GET only and never read cookies or credentials.
const CheckDomain = async (name) => {
const response = await fetch(`https://api.modulify.ai/domains/availability?name=${encodeURIComponent(name)}`)
const { success, data, message } = await response.json()
if (!response.ok || !success) throw new Error(message)
return data.Results.filter(result => result.PriceCents !== null)
}Send people to a result's BuyUrl to buy it. Someone who is signed out signs in first, and the search runs once they are in.
Limits
Answers Modulify already holds cost nothing. Only lookups that have to ask Name.com count, toward 20 a minute from one network and 60 a minute shared by every caller. Past either, /availability answers 429 with a Retry-After header giving the seconds to wait, repeated in data.retryAfter. It answers the same way, with a wait of 60 seconds, while Name.com itself is too busy to answer. /prices never asks Name.com, so it has no limit.
Searches from the Domains page and from AI clients never use this allowance.
Errors
| Status | Cause | Message |
|---|---|---|
400 |
name is missing or is not a domain name |
"Pass a name like acme in name, with an extension like com in tld or on the name itself!" |
400 |
tld is not an extension |
"Pass an extension like com or co.uk in tld!" |
400 |
An extension in tld or tlds on /prices is not an extension |
"Pass extensions like com or co.uk in tld or tlds!" |
400 |
More than 100 extensions on /prices |
"Ask for up to 100 extensions at once!" |
404 |
The single extension asked for on /prices is not on sale |
Names it, for example ".local domains are not for sale!" |
503 |
/prices could not load the price list, for example before Modulify first read it from Name.com |
"Domain prices are not available right now. Please try again!" |
429 |
Your network used its lookups of the minute | "Too many domain lookups are coming from your network. Try again in 12 seconds!" |
429 |
Every caller together used the lookups of the minute | "Domain search is busy right now. Try again in 12 seconds!" |
429 |
Name.com is too busy to answer | "The registrar is busy right now. Try again in a moment!" |
502 |
Name.com could not be reached | "Domain search is not available right now. Please try again!" |
503 |
Modulify could not count the lookup | "Domain search is not available right now. Please try again!" |
503 |
Modulify is not selling domains right now | "Domain search is not available right now!" or "Domain prices are not available right now!" |
500 |
Something unexpected went wrong | "Something went wrong while searching for domains!" or "Something went wrong while listing domain prices!" |
429, 502 and 503 are worth retrying after a pause. Never retry in a tight loop.