Custom domains
- Written for
- + Written for
- Deprecated
- + Deprecated
- Applies to
- + Applies to
Custom domains
Serve your help center from your own hostname — with CNAME or TXT verification, Domain Connect one-click setup, and automatic TLS.
By default, your help center lives at a path under Chatly's help host — https://help.chatlychat.com/{workspaceId}. Most customers want their own hostname for trust and brand consistency: help.acme.com.
Warning — Custom domains cover the help center, and only the help center
There is one domain kind:
help_center. Chatly briefly offeredwidget,marketing, andmarketing.acme.comand find nothing there forever. They were removed in migration 0384. The widget loader and inbound email always run on Chatly's own hostnames.
This page walks through claiming a hostname, verifying it, and what happens after.
Claim a hostname
Dashboard
Workspace → Domains → Add domain.
Type the full hostname you want served —
help.acme.com, notacme.com. Chatly does not add a prefix for you.We return the CNAME target and a TXT challenge, plus a one-click button if your registrar speaks Domain Connect.
API
POST /v1/domains — Bearer token
POST /v1/domains
Authorization: Bearer …
Idempotency-Key: 3d90…
Content-Type: application/json
{ "hostname": "help.acme.com" }Response:
{
"id": "01920f3c-...",
"hostname": "help.acme.com",
"kind": "help_center",
"status": "pending",
"txtRecord": {
"host": "_chatly.help.acme.com",
"value": "chatly-domain-verify=abc123def456"
}
}Request
Name | Type | Description |
|---|---|---|
|
| 3–253 characters, letters/digits/dots/hyphens only, lowercased on write. The whole hostname to serve. |
Claiming a hostname that already exists re-issues its verification token and puts it back to pending. Hostnames are unique across the platform.
The records to add
GET /v1/domains — Bearer token
{
"cnameTarget": "connect.chatlychat.com",
"domains": [ { "id": "…", "hostname": "help.acme.com", "status": "pending", "…": "…" } ]
}cnameTarget is the value to publish. Read it from the API rather than guessing — it is deliberately not the help host, which sits behind a proxy, and a customer pointed at the wrong one lands on a CDN with a hostname that is not in our zone.
Records
Name | Type | Description |
|---|---|---|
|
| This is both the routing and the proof. A CNAME that resolves to |
|
| An apex cannot legally hold a CNAME. An |
|
| Proves control without routing traffic, for a hostname you cannot repoint yet. Accepted as verification — but a TXT alone never makes the domain live, because nothing is pointing at us to serve it. |
Verification
Verification is done by a background sweep, not by the request you make.
POST /v1/domains/{id}/verify — Bearer token
{ "queued": true }That is the honest answer this button can give: it moves the row to the front of the sweep's queue. It used to resolve DNS inline and report the result, which made a click feel authoritative when it could not be — DNS propagates somewhere between five seconds and an hour after a record is saved, so an immediate check almost always ran inside that window and told someone who had done everything right that they had failed.
The sweep re-checks on a backoff ladder — 30s, 60s, 2m, 5m, 10m, then every 30m — and once a domain is live it re-checks every 6 hours.
Verify by Domain Connect (one click)
If your DNS registrar implements Domain Connect, the dashboard shows a Set up at your registrar button instead of the copy-paste records:
GET /v1/domains/{id}/domain-connect — Bearer token
{ "supported": true, "applyUrl": "https://…", "providerName": "GoDaddy" }Click it → land on your registrar → see the exact records that will be applied → confirm → records appear in your zone. { "supported": false } is a normal answer; the page keeps showing the records to copy.
After verification
Once the sweep proves the hostname:
A Traefik router for that host is published — the certificate cannot be issued for a hostname the proxy has no router for, so this happens before the certificate is probed.
Traefik issues a Let's Encrypt certificate on demand, via the resolver named by
TRAEFIK_CERT_RESOLVER(defaultletsencrypt-http). Renewal is automatic.Requests for that host resolve to the workspace's help center. The renderer maps the
Hostheader back to the workspace, and to the non-default portal if the hostname is bound to one.
The first request after verification may take a few seconds while the certificate issues. After that it's instant.
Status and diagnosis
GET /v1/domains returns a status (pending / verified / revoked), a cert_status, a verification_method (cname / address / txt), and a diagnosis — which is the field worth reading, because "the record is missing", "the record points somewhere else", "a proxy is in the way", "your CAA record forbids our certificate authority", and "DNS is perfect, the certificate is still issuing" used to all be one word.
diagnosis
Name | Type | Description |
|---|---|---|
|
| Nothing published yet, or not propagated. The overwhelmingly common state for the first few minutes, and not an error. |
|
| The hostname resolves, but not to us. Check that the CNAME target matches |
|
| The zone is on a provider whose proxy mode hides the origin. Turn proxying off for this hostname (DNS-only) so validation can reach us. |
|
| A CAA record on the domain lists which authorities may issue, and ours is not among them. Add a CAA record permitting |
|
| DNS is correct and the certificate is being issued. Nothing for you to do. |
|
| DNS is correct but issuance did not complete — usually CAA, or a proxy intercepting the validation request. We keep retrying. |
|
| Serving. Re-checked every 6 hours. |
TLS certificates
Certificates are issued and renewed by Traefik against Let's Encrypt. There is no endpoint for uploading your own certificate or key — a wildcard cert you already hold cannot be attached to a Chatly custom domain.
Removing a domain
DELETE /v1/domains/{id} — Bearer token
Deletes the row. The Traefik router for that host is dropped on the next sweep, and the certificate simply expires. Re-adding the same hostname later starts the flow over with a fresh verification token.
Warning — Make sure no traffic still depends on it
Links you have published to
help.acme.comstop resolving to your help center. Point people at the defaulthelp.chatlychat.com/{workspaceId}URL before deleting the hostname, not after.
Troubleshooting
Warning — I added the records but the status is still pending
Verification is a background sweep, not the button. Give it a cycle — the first few retries are 30s, 60s, 2m apart. If it stays
awaiting_dns, rundig CNAME help.acme.com +shortfrom your own machine; an empty answer means the record is not authoritative yet. Some registrars take ~30 minutes despite the TTL.
Info — Diagnosis says points_elsewhere
Compare your CNAME's value against
cnameTargetfromGET /v1/domains. The two most common mistakes are pointing at the dashboard's hostname and pointing at the help host — neither serves a custom domain.
Info — Cert issuance stuck on 'issuing certificate'
Check for a CAA record first (
dig CAA acme.com +short) — the sweep reportscaa_blockedwhen it can see one, but a CAA at a parent zone can still bite. Otherwise the Traefik log (docker logs traefik | grep acmeon self-host) shows the exact ACME error.