Skip to main content

Domains

Add domains you or your customers own, connect them to a published project, and read their DNS, HTTPS certificate and reachability status. One project can serve any number of domains at the same time. The app sees which one a visitor used in window.location.hostname, so each domain can show a different tenant.

All calls need the API key described in Authentication.

Typical flow​

  1. Add and connect the domain with Domain/Create, passing your ProjectID. Save the returned ID.
  2. Show the DNS record to the domain owner. Domain/Get returns it (DnsRecordType, DnsRecordName, DnsRecordValue).
  3. Poll Domain/Get (or Domain/Page for many) every few minutes until Status is SUCCESS and CertificateStatus is Valid. Most domains are live within a few minutes of the DNS record resolving.
  4. Remove it with Domain/Delete when the tenant leaves.

DNS records​

DomainRecordValue
Subdomain, e.g. portal.example.comCNAMEclient.easysite.ai
Root domain, e.g. example.com or example.co.zaA40.112.140.56
  • Cloudflare: set the record to DNS only (grey cloud). With the proxy on (orange cloud) EZsite can't verify the domain or issue its certificate.
  • Wildcards such as *.example.com are not supported for DNS hosted elsewhere. Add each subdomain on its own.
  • Certificates are issued and renewed automatically as long as the record keeps pointing to EZsite.

Add a domain: POST /Domain/Create​

{ "Name": "portal.clienta.co.za", "Type": 1, "ProjectID": 12345 }
FieldRequiredDescription
NameyesThe domain, lowercase, no https://
Typeyes1 = a domain you own. (0 creates an EZsite subdomain instead.)
ProjectIDnoConnect the domain to this project in the same call. The project must already be published.

Returns the new domain (same shape as one Domain/Page item):

{
"Success": true,
"Data": {
"ID": 9876,
"Domain": "portal.clienta.co.za",
"Url": "https://portal.clienta.co.za",
"ProjectId": 12345,
"Type": "CustomDomain",
"Status": "Pending",
"RawStatus": "Pending",
"Role": "inactive",
"Health": "Unknown"
}
}

Errors (Success: false, see Message): the domain is already live on another EZsite account or project; the project is not published yet; your plan does not include custom domains. A failed call creates nothing.

Get one domain: GET /Domain/Get?id={id}​

Everything about one domain, including what Domain/Page does not return:

{
"ID": 9876,
"Domain": "portal.clienta.co.za",
"ProjectId": 12345,
"Status": "SUCCESS",
"RawStatus": "SUCCESS",
"Discription": "",
"Role": "independent",
"Health": "Ok",
"HealthDetail": "",
"HealthCheckTime": "2026-11-10T09:12:00",
"ExpireTime": "2027-03-01T00:00:00Z",
"CertificateStatus": "Valid",
"CertificateExpiresAt": "2027-02-08T10:41:22Z",
"CertificateRenewsAt": "2027-01-09T10:41:22Z",
"DnsPointsToEZsite": true,
"DnsMessage": "",
"DnsRecordType": "CNAME",
"DnsRecordName": "portal.clienta.co.za",
"DnsRecordValue": "client.easysite.ai"
}
FieldMeaning
StatusPending (just added) · Processing (verifying DNS / issuing the certificate) · SUCCESS (live) · PermissionExpired (your plan no longer includes custom domains)
RawStatusSame, but reports CNameError separately: DNS does not point to EZsite yet, so the owner has to fix the record
DiscriptionWhat to do next when the domain is not live
DnsPointsToEZsite / DnsMessageResult of the last DNS check, and the reason when it failed
CertificateStatusValid · Pending (not issued yet) · NotNeeded (EZsite subdomains)
CertificateExpiresAtExpiry of the certificate the domain serves right now (UTC), read live when you call Domain/Get. null while DNS doesn't point to EZsite
CertificateRenewsAtWhen the automatic renewal is scheduled, about 30 days before expiry. A renewal that fails is retried, and Health turns TlsError if the certificate actually lapses
HealthLast reachability check: Ok, RedirectToPrimary, RedirectElsewhere, NotServedByUs, DnsFailed, Unreachable, TlsError, HttpError, Expired or Unknown (not checked yet). HealthDetail explains any problem.
ExpireTimeWhen the domain registration expires, if the registry publishes it
Roleunbound (not connected) · inactive (connected, not live yet) · independent (serves the app on its own) · primary / redirect (only if you set a primary domain)

Pending domains are re-checked automatically every 2 minutes and live ones every 10 minutes.

List domains: POST /Domain/Page​

{ "PageNo": 1, "PageSize": 50, "ProjectID": 12345 }

ProjectID is optional and limits the list to one project's domains. Returns { "List": [...], "VirtualCount": 120 }. Each item has the fields shown for Domain/Create, plus the health and role fields. Use Domain/Get for certificate and DNS details.

Check reachability now: GET /Domain/CheckHealth?id={id}​

Re-tests the domain immediately instead of waiting for the next automatic check. Returns Health, HealthDetail, HealthCheckTime and ExpireTime. Limited to once a minute per domain.

Connect an existing domain: GET /Domain/BindProject?id={id}&deployId={deployId}​

Connects a domain you added earlier without ProjectID. deployId is the project's current deployment, the DeployId shown on another domain of the same project. For new domains, pass ProjectID to Domain/Create instead.

Disconnect: GET /Domain/RemoveBind?id={id}​

The domain stops serving the project but stays in your account.

Remove: GET /Domain/Delete?id={id}​

Disconnects the domain and deletes it from your account.

Notifications​

There are no webhooks for domain events yet. Poll Domain/Page (all domains in one call) every 5–10 minutes, or Domain/Get for one domain while it is being set up.

Limits​

  • No limit on the number of custom domains on Tier 3 and above.
  • Certificates come from Let's Encrypt, which allows about 50 new certificates per week per registered domain. All subdomains of example.com share that allowance, so spread very large batches over several days.
  • CheckHealth: once a minute per domain.

MCP tools​

The same operations are available to AI agents through the EZsite MCP server: ezsite_domain_add (with projectID), ezsite_domain_get, ezsite_domain_list, ezsite_domain_bind, ezsite_domain_unbind and ezsite_domain_remove.