Docs
Docs
Troubleshooting

Why isn't it live?

One call runs every check that decides whether a domain serves, and names the one thing to change.

GET /v1/domains/{id}/diagnose (or Diagnose on the domain in the dashboard) runs every check live and returns each one as pass, fail, warn or skip, with what we saw (detail) and what to change (fix). blocking_check_id is the failing check to fix first: a root cause such as the Cloudflare proxy comes before the DNS checks it breaks. live is true when the domain is active and nothing fails.

curl https://api.apexly.dev/v1/domains/dom_01J9X8T4Q5M6N7P8R9S0V1W2X3/diagnose \
  -H "Authorization: Bearer $APEXLY_API_KEY"
{
  "domain_id": "dom_01J9X8T4Q5M6N7P8R9S0V1W2X3",
  "hostname": "careers.acme.com",
  "status": "pending_dns",
  "live": false,
  "blocking_check_id": "cloudflare_proxy",
  "checked_at": "2026-10-24T09:12:03.120Z",
  "checks": [
    {
      "id": "cloudflare_proxy",
      "status": "fail",
      "title": "Cloudflare proxy",
      "detail": "careers.acme.com answers with Cloudflare addresses (104.21.3.4), so the record is proxied (orange cloud). Cloudflare hides the record from our checks and the certificate authority.",
      "fix": "Ask Acme to open Cloudflare → DNS → Records for acme.com, edit the CNAME record careers and set Proxy status to DNS only (grey cloud).",
      "docs": "https://docs.apexly.dev/troubleshooting/domain-doctor#cloudflare_proxy"
    }
  ]
}

The diagnosis is read-only: it never changes the domain or its schedule. Results are reused for 20 seconds per domain, and each app can run 30 a minute. The Node SDK has apexly.domains.diagnose(id).

The connect page uses the same verdict: when the blocking check is one the customer fixes on a record (the Cloudflare proxy, other A records, stale AAAA records), it shows that as the one thing to change.

Warnings when you add a domain

POST /v1/domains runs a quick preflight on a new live domain (at most 2 seconds; a lookup that takes longer is skipped and never fails the request). Anything that will stop the domain going live comes back in warnings[]; the domain is created either way.

codeMeaning
cloudflare_proxyThe name is proxied by Cloudflare. The record must be DNS only (grey cloud).
apex_records_elsewhereThe apex already has A or AAAA records pointing somewhere else. They must be replaced by ours.
caa_blocks_issuanceCAA records do not allow Let's Encrypt. See caa_blocks_issuance.
origin_unreachableYour app's origin failed its last probes (or resolves to a private address).

An origin override that resolves to a private address is still refused with 422 origin_not_allowed.

The checks

dns_authoritative

The record at the domain's own nameservers, judged exactly as verification judges it: one CNAME for a subdomain; for an apex, the A records plus the _apexly TXT record (the TXT is no longer needed once verified). The fix names the exact record. Reason pages: dns_record_missing, dns_record_mismatch, apex_a_mismatch, apex_txt_missing.

dns_1.1.1.1

The same record at Cloudflare DNS. When the nameservers already have it and 1.1.1.1 doesn't yet, this is a warning: the change is still spreading (dns_resolvers_disagree).

dns_8.8.8.8

The same at Google DNS.

apex_extra_a

Apex only. A records at @ that are not ours. Visitors and the certificate authority are sent to one of them at random, so the domain flaps. Delete them and keep only the addresses in the domain's dns.apex.a.

stale_aaaa

AAAA (IPv6) records pointing somewhere else, often left from the old host. IPv6 visitors, and the certificate authority, which prefers IPv6, reach the old server. Delete them (or replace them with the domain's dns.apex.aaaa). A subdomain with a CNAME cannot have its own AAAA records, so this passes.

cloudflare_proxy

The record is proxied (orange cloud): Cloudflare answers with its own addresses and terminates TLS itself, so we never see the record and the certificate authority cannot validate it. In Cloudflare → DNS → Records, set the record's Proxy status to DNS only (grey cloud). While the proxy is on, the DNS checks are warnings that say the record is hidden: it may well be right, so they don't ask for a different value.

caa

CAA records must allow letsencrypt.org (or sectigo.com, which we use through ZeroSSL as a fallback; that is a warning). See caa_blocks_issuance.

certificate

The serving certificate and its expiry (a warning inside 15 days), or where issuance stands: being issued, or failed with the reason and its page (ca_rate_limited, ca_unreachable). Skipped until DNS is verified.

origin

Where the edge forwards visitors. Your app's origin uses its scheduled probe (every 15 minutes; unreachable after three failures in a row). A per-domain origin override is probed live.

www_pair

Only with apex_redirect: "www". The apex redirects to www.<apex>, which has to be a domain of your app too and active; otherwise visitors land on "not connected".

Was this helpful?