Skip to main content

Custom domains

Published pages normally serve from Erdo’s pages host. A custom domain puts them on a hostname you own instead — pages.acme.com rather than pages.erdo.ai — via a single CNAME record. The domain belongs to your organization, not to one page: once active, every public page the org publishes is reachable on it, and share links are built on it automatically.

How a domain goes live

  1. Register the domain. Use a direct subdomain of a domain you control (e.g. pages.acme.com — a root domain can’t carry the CNAME). Registration returns the DNS records to create.
  2. Create the DNS records. A routing CNAME pointing at Erdo’s pages host, plus a one-time _acme-challenge delegation CNAME so certificates can issue and renew without you ever touching DNS again.
  3. Wait for validation. Erdo re-checks the domain continuously: ownership is verified from the routing CNAME, then a certificate is issued, then the domain starts serving.
The domain’s status tells you exactly where it is in that walk: Status is read from the same record the page-serving path uses — never a cached copy that can drift — and last_checked_at says when it was last reconciled, so a domain that has sat in pending_cert for a month is visible for exactly what it is.

Pick a name that doesn’t receive email

The routing CNAME forbids every other DNS record on the same name, so a name that receives email — one with MX records, whether at your mailbox provider or a domain registered with Erdo to receive replies — can never carry it: publishing the CNAME would take that mailbox down, and most DNS providers refuse to create it at all. Erdo checks at registration and refuses such a name, rather than register a domain that can never activate. Serve pages and receive email on sibling names instead — pages on go.acme.com, email on acme.com or mail.acme.com. A domain that only sends through Erdo is not affected: sending’s records all sit on names beneath it, which coexist with the CNAME fine.

API

All endpoints act on the caller’s organization and require an org admin. Domains are addressed by the domain name itself — a name registered to another organization answers 404, with no hint that it exists. List the org’s domains with live status:
Register a domain (the response carries dns_records — the records to create):
Remove a registration (the hostname stops serving pages):
On the CLI: erdo pages domains list | add <domain> | remove <domain> | transfer <domain> <org> | manager-default <domain> [--unset]. The MCP tool erdo_list_custom_domains gives agents the same read; mutations are deliberately REST/CLI-only.

Moving a domain between organizations

When a customer’s pages are rebuilt in a new organization — a tenant migration, a portal cutover — the branded hostname has to start serving the new org’s pages. Deleting and re-registering it would tear down its CDN hostname and force certificate re-issuance: a visible outage on a live domain. Transfer avoids that entirely:
The domain keeps its CDN hostname and certificate; only its owning organization changes, so serving flips to the target org atomically with the move — zero downtime, nothing to re-validate, no DNS changes for the customer. Transfer is two-sided by construction: you must be an org admin of the organization that owns the domain and of the target organization. A manager account satisfies both when steering a domain between its own managed orgs — which is exactly the cutover case — and nobody who administers only one side can move a domain in or out. Transfers are idempotent: re-running one that already happened succeeds without changing anything.

Manager default domains

An agency that runs an organization per client meets the same wall on every new one: the client’s pages are built and published, everything works, and their URLs say pages.erdo.ai. Registering a hostname per client does fix it, but one client at a time — a DNS record to create and a certificate to wait for on each — which is a lot of setup to repeat for what is really one branded name. A manager default is that name registered once. A manager account registers an ordinary custom domain on its own organization and marks it the default for the organizations it manages; from then on every client it manages publishes on that hostname, including clients adopted or provisioned later, with nothing to set up per client.

Which hostname a page’s URL carries

A published page’s URL resolves in three steps:
  1. The organization’s own active custom domain, if it has one.
  2. Otherwise, its manager’s default domain, once that domain is active.
  3. Otherwise, Erdo’s pages host.
Step 1 comes before step 2 deliberately: a client that registered its own hostname chose it, so a manager default fills in where a client has none and never overrides one it has. A client that registers its own domain later moves onto it automatically, and nothing about the manager default has to be undone.

The manager’s hostname serves those pages too

A custom domain only serves pages it is entitled to, and the manager default widens that entitlement to match the URLs it mints: it serves its own organization’s pages plus the pages of every organization that manager actively manages. Anything else answers 404, exactly as a request for another organization’s page on an ordinary custom domain does. So a page whose URL carries the manager’s hostname is always a page that hostname will serve — the two halves cannot disagree about which pages belong there. Both halves are read from the live management relationship, so ending management ends both at once: the client’s pages go back to minting URLs on Erdo’s pages host, and the manager’s hostname stops serving them. There is nothing to unwind by hand, and no cutover to schedule.

Setting it

The flag changes nothing about how the domain itself works. It is an ordinary registration — the same CNAME, the same certificate, the same statuses in the table above — and only an active domain brands anything, since a default still waiting on DNS would mint URLs to a hostname that does not resolve. So the usual order is to register the hostname, let it reach active, and promote it afterwards:
Send {"manager_default": false} to the same endpoint to clear it. A domain can also be registered and marked in one call, when you already know that is what it is for:
On the CLI:
GET /v1/custom-domains carries manager_default on every domain, and the read-only MCP tool erdo_list_custom_domains reports it too, so an agent can tell an agency’s shared hostname from an ordinary one without being able to change it. Setting it takes an org admin of an organization that actually manages at least one other. An organization that manages nobody is refused with that as the reason rather than a permissions error, because there is nothing for it to be the default of yet — provision or adopt a client organization first. Clearing the flag is always allowed, so an organization that has since stopped managing anyone can still turn it off. A public page renders inside an iframe, so the browser-tab favicon and the share-card image (the og:image/twitter:image a chat app or search engine shows when the link is pasted) come from the outer shell, not the page’s own HTML — and that’s true whatever host the page serves from, custom domain or not. They resolve from a meta_icon_asset_id / meta_image_asset_id pair on the page: the org’s Brand Style record’s apple-icon-180x180 / favicon-32x32 attachment for the tab icon, and its og-image (or, absent that, the first hero photo) for the share card. Pages the builder agent creates get these filled in automatically from the org’s Brand Style record, and existing published pages are backfilled from whichever Brand Style record their logo already comes from. You can also set or clear either one per page — the page tools’ meta_icon_asset_id / meta_image_asset_id fields, or --meta-icon-asset / --meta-image-asset on the CLI. Leave both unset and the page falls back to Erdo’s own favicon and share card.

Scope and limits

  • Domains must be direct subdomains (pages.acme.com, not acme.com or pages.team.acme.com).
  • A domain can be registered to one organization at a time, platform-wide. A manager default is no exception: it stays registered to the manager’s organization and serves its managed organizations’ pages, rather than belonging to them.
  • Each organization can hold up to 25 custom domains, and at most one of them can be the manager default. Marking a second one moves the default, and the managed organizations follow it.
  • Registration, validation, and certificate mechanics are platform-owned — you only ever create the DNS records the API hands you.