Domains API
Add your own domain to a project, get the DNS records to publish, verify ownership, and check where it points and whether HTTPS is working.
A custom domain takes two DNS records. A TXT record proves the domain is yours; a CNAME sends its traffic to the project. A domain is stored unverified and serves nothing until the TXT record is found, so nobody can claim a domain they do not control. For the walkthrough, see Custom domains.
/ projects/ {name}/ domainsA project's domains, with the records to publish/ projects/ {name}/ domainsAdd a domain/ projects/ {name}/ domains/ {host}/ verifyCheck the TXT record and start serving/ projects/ {name}/ domains/ {host}Remove a domain/ domainsEvery domain across your projectsThe records, for shop.example.com on the project my-app-ada:
TXT _fortly.shop.example.com fortly-verify=4c1d… # proves it is yours
CNAME shop.example.com my-app-ada.fortly.com # sends traffic hereAt the apex of a domain (example.com itself) a CNAME is not allowed; use your DNS provider's ALIAS or ANAME record if it has one.
List a project's domains
/ projects/ {name}/ domainsA project's domains, with the records to publishEach domain, whether it is verified, where its DNS points and the state of its certificate. This route looks up DNS for each domain, so it is slower than most.
namestringRequiredname.curl https://api.fortly.com/projects/my-app-ada/domains \
-H "Authorization: Bearer $FORTLY_TOKEN"const res = await fetch("https://api.fortly.com/projects/my-app-ada/domains", {
headers: { Authorization: `Bearer ${process.env.FORTLY_TOKEN}` },
});
const { domains } = await res.json();{
"domains": [
{
"url": "https://shop.example.com",
"host": "shop.example.com",
"verified": true,
"created_at": 1791820800,
"record_name": "_fortly.shop.example.com",
"record_short": "_fortly.shop",
"record_value": "fortly-verify=4c1d9e2a7b3f4c8d9e0a1b2c3d4e5f6a",
"points_to": "my-app-ada.fortly.com",
"pointing": "here",
"nameservers": [],
"certificate": "active"
}
],
"custom_domains_ready": true
}record_namestringrecord_shortstring | nullnull when there is no shorter form.record_valuestringpoints_tostringpointingstringunchecked until the domain is verified; then here (the CNAME points at this project), elsewhere, proxied (served through your own Cloudflare zone), or unknown (no CNAME visible, as with a flattened apex record).nameserversstring[]certificatestringnone, pending, active, failed, or external when your own Cloudflare zone terminates TLS.custom_domains_readybooleanfalse when the platform cannot issue certificates for custom domains right now, so a domain added here would fail HTTPS.Add a domain
/ projects/ {name}/ domainsAdd a domainAdds a domain, unverified, and returns the TXT record to publish.
namestringRequiredname.hoststringRequiredshop.example.com. Lower-cased; a trailing dot is dropped. Needs at least one dot; letters, digits and hyphens only; no wildcards.curl -X POST https://api.fortly.com/projects/my-app-ada/domains \
-H "Authorization: Bearer $FORTLY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"host":"shop.example.com"}'const res = await fetch("https://api.fortly.com/projects/my-app-ada/domains", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.FORTLY_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ host: "shop.example.com" }),
});
const { record_name, record_value } = await res.json();Answers 201:
{
"host": "shop.example.com",
"verified": false,
"record_name": "_fortly.shop.example.com",
"record_value": "fortly-verify=4c1d9e2a7b3f4c8d9e0a1b2c3d4e5f6a"
}| Status | When |
|---|---|
400 | Not a valid hostname, or a name under fortly.com, which Fortly gives out itself. |
403 | Your account has as many custom domains as its plan allows. The count is across all your projects, verified or not. |
409 | The domain is already on a project. |
Verify a domain
/ projects/ {name}/ domains/ {host}/ verifyCheck the TXT record and start servingLooks up the TXT record now. When it is found the domain is marked verified, starts serving at once, and a certificate is requested for it.
namestringRequiredname.hoststringRequiredcurl -X POST https://api.fortly.com/projects/my-app-ada/domains/shop.example.com/verify \
-H "Authorization: Bearer $FORTLY_TOKEN"const res = await fetch(
"https://api.fortly.com/projects/my-app-ada/domains/shop.example.com/verify",
{ method: "POST", headers: { Authorization: `Bearer ${process.env.FORTLY_TOKEN}` } },
);
const { verified, certificate, why } = await res.json();When the record is found:
{ "host": "shop.example.com", "verified": true, "certificate": "pending" }When it is not found yet, the answer is still 200, with the reason and the record again:
{
"host": "shop.example.com",
"verified": false,
"why": "That record is not visible yet. DNS changes can take a few minutes.",
"record_name": "_fortly.shop.example.com",
"record_short": "_fortly.shop",
"record_value": "fortly-verify=4c1d9e2a7b3f4c8d9e0a1b2c3d4e5f6a"
}| Status | When |
|---|---|
404 | The domain is not on this project. |
502 | DNS could not be asked. This is not the same as the record being missing; try again. |
Verifying proves ownership; it does not send traffic. Publish the CNAME as well, then check pointing on List a project's domains.
Remove a domain
/ projects/ {name}/ domains/ {host}Remove a domainStops serving the domain and releases its certificate.
namestringRequiredname.hoststringRequiredcurl -X DELETE https://api.fortly.com/projects/my-app-ada/domains/shop.example.com \
-H "Authorization: Bearer $FORTLY_TOKEN"await fetch("https://api.fortly.com/projects/my-app-ada/domains/shop.example.com", {
method: "DELETE",
headers: { Authorization: `Bearer ${process.env.FORTLY_TOKEN}` },
});Answers 204 No Content. A domain can be removed only by the account that added it; for anyone else, and for a domain that is not on the project, the answer is 404 with that domain is not on this project.
List all domains
/ domainsEvery domain across your projectsEvery custom domain on every project you can access.
curl https://api.fortly.com/domains \
-H "Authorization: Bearer $FORTLY_TOKEN"const res = await fetch("https://api.fortly.com/domains", {
headers: { Authorization: `Bearer ${process.env.FORTLY_TOKEN}` },
});
const { domains } = await res.json();{
"domains": [
{
"project": "my-app-ada",
"url": "https://shop.example.com",
"host": "shop.example.com",
"verified": true,
"created_at": 1791820800,
"points_to": "my-app-ada.fortly.com",
"certificate": "active"
}
]
}